25

I have a bunch of classes which use "special-methods":

class Foo(object):
   "Foo docstring"

   attr1 = "Attribute!" #: first attribute
   attr2 = "Another Attribute!" #: second attribute

   def __init__(self):
       self.x = 12

   def say_hello(self):
       """
       say_hello(self) -> None

       Issue a friendly greeting.
       """
       print "Hello! x is {0}".format(self.x)

   def __contains__(self,other):
       """Implement ``other in self``"""
       return other == self.x

now I would like to generate html documentation for this using Sphinx and autodoc. How do I tell Sphinx to document __contains__? I tried adding

autodoc_default_flags = ['members', 'undoc-members', 'special-members']

to conf.py, but that also included __dict__ which I definitely don't want.

Currently, the relevant portions of the myproject.rst file look like:

.. automodule:: myproject.foomodule
    :members:
    :undoc-members:
    :show-inheritance:

edit adding

.. automodule:: myproject.foomodule
    :members:
    :undoc-members:
    :show-inheritance:

.. automethod:: myproject.foomodule.Foo.__contains__

does add documentation of that method, but in a separate section -- Not as part of the Foo class documentation.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • @GarethRees -- If you must know, my use case is that the class `Foo` is something of a poor man's ABC. It's docstrings tell the user what the expected behavior of it's subclasses are and it raises `NotImplementedErrors`. I want to document `__contains__` so the user knows what `if x in foo_subclass_instance` is expected to mean, but this could just as easily have been a special `__getitem__` method which doesn't behave in a completely standard way. – mgilson Apr 09 '13 at 13:59

5 Answers5

21

You can add:

:special-members:
:exclude-members: __dict__,__weakref__

To the .rst file in order to show special members, except __dict__ and __weakref__

arutaku
  • 5,937
  • 1
  • 24
  • 38
15

What worked for me is adding the ".. automethod:: methodName"

directive in the docstring of the class, instead of doing it in the .rst file.

So, you can change "Foo docstring" to

"""
Foo docstring

.. automethod:: __contains__
"""
rb3363392
  • 151
  • 1
  • 2
  • Thank you! It really worked. I added this directive to the `rst`, and it worked fine (I didn't want to mess my class documentation with what is shown in Sphinx). – Yaroslav Nikitenko Nov 04 '21 at 14:53
  • There was a bug connected to `special-members`, it was fixed in 1.8 (https://github.com/sphinx-doc/sphinx/issues/2401). I filed another bug now, https://github.com/sphinx-doc/sphinx/issues/9818 . – Yaroslav Nikitenko Nov 04 '21 at 15:43
11

The special-members option now takes arguments (this is a new feature in Sphinx 1.2).

So this should work:

.. automodule:: myproject.foomodule
    :members:
    :undoc-members:
    :special-members: __contains__
    :show-inheritance:
mzjn
  • 48,958
  • 13
  • 128
  • 248
4

Since Sphinx 1.8, you can use autodoc_default_options in conf.py. Example:

autodoc_default_options = {
    'members': 'var1, var2',
    'member-order': 'bysource',
    'special-members': '__init__',
    'undoc-members': True,
    'exclude-members': '__weakref__'
}

Setting None or True to the value is equivalent to giving only the option name to the directives.

Note that you can give several values in one string: '__init__,__call__'.

Yaroslav Nikitenko
  • 1,695
  • 2
  • 23
  • 31
3

I'm currently not 100% thrilled with this solution, so I hope someone can come along an improve it. However, the way I've solved this problem is to do the following:

.. automodule:: myproject.foomodule
    :members:
    :undoc-members:
    :show-inheritance:

    .. autoclass:: myproject.foomodule.Foo
        :exclude-members: attr1,attr2

        .. autoattribute:: myproject.foomodule.Foo.attr1 

        .. autoattribute:: myproject.foomodule.Foo.attr2 

        .. automethod:: myproject.foomodule.Foo.__contains__

Here I actually need to tell autodoc to avoid documenting the class attributes (automatically) and then I need to add them back on explicitly. The reason is because apparently when you explicitly nest commands, the explicit ones come first. If I only explicitly say to add __contains__, then it shows up before the attributes which I didn't like.

mgilson
  • 300,191
  • 65
  • 633
  • 696