Get dosctring without import

J

Joan Miller

When a package is imported, it gets the dosctring to store it in
*__doc__*.

Does that funcion is built in python? because I would want use it to
get the docstring without import a package
 
D

Diez B. Roggisch

Am 26.02.10 09:55, schrieb Joan Miller:
When a package is imported, it gets the dosctring to store it in
*__doc__*.

Does that funcion is built in python? because I would want use it to
get the docstring without import a package

You'd need to write your own parser for that. All standard tools simply
import, see another thread a few days ago where a user had problems with
help on modules.

Also, without importing, you'd not get docstrings of C-extension-objects.

Diez
 
J

Jean-Michel Pichavant

Joan said:
When a package is imported, it gets the dosctring to store it in
*__doc__*.

Does that funcion is built in python? because I would want use it to
get the docstring without import a package
Epydoc, a documentation builder is able to do so with the --parse-only
option. You could take a look at the code, even grab their parser to
suit your needs. It may be quite difficult though.

JM
 
P

Peter Otten

Joan said:
When a package is imported, it gets the dosctring to store it in
*__doc__*.

Does that funcion is built in python? because I would want use it to
get the docstring without import a package

Something to get you started:


import ast


def walk(root, stack):
for node in ast.iter_child_nodes(root):
if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
yield node
stack.append(node)
for child in walk(node, stack):
yield child
del stack[-1]

def get_name(node):
try:
return node.name
except AttributeError:
return "(%s)" % node.__class__.__name__

def get_path(path):
return ".".join(get_name(node) for node in path)

def find_docstrings(filename):
with open(filename) as f:
module = ast.parse(f.read())
print filename.center(len(filename) + 2).center(80, "=")
print ast.get_docstring(module)
print "=" * 80
print

path = []
for node in walk(module, path):
s = ast.get_docstring(node)
if s is not None:
name = get_path(path + [node])
print name.center(len(name) + 2).center(80, "-")
print s
print


if __name__ == "__main__":
import sys
args = sys.argv[1:]
if args:
for arg in args:
find_docstrings(arg)
else:
find_docstrings("/usr/lib/python2.6/unittest.py")
assert "unittest" not in sys.modules

To get an idea of the differences to the import-based approach try analysing
the following script:

import random

if random.choice([True, False]):
def f():
"say hello"
else:
def f():
"kill a kitten"

def g():
"whatever"
del g

Peter
 
J

Joan Miller

Joan, in this message and numerous others you've been following the
widespread convention of using asterisks ‘*’ to surround text you want
to emphasise.

Normally that's good, but in a programming-language context (or any
other where asterisks have a separate established meaning), it's not a
good idea. In many cases, asterisks signify “match any number of
arbitrary characters at this position”, which gives a rather different
meaning to what you're writing.

You might be better off using quotes (like '__doc__' or ‘__doc__’), or
the reStructuredText syntax for demarcating a special element, backticks
(like `__doc__`). Even they need to be used with care, though, because
they also have specific established meanings (except the typographical
quotes, which is why I use them).

I hope that helps.


Why is it you want to do this? Modules should not have unwanted side
effects when imported; if you can't import the module without invoking
those unwanted side effects, the module is poorly written.

That's not to say that such poorly-written modules don't exist. What is
the situation? Perhaps there's a better solution.
I use a function in 'setupy.py' to get automatically the description
from the package's docstring, but there is a problem when you import a
module that has to be built by cython (because it tries load a module
that doesn't exists).
 
J

Joan Miller

Joan said:
When a package is imported, it gets the dosctring to store it in
*__doc__*.
Does that funcion is built in python? because I would want use it to
get the docstring without import a package

Something to get you started:

import ast

def walk(root, stack):
    for node in ast.iter_child_nodes(root):
        if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
            yield node
        stack.append(node)
        for child in walk(node, stack):
            yield child
        del stack[-1]

def get_name(node):
    try:
        return node.name
    except AttributeError:
        return "(%s)" % node.__class__.__name__

def get_path(path):
    return ".".join(get_name(node) for node in path)

def find_docstrings(filename):
    with open(filename) as f:
        module = ast.parse(f.read())
    print filename.center(len(filename) + 2).center(80, "=")
    print ast.get_docstring(module)
    print "=" * 80
    print

    path = []
    for node in walk(module, path):
        s = ast.get_docstring(node)
        if s is not None:
            name = get_path(path + [node])
            print name.center(len(name) + 2).center(80, "-")
            print s
            print

if __name__ == "__main__":
    import sys
    args = sys.argv[1:]
    if args:
        for arg in args:
            find_docstrings(arg)
    else:
        find_docstrings("/usr/lib/python2.6/unittest.py")
        assert "unittest" not in sys.modules

To get an idea of the differences to the import-based approach try analysing
the following script:

import random

if random.choice([True, False]):
    def f():
        "say hello"
else:
    def f():
        "kill a kitten"

def g():
    "whatever"
del g

Peter

Thanks! What I need there is:
 
J

Joan Miller

A simple approach (at least, simpler than crawling a parse tree) might
be to store the package description in a separate non-executable file.

A common convention is to have a ‘README’ text file, written in
reStructuredText for rendering to various output formats as part of the
documentation. You could then have the ‘setup.py’ program read the
contents of that file and use it (or a slice of it) for the package
description.
I get the 'README.txt' file to get the long description but I use the
docstring because each package should include a short desciption about
it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top