14

I have a package:

  • foo
    • foo.py
    • bar.py
    • __init__.py

foo.py has a class Foo. In __init__.py I import class Foo so users can do:

from foo import Foo

Sphinx rightly documents Foo as foo.foo.Foo, which is right but confusing to users. How do I get Sphinx to document it as foo.Foo?

It's also important to get the overall module documentation associated with the right module.

Sphinx documents something called:

..module:: module.name

but when I use it in the first comment in a foo.py file, the doc is still attributed to foo.foo.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
Aaron
  • 3,249
  • 4
  • 35
  • 51

2 Answers2

4

The value of the __module__ attribute is the name of the module in which a class/function/method was defined (see https://docs.python.org/2.7/reference/datamodel.html). The attribute is writable so it can be redefined in __init__.py:

Foo.__module__ = "foo"

Now if you use .. automodule:: foo, the qualified name of the Foo class will be shown as foo.Foo in the generated module documentation.


As an alternative to __module__-fiddling, you can use autoclass instead of automodule.

.. autoclass:: foo.Foo will produce the wanted output.

mzjn
  • 48,958
  • 13
  • 128
  • 248
  • Does it have to be \__init__.py? I tried to do it at the point of the definition itself, and it didn't seem to have any effect. – bmargulies Jul 31 '14 at 13:13
  • @bmargulies: In the little "Foo" example that I created based on the file structure in the original question, it works as described. And the `Foo.__module__ = "foo"` line can be put in either \__init__.py or in foo.py. I cannot say why it does not work for you. – mzjn Jul 31 '14 at 13:33
  • Would you expect me to have run sphinx-apidoc again after adding the `__module__` settings? I am using a variation on this that reflects my particular structure. I'll try running sphinx-apidoc again. – bmargulies Jul 31 '14 at 14:05
  • @bmargulies: I did not use sphinx-apidoc. I just created a very small project that includes an .rst file that has `.. automodule:: foo` in it. This allowed me to verify that `__module__` can be manipulated to achieve the desired effect. – mzjn Aug 01 '14 at 08:03
2

Refer this answer for a solution.

In your case, modify your __init__.py file to:

# This lets you use foo.foo.Foo as foo.Foo in your code.
from .foo import Foo

# This lets Sphinx know you want to document foo.foo.Foo as foo.Foo.
__all__ = ['Foo']
Nikhil Kumar
  • 1,015
  • 1
  • 9
  • 14
  • Sphinx just outputs "class foo.Foo: An alias of class foo.foo.Foo" and does not document any members. – Ark-kun Aug 18 '23 at 07:47