1 """Simple code to extract class & function docstrings from a module.
3 This code is used as an example in the library reference manual in the
4 section on using the parser module. Refer to the manual for a thorough
5 discussion of the operation of this code.
14 from types
import ListType
, TupleType
17 def get_docs(fileName
):
18 """Retrieve information from the parse tree of a source file.
21 Name of the file to read Python source code from.
23 source
= open(fileName
).read()
24 basename
= os
.path
.basename(os
.path
.splitext(fileName
)[0])
25 ast
= parser
.suite(source
)
26 return ModuleInfo(ast
.totuple(), basename
)
33 def __init__(self
, tree
= None):
35 self
._function
_info
= {}
37 self
._extract
_info
(tree
)
39 def _extract_info(self
, tree
):
42 found
, vars = match(DOCSTRING_STMT_PATTERN
[1], tree
[1])
44 found
, vars = match(DOCSTRING_STMT_PATTERN
, tree
[3])
46 self
._docstring
= eval(vars['docstring'])
47 # discover inner definitions
49 found
, vars = match(COMPOUND_STMT_PATTERN
, node
)
51 cstmt
= vars['compound']
52 if cstmt
[0] == symbol
.funcdef
:
54 self
._function
_info
[name
] = FunctionInfo(cstmt
)
55 elif cstmt
[0] == symbol
.classdef
:
57 self
._class
_info
[name
] = ClassInfo(cstmt
)
59 def get_docstring(self
):
60 return self
._docstring
65 def get_class_names(self
):
66 return self
._class
_info
.keys()
68 def get_class_info(self
, name
):
69 return self
._class
_info
[name
]
71 def __getitem__(self
, name
):
73 return self
._class
_info
[name
]
75 return self
._function
_info
[name
]
79 # Mixin class providing access to function names and info.
81 def get_function_names(self
):
82 return self
._function
_info
.keys()
84 def get_function_info(self
, name
):
85 return self
._function
_info
[name
]
88 class FunctionInfo(SuiteInfoBase
, SuiteFuncInfo
):
89 def __init__(self
, tree
= None):
90 self
._name
= tree
[2][1]
91 SuiteInfoBase
.__init
__(self
, tree
and tree
[-1] or None)
94 class ClassInfo(SuiteInfoBase
):
95 def __init__(self
, tree
= None):
96 self
._name
= tree
[2][1]
97 SuiteInfoBase
.__init
__(self
, tree
and tree
[-1] or None)
99 def get_method_names(self
):
100 return self
._function
_info
.keys()
102 def get_method_info(self
, name
):
103 return self
._function
_info
[name
]
106 class ModuleInfo(SuiteInfoBase
, SuiteFuncInfo
):
107 def __init__(self
, tree
= None, name
= "<string>"):
109 SuiteInfoBase
.__init
__(self
, tree
)
111 found
, vars = match(DOCSTRING_STMT_PATTERN
, tree
[1])
113 self
._docstring
= vars["docstring"]
116 def match(pattern
, data
, vars=None):
117 """Match `data' to `pattern', with variable extraction.
120 Pattern to match against, possibly containing variables.
123 Data to be checked and against which variables are extracted.
126 Dictionary of variables which have already been found. If not
127 provided, an empty dictionary is created.
129 The `pattern' value may contain variables of the form ['varname'] which
130 are allowed to match anything. The value that is matched is returned as
131 part of a dictionary which maps 'varname' to the matched value. 'varname'
132 is not required to be a string object, but using strings makes patterns
133 and the code which uses them more readable.
135 This function returns two values: a boolean indicating whether a match
136 was found and a dictionary mapping variable names to their associated
141 if type(pattern
) is ListType
: # 'variables' are ['varname']
142 vars[pattern
[0]] = data
144 if type(pattern
) is not TupleType
:
145 return (pattern
== data
), vars
146 if len(data
) != len(pattern
):
148 for pattern
, data
in map(None, pattern
, data
):
149 same
, vars = match(pattern
, data
, vars)
155 # This pattern identifies compound statements, allowing them to be readily
156 # differentiated from simple statements.
158 COMPOUND_STMT_PATTERN
= (
160 (symbol
.compound_stmt
, ['compound'])
164 # This pattern will match a 'stmt' node which *might* represent a docstring;
165 # docstrings require that the statement which provides the docstring be the
166 # first statement in the class or function, which this pattern does not check.
168 DOCSTRING_STMT_PATTERN
= (
187 (token
.STRING
, ['docstring'])