Skip to content

Treat __init__ differently than other methods #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
aomader opened this issue Feb 6, 2019 · 13 comments
Closed

Treat __init__ differently than other methods #24

aomader opened this issue Feb 6, 2019 · 13 comments
Labels
enhancement New feature or request

Comments

@aomader
Copy link
Contributor

aomader commented Feb 6, 2019

I use Google's docstring style by documenting Class.__init__(self) methods in the Class docstring. Which means, I always have an __init__ method rendered without any documentation but the parameters and the default values. On the flip side, I have a large Class docstring rendered which contains explanations for all these parameters. Basically, everything is split up.

What about an option to tackle this case including proper output?

For example, the one from sklearn where the __init__ signature is included in the Class:
image

@kernc
Copy link
Member

kernc commented Feb 6, 2019

So pdoc currently shows HuberRegressor as:
screenshot_2019-02-06_23-20-32

How exactly would you prefer it?

@aomader
Copy link
Contributor Author

aomader commented Feb 6, 2019

I, personally, prefer to illustrate how you call the class, i.e., join the __init__ documentation and the Class documentation, given a lower importance to the inheritance.

Trying to sketch it, I would make it look like this:

class MyAwesomeClass(param_a, param_b=3):
    inherits: Mixin1, Mixin2 (I would visually reduce the importance of this line)
  
  My class is the freakin' BEST!

  Parameters:
    param_a : Just a param
    param_b : Another one pew pew

  Attributes:
    ...

Additionally, I think the attributes documentation section should be placed in Instance variables if I'm not mistaken.

It would also make sense to include the inherited methods in maybe a collapsible section, something like 'Methods inherited from ClassFoo'. Similar to the way rustdoc illustrates which trait methods were implemented. I personally find this very useful.

@kernc
Copy link
Member

kernc commented Feb 7, 2019

This looks particular and specific. 😬 Classes shown as callable in stead of their __inits__ can be easily achieved by overriding html.mako with a custom template. The API is pretty stable at this point. I'm certainly 👎 a command-line switch. Perhaps a config.mako tunable? Alternatively, we could go with a more fine-grained template for easier overriding part-wise.

Listing Attributes as Instance variables would be trickier and would require manipulating the docstring and the Class object sooner in the pipeline. Numpydoc defines Attributes too, so I guess Attributes should always be listed as instance variables? But if one is documenting attributes in this way and not, say, pdoc-supported PEP-224 way, then they won't even have an Instance variables section (they'll just have their Attributes section)?

Pdoc already lists inherited identifiers from ancestor Class objects it knows about (i.e. those that are defined within Modules that are being documented).
screenshot_2019-02-07_00-57-05
It doesn't list identifiers from other projects or builtins. Doing so might require substantial refactoring. The rust traits link points to rust stdlib documentation. Run pdoc on CPython/Lib and you will get the same full inherited lists (in theory).

@aomader
Copy link
Contributor Author

aomader commented Feb 7, 2019

Concerning the first point. What about changing the default template? Obviously this is a very subjective thing, but I personally think showing classes as callable makes sense, since this is the way you would write out the code when using this class. Thus I think it would make sense to adapt the default style into this direction. What is your opinion on this?
(I was thinking that pdoc3 might become something like PEP8 for style, in the sense that you do not have to fiddle with the details to much but get a consistent and uniform output, i.e., not a Sphinx where I have to tweak every little but, more like rustdoc for Python)

Concerning the second paragraph. Just for clarification, I assume that attributes is a synonym for instance variable. Thus I think these two things should be placed in the same doc output, whether I like to place docstring next to the variables or in the class documentation in an 'Attributes' section.

For the last part, I did not know that. What about making a bit more direct by including a way to see the actual documentation right in that very place, maybe initially hidden by a collapsible element?

@kernc
Copy link
Member

kernc commented Feb 8, 2019

What about changing the default template?

And Sphinx also does it this way. Good, I agree. This way, we can rid us of __init__ as the only method prefixed with an underscore. PR welcome.

Don't know about something like PEP8 for style (:sweat_smile:), but following the conventions and serving the 95% use case certainly is the idea.

@kernc
Copy link
Member

kernc commented Feb 8, 2019

Re Attributes listed as Instance variables, it is the same. But no one in their right mind uses both ways (intermixed) to document their class' members, so they will only ever end up with one of the two subsections. Attributes are technically Instance variables and we could parse them out and then attach them as pdoc.Variable objects as is done currently ..., but we are not a type checker to be forcing that assertion, and it seems a lot of work. If you find you can solve it in an elegant manner, certainly welcome.

@kernc
Copy link
Member

kernc commented Feb 8, 2019

What about making a bit more direct by including a way to see the actual documentation right in that very place

Currently, there is a config.mako flag which you can tune:

show_inherited_members = False

and which is then passed to pdoc.Class methods:
class_vars = c.class_variables(show_inherited_members)
smethods = c.functions(show_inherited_members)
inst_vars = c.instance_variables(show_inherited_members)
methods = c.methods(show_inherited_members)

This also lists inherited members, but they are dimmed (greyed out).
Improvements welcome. 👍

@kernc kernc added the enhancement New feature or request label Feb 9, 2019
@kernc
Copy link
Member

kernc commented Feb 25, 2019

@b52 Are you still interested in this (callable class instead of separate __init__) and enough to give it a shot? It'd be a good thing to have in the next release. 😁

@aomader
Copy link
Contributor Author

aomader commented Feb 25, 2019

@kernc Definitely, I was just occupied with finalizing a paper, but I might have a few hours this week, at latest the upcoming weekend.

@aomader
Copy link
Contributor Author

aomader commented Mar 16, 2019

@kernc Got some pointers where to start for doing the __init__ thing?

@kernc
Copy link
Member

kernc commented Mar 17, 2019

I think maybe with a test containing a class with the two docstrings, expecting them concatenated. I guess most changes, shouldn't be a lot, really, would be in pdoc.Class.

@kernc kernc closed this as completed in 9ea83fd Apr 21, 2019
@kernc
Copy link
Member

kernc commented Apr 21, 2019

A little bit ad-hoc but seems to work. @b52, welcome to test current master on your project.

@aomader
Copy link
Contributor Author

aomader commented Apr 22, 2019

@kernc Looks very good! I think it solves the problem nicely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

2 participants