Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent Sphinx from listing "object" as a base class?

I have this class:

class Class:
    pass

The documentation generated by sphinx (in case it matters, I used the autodoc extension) looks like this:

class package.Class

     Bases: object

The inheritance from object isn't useful information for the reader, and therefore I don't want it in my documentation. The output I'd like to see is this:

class package.Class


Is there a way to exclude object from the list of base classes?

like image 492
Aran-Fey Avatar asked Sep 18 '17 12:09

Aran-Fey


People also ask

What does Sphinx Autodoc do?

autodoc imports the modules to be documented. If any modules have side effects on import, these will be executed by autodoc when sphinx-build is run. If you document scripts (as opposed to library modules), make sure their main routine is protected by a if __name__ == '__main__' condition.

What is Sphinx Apidoc?

sphinx-apidoc is a tool for automatic generation of Sphinx sources that, using the autodoc extension, document a whole package in the style of other automatic API documentation tools. MODULE_PATH is the path to a Python package to document, and OUTPUT_PATH is the directory where the generated sources are placed.

What is conf py?

The configuration directory must contain a file named conf.py . This file (containing Python code) is called the “build configuration file” and contains (almost) all configuration needed to customize Sphinx input and output behavior. An optional file docutils.


2 Answers

This is actually deeply embedded in the autodoc source code, with no way to turn it off:

bases = [b.__module__ in ('__builtin__', 'builtins') and
         u':class:`%s`' % b.__name__ or
         u':class:`%s.%s`' % (b.__module__, b.__name__)
         for b in self.object.__bases__]
self.add_line(u'   ' + _(u'Bases: %s') % ', '.join(bases), sourcename)

object isn't given any special treatment; there's no builtin way to exclude it from the list.


The best (automatic) solution I could find was to monkeypatch autodoc.

Adding this to conf.py enables the desired behavior:

# ClassDocumenter.add_directive_header uses ClassDocumenter.add_line to
#   write the class documentation.
# We'll monkeypatch the add_line method and intercept lines that begin
#   with "Bases:".
# In order to minimize the risk of accidentally intercepting a wrong line,
#   we'll apply this patch inside of the add_directive_header method.

from sphinx.ext.autodoc import ClassDocumenter, _

add_line = ClassDocumenter.add_line
line_to_delete = _(u'Bases: %s') % u':class:`object`'

def add_line_no_object_base(self, text, *args, **kwargs):
    if text.strip() == line_to_delete:
        return

    add_line(self, text, *args, **kwargs)

add_directive_header = ClassDocumenter.add_directive_header

def add_directive_header_no_object_base(self, *args, **kwargs):
    self.add_line = add_line_no_object_base.__get__(self)

    result = add_directive_header(self, *args, **kwargs)

    del self.add_line

    return result

ClassDocumenter.add_directive_header = add_directive_header_no_object_base
like image 64
Aran-Fey Avatar answered Oct 06 '22 02:10

Aran-Fey


Disclaimer: This may not be the best or most elegant solution, because the more plain classes you have (that subclass object only), the more work you will have to do as you have to preprocess each class manually.


If you are using autoclass directive to document the class, simply don't use the :show-inheritance: option. If you are using automodule to generate documentation for all module members, turning :show-inheritance: off will not help as no base classes will be documented for each class in module. Thus, I would go with the following:

Step 1: Document the class outside of the module without :show-inheritance: like this:

my\.mod module
--------------

.. automodule:: my.mod
   :members:
   :undoc-members:
   :show-inheritance:

.. autoclass:: Class
   :members:
   :undoc-members:

Step 2: Filter class Class out of module's automodule documentation in your conf.py via autodoc-skip-member hook:

def skip_some_classes(app, what, name, obj, skip, options):
    return skip or name in ('Class',)  # define some better condition here

def setup(app):
    app.connect('autodoc-skip-member', skip_some_classes)

This way, all module members except Class will be processed with :show-inheritance: option, while Class is treated separately.

like image 39
hoefling Avatar answered Oct 06 '22 01:10

hoefling