9

I am using sphinx with the autodoc extension, and would like to generate a list only containing the undocumented member functions in several modules, and not the documented members.

I can successfully create a list that includes both documented members and undocumented members as follows:

.. automodule:: module
    :members:
    :undoc-members:

Using the :members: directive alone creates the list of documented members only, as expected.

.. automodule:: module
    :members:

But using just the :undoc-members: directive alone (i.e. omitting the :members: flag) does not result in any list at all:

.. automodule:: module
    :undoc-members:

Is there a way to automatically generate this?

(The primary documentation includes a page that shows all the documented members, but I'd find it far more useful to ensure I have written docs for each function etc by having a single page that lists any undocumented member, without showing the text for those that are documented).

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Bonlenfum
  • 19,101
  • 2
  • 53
  • 56
  • If this is about finding and documenting these undocumented members, there ought to be a way to list those automatically during build... if not built in, there's an event (`autodoc-process-docstring`) that might be useful, but requires writing your own sphinx extension. –  Jan 03 '13 at 16:29
  • OK thanks @delnan, I'll look into writing an extension. – Bonlenfum Jan 08 '13 at 19:54

2 Answers2

7

Overriding the autodoc-process-docstring event (as noted by @delnan) can help, by adding the following to conf.py:

# set up the types of member to check that are documented
members_to_watch = ['function',];

def warn_undocumented_members(app, what, name, obj, options, lines):
    if(what in members_to_watch and len(lines)==0):
        # warn to terminal during build
        print "Warning: ", what, "is undocumented: ", name, "(%d)"% len(lines);
        # or modify the docstring so the rendered output is highlights the omission
        lines.append(".. Warning:: %s '%s' undocumented" % (what, name));

And then connect this function to the event (from an answer in this SO thread):

def setup(app):
    app.connect('autodoc-process-docstring', warn_undocumented_members);

To turn on (off) the warnings include (exclude) the undoc-members -- globally with autodoc_default_flags in conf.py, or with both the directives as in the question.

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

EDIT:

I attempted to extend this approach to generate just the undoc members, by the following method:

  • conditionally set a property, say, warn_undoc=True, on the object during during the function warn_undocumented_members (above)
  • attach a second override function to the preprocessor event autodoc-skip-member that skipped all members if they did not have warn_undoc set.

However, further investigation rules this approach out, because autodoc-skip-member occurs for each group of members before autodoc-process-docstring occurs. Thus, the properties are set too late to conditionally skip based on presence/absence of docstrings.

Community
  • 1
  • 1
Bonlenfum
  • 19,101
  • 2
  • 53
  • 56
  • This doesn't totally answer my the question, because it still doesn't provide a way to generate a page with *only* the undoc members, but it does provide access to information to find (&hence document) them. – Bonlenfum Jan 09 '13 at 15:17
0

From Skipping Members, add this to your conf.py:

def skip_non_undoc(app, what, name, obj, skip, options):
    # if undoc-members is set, show only undocumented members
    if 'undoc-members' in options and obj.__doc__ is not None:
        # skip member that have a __doc__
        return True
    else:
        return None

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

Using options members and undoc-members should now only show undocumented members. However, it will always do so wherever you use undoc-members. If there's some situations where you want to show only undocumented members and some where you want to show both, then you'll need to implement some more sophisticated checks in that function.

Maybe this'll help if you've been scratching your head over this for the past 6 years?

snazzybouche
  • 2,241
  • 3
  • 21
  • 51