Show More
@@ -27,6 +27,40 b' class Obj(object):' | |||||
27 | def __init__(self, **kwargs): |
|
27 | def __init__(self, **kwargs): | |
28 | for k, v in kwargs.items(): |
|
28 | for k, v in kwargs.items(): | |
29 | setattr(self, k, v) |
|
29 | setattr(self, k, v) | |
|
30 | ||||
|
31 | class FuncClsScanner(ast.NodeVisitor): | |||
|
32 | """Scan a module for top-level functions and classes. | |||
|
33 | ||||
|
34 | Skips objects with an @undoc decorator, or a name starting with '_'. | |||
|
35 | """ | |||
|
36 | def __init__(self): | |||
|
37 | ast.NodeVisitor.__init__(self) | |||
|
38 | self.classes = [] | |||
|
39 | self.classes_seen = set() | |||
|
40 | self.functions = [] | |||
|
41 | ||||
|
42 | @staticmethod | |||
|
43 | def has_undoc_decorator(node): | |||
|
44 | return any(isinstance(d, ast.Name) and d.id == 'undoc' \ | |||
|
45 | for d in node.decorator_list) | |||
|
46 | ||||
|
47 | def visit_FunctionDef(self, node): | |||
|
48 | if not (node.name.startswith('_') or self.has_undoc_decorator(node)) \ | |||
|
49 | and node.name not in self.functions: | |||
|
50 | self.functions.append(node.name) | |||
|
51 | ||||
|
52 | def visit_ClassDef(self, node): | |||
|
53 | if not (node.name.startswith('_') or self.has_undoc_decorator(node)) \ | |||
|
54 | and node.name not in self.classes_seen: | |||
|
55 | cls = Obj(name=node.name) | |||
|
56 | cls.has_init = any(isinstance(n, ast.FunctionDef) and \ | |||
|
57 | n.name=='__init__' for n in node.body) | |||
|
58 | self.classes.append(cls) | |||
|
59 | self.classes_seen.add(node.name) | |||
|
60 | ||||
|
61 | def scan(self, mod): | |||
|
62 | self.visit(mod) | |||
|
63 | return self.functions, self.classes | |||
30 |
|
64 | |||
31 | # Functions and classes |
|
65 | # Functions and classes | |
32 | class ApiDocWriter(object): |
|
66 | class ApiDocWriter(object): | |
@@ -158,33 +192,7 b' class ApiDocWriter(object):' | |||||
158 | return ([],[]) |
|
192 | return ([],[]) | |
159 | with open(filename, 'rb') as f: |
|
193 | with open(filename, 'rb') as f: | |
160 | mod = ast.parse(f.read()) |
|
194 | mod = ast.parse(f.read()) | |
161 |
return |
|
195 | return FuncClsScanner().scan(mod) | |
162 |
|
||||
163 | @staticmethod |
|
|||
164 | def _find_functions_classes(mod): |
|
|||
165 | """Extract top-level functions and classes from a module AST. |
|
|||
166 |
|
||||
167 | Skips objects with an @undoc decorator, or a name starting with '_'. |
|
|||
168 | """ |
|
|||
169 | def has_undoc_decorator(node): |
|
|||
170 | return any(isinstance(d, ast.Name) and d.id == 'undoc' \ |
|
|||
171 | for d in node.decorator_list) |
|
|||
172 |
|
||||
173 | functions, classes = [], [] |
|
|||
174 | for node in mod.body: |
|
|||
175 | if isinstance(node, ast.FunctionDef) and \ |
|
|||
176 | not node.name.startswith('_') and \ |
|
|||
177 | not has_undoc_decorator(node): |
|
|||
178 | functions.append(node.name) |
|
|||
179 | elif isinstance(node, ast.ClassDef) and \ |
|
|||
180 | not node.name.startswith('_') and \ |
|
|||
181 | not has_undoc_decorator(node): |
|
|||
182 | cls = Obj(name=node.name) |
|
|||
183 | cls.has_init = any(isinstance(n, ast.FunctionDef) and \ |
|
|||
184 | n.name=='__init__' for n in node.body) |
|
|||
185 | classes.append(cls) |
|
|||
186 |
|
||||
187 | return functions, classes |
|
|||
188 |
|
196 | |||
189 | def generate_api_doc(self, uri): |
|
197 | def generate_api_doc(self, uri): | |
190 | '''Make autodoc documentation template string for a module |
|
198 | '''Make autodoc documentation template string for a module |
General Comments 0
You need to be logged in to leave comments.
Login now