Major Eccles
Major Eccles

Reputation: 491

How do I document classes imported from other modules - hence without the declaration module's name?

The package I am documenting consists of a set of *.py files, most containing one class with a couple of files being genuine modules with functions defined. I do not need to expose the fact that each class is in a module so I have added suitable from statements in the __init__.py file e.g.

from base import Base

so that the user can use the import pkg command and does not then have to specify the module that contains the class:

import pkg

class MyBase(pkg.Base):  # instead of pkg.base.Base ...
...

The problem is that Sphinx insists on documenting the class as pkg.base.Base. I have tried to set the add_module_names = False in conf.py. However this results in Sphinx showing the class as simply Base instead of pkg.Base. Additionally this also ruins the documentation of the couple of *.py files that are modules.

How do I make Sphinx show a class as pkg.Base? And how do I set the add_module_names directive selectively for each *.py file?

Upvotes: 20

Views: 5577

Answers (4)

buhtz
buhtz

Reputation: 12200

I would like to provide a more generalized approach.

The variable __all__ is filled up based on dir(). But the sub-packages name (here mypackage) and all in-build attributes (starting with __) are ignored.

from .mypackage import *

__all__ = []
for v in dir():
    if not v.startswith('__') and v != 'mypackage':
        __all__.append(v)

Upvotes: 1

Micael Jarniac
Micael Jarniac

Reputation: 441

I've incorporated the answers I found in a scalable-ish form factor:

my_project/
    __init__.py
    mess.py
  • mess.py:
class MyClass:
    pass

class MyOtherClass(MyClass):
    pass
  • __init__.py:
from .mess import MyClass, MyOtherClass

__all_exports = [MyClass, MyOtherClass]

for e in __all_exports:
    e.__module__ = __name__

__all__ = [e.__name__ for e in __all_exports]

This seems to have worked pretty well for me.

Upvotes: 1

mzjn
mzjn

Reputation: 51062

Here is a way to accomplish what the OP asks for:

  1. Add an __all__ list in pkg/__init__.py:

    from base import Base    # Or use 'from base import *'
    
    __all__ = ["Base"]
    
  2. Use .. automodule:: pkg in the .rst file.

Sphinx will now output documentation where the class name is shown as pkg.Base instead of pkg.base.Base.

Upvotes: 15

mstuebner
mstuebner

Reputation: 434

Short answer: You shouldn't. Just point the sphinx to the directory of your code. Sphinx documents the code and shows the module hirarchy. How the module finally will be imported is purely in the hand of the developer, but not a responsibility of the documentation tool.

Upvotes: -4

Related Questions