2

I have several modules that are within a Python package:

# my_package contents
__init__.py
module1.py
module2.py

Within my __init__.py, I'm importing these modules so that they will be accessible once the package is imported by my users.

# __init__.py
import module1
import module2

My question is: how do I programatically access the docstrings for each of my defined functions within each of these modules? I've seen others use a form of this:

getattr(module, key). __doc__

but I can't get it to work for me. Any ideas?

EDIT: A little more background... we're trying to extract content (one of the important things is the docstrings) from our python packages with the intent of using that as content for documentation. My boss has something already set up that we're trying to feed into.

Ideally, I'd like to have a package.module.function docstring result

EDIT2: Here's what is currently not working:

#my package is named 'tpp'
import tpp

for script in dir(tpp):
    if not "__" in script: #not a builtin...
        docstrings1 = getattr( tpp, script).__doc__
        docstrings2 = " ".join(docstrings1.split())#clean out any newline chars
        print script, docstrings

EDIT3: To get a picture of where the docstrings are and how we've organized things:

import inspect
import tpp

inspect.getdoc(tpp)
#returns None

inspect.getdoc(tpp.module1)
#returns None

inspect.getdoc(tpp.module1.function1)
#'DOCSTRING TEXT FOUND!'

**Ultimately, I'd like to get a list like ['module1', 'function1', 'DOCSTRING TEXT FOUND!']

4
  • It's not clear why you need to access the docstrings for functions in there. Can you clarify? (Also, your import statement examples shouldn't have trailing .pys :) Commented Jul 25, 2012 at 14:24
  • One option to access all docstrings is pydoc my_package. Please provide more context on what your actual aim is. Commented Jul 25, 2012 at 14:27
  • "but I can't get it to work for me" -- what's wrong, does it raise an exception? what's the error? Commented Jul 25, 2012 at 14:41
  • @mgilson - updated w/ example above Commented Jul 25, 2012 at 14:50

2 Answers 2

1

Maybe you want something like this:

for script in dir(tpp):
    if not "__" in script: #not a builtin...
        docstrings1 = getattr( tpp, script).__doc__
        if docstrings1:  #objects without docstrings return None above, which can't be split.
            docstrings2 = " ".join(docstrings1.split())#clean out any newline chars
            print script, docstrings2

but I don't guarantee that this will get all the docstrings. You may need to recursively go into items that you retrieve with getattr.

Here's a recursive version (which probably will get way more than you want) and will choke on circular dependencies:

def get_all_doc(obj,indent=''):
    for item in filter(lambda x:not x.startswith('__'),dir(obj)):
        o=getattr(obj,item)
        print "{indent}{item} {doc}".format(indent=indent,
                                            item=item,
                                            doc=o.__doc__)
        get_all_doc(o,indent=indent+'   ')
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer, mgilson! As you suspected, this only inspects the module as a whole, not any defined functions within the module (don't know if I'm saying it right :)
Any ideas on how to recursively get to the functions (and ultimately, the docstrings) within?
using your recursive version, i'm just getting the modules, not their internal functions & docstrings. the print statement gives me: ' module1 None' then ' module2 None'
@JGraham -- it mostly works for me. (I get recursion errors because I haven't set my recursion limit high enough, or I may have circular dependencies). You could try printing out the result of the filter expression and see if that is illuminating at all.
Thanks for your help, here. hmmm. Using my local example (see Edit1 above), I'm still just getting the base modules. See Edit2 for some more detail about how my data are organized... I have a feeling I haven't explained this well enough.
1

Use inspect.getdoc(object) to get the docstring of an object. Use inspect.isfunction to check if an object is a function.

import inspect
for variable in vars(module).values():
    if inspect.isfunction(variable):
        print(inspect.getdoc(variable))

Note that inspect.getdoc returns None when there is no docstring for the object and so the code will print None if there is no docstring for the function.

2 Comments

Thanks for the response, Ramchandra... so, if I take your example and use my package name (tpp) in place of <code>module</code> the code never gets to the print statement.
tpp may not have functions it may only have callables - are you sure it has functions try vars(tpp) and check if you see <function object at ...>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.