pdoc3 / pdoc

:snake: :arrow_right: :scroll: Auto-generate API documentation for Python projects
https://pdoc3.github.io/pdoc/
GNU Affero General Public License v3.0
1.12k stars 145 forks source link

Document an object in a place other than where it was defined #259

Closed jwcarr closed 4 years ago

jwcarr commented 4 years ago

I'm just getting to grips with pdoc and so far I'm super impressed – such a fantastic project!

I have a question that I can't seem to find a clear answer to. I have a project structure like this:

project
->  __init__.py
->  _important.py

I have a class which should be available at the top level of the package (i.e., project.ImportantClass). But to keep my code tidy, I want to define ImportantClass in _important.py and then import it in the __init__.py like this

from ._important import ImportantClass

However, it seems that pdoc will only document objects in the place where they are defined. This means I have three options:

  1. I define ImportantClass in __init__.py, but this is not great, because I have several large classes across several private modules, so it's quite messy to have everything defined in __init__.py.
  2. I allow pdoc to see the _important module by setting __pdoc__ = {'_important':True}, but this is not great because ImportantClass gets documented under the _important submodule and not at the top-level, which is the intended usage pattern.
  3. I make the important module public and change the usage pattern so that user has to do project.important.ImportantClass, but this is a bit annoying from a usability perspective.

Have I understood this correctly, and is there some way around this?

kernc commented 4 years ago

I think the following two additional methods might work:

  1. Define a __pdoc__ exception for ImportantClass. I guess you certainly tried that, and it didn't work?
    
    from ._important import ImportantClass

pdoc = { 'ImportantClass': True, ... }


5. Export `ImportantClass` in [`__all__`](https://docs.python.org/3/tutorial/modules.html#importing-from-a-package):
```py
__all__ = ['ImportantClass', ...]
kernc commented 4 years ago

Similar issues: https://github.com/pdoc3/pdoc/issues/228, https://github.com/pdoc3/pdoc/issues/231.

jwcarr commented 4 years ago

Ah, thank you! Yes, this is exactly what I was looking for. In case it's any help, the thing that threw me off was this line in the docs:

If a module defines __all__, then only the identifiers contained in this list are considered public. More generally, objects (modules, variables, functions, classes, methods) are only considered public in the module where they are defined (vs. imported from somewhere else) and only if their identifiers don't begin with an underscore ( _ ).

I interpreted the second sentence ("only considered public in the module where they are defined") as overriding the first, and so I didn't try setting __all__. Maybe you could rephrase to something along these lines:

Objects (modules, variables, functions, classes, methods) are considered public in the module where they are defined (vs. imported from somewhere else) as long as their identifiers don't begin with an underscore ( _ ). If a module defines __all__, then only the identifiers contained in this list (regardless of where they were defined) are considered public.

Thanks again!