[Python-Dev] Re: [PEP 224] Attribute Docstrings (original) (raw)

Ka-Ping Yee ping@lfw.org
Tue, 29 Aug 2000 15:43:23 -0500 (CDT)


On Tue, 29 Aug 2000, Christian Tanzer wrote:

Triple quoted strings work -- that's what I'm constantly using. The downside is, that the docstrings either contain spurious white space or it messes up the layout of the code (if you start subsequent lines in the first column).

The "inspect" module (see http://www.lfw.org/python/) handles this nicely.

Python 1.5.2 (#4, Jul 21 2000, 18:28:23) [C] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import inspect
>>> class Foo:
...     """First line.
...        Second line.
...            An indented line.
...        Some more text."""
... 
>>> inspect.getdoc(Foo)
'First line.\012Second line.\012    An indented line.\012Some more text.'
>>> print _
First line.
Second line.
    An indented line.
Some more text.
>>>        

I suggested "inspect.py" for the standard library quite some time ago (long before the feature freeze, and before ascii.py, which has since made it in). MAL responded pretty enthusiastically (http://www.python.org/pipermail/python-dev/2000-July/013511.html). Could i request a little more feedback from others?

It's also quite handy for other purposes. It can get the source code for a given function or class:

>>> func = inspect.getdoc
>>> inspect.getdoc(func)
'Get the documentation string for an object.'
>>> inspect.getfile(func)
'inspect.py'
>>> lines, lineno = inspect.getsource(func)
>>> print string.join(lines)
def getdoc(object):
     """Get the documentation string for an object."""
     if not hasattr(object, "__doc__"):
         raise TypeError, "arg has no __doc__ attribute"
     if object.__doc__:
         lines = string.split(string.expandtabs(object.__doc__), "\n")
         margin = None
         for line in lines[1:]:
             content = len(string.lstrip(line))
             if not content: continue
             indent = len(line) - content
             if margin is None: margin = indent
             else: margin = min(margin, indent)
         if margin is not None:
             for i in range(1, len(lines)): lines[i] = lines[i][margin:]
         return string.join(lines, "\n")

And it can get the argument spec for a function:

>>> inspect.getargspec(func)
(['object'], None, None, None)
>>> apply(inspect.formatargspec, _)
'(object)'

Here's a slightly more challenging example:

>>> def func(a, (b, c), (d, (e, f), (g,)), h=3): pass
... 
>>> inspect.getargspec(func)
(['a', ['b', 'c'], ['d', ['e', 'f'], ['g']], 'h'], None, None, (3,))
>>> apply(inspect.formatargspec, _)
'(a, (b, c), (d, (e, f), (g,)), h=3)'
>>> 

-- ?!ng