Show More
@@ -64,6 +64,7 b' from IPython.utils import PyColorize' | |||
|
64 | 64 | from IPython.utils import io |
|
65 | 65 | from IPython.utils import py3compat |
|
66 | 66 | from IPython.utils import openpy |
|
67 | from IPython.utils.decorators import undoc | |
|
67 | 68 | from IPython.utils.doctestreload import doctest_reload |
|
68 | 69 | from IPython.utils.io import ask_yes_no |
|
69 | 70 | from IPython.utils.ipstruct import Struct |
@@ -90,6 +91,7 b" dedent_re = re.compile(r'^\\s+raise|^\\s+return|^\\s+pass')" | |||
|
90 | 91 | # Utilities |
|
91 | 92 | #----------------------------------------------------------------------------- |
|
92 | 93 | |
|
94 | @undoc | |
|
93 | 95 | def softspace(file, newvalue): |
|
94 | 96 | """Copied from code.py, to remove the dependency""" |
|
95 | 97 | |
@@ -105,9 +107,10 b' def softspace(file, newvalue):' | |||
|
105 | 107 | pass |
|
106 | 108 | return oldvalue |
|
107 | 109 | |
|
108 | ||
|
110 | @undoc | |
|
109 | 111 | def no_op(*a, **kw): pass |
|
110 | 112 | |
|
113 | @undoc | |
|
111 | 114 | class NoOpContext(object): |
|
112 | 115 | def __enter__(self): pass |
|
113 | 116 | def __exit__(self, type, value, traceback): pass |
@@ -115,6 +118,7 b' no_op_context = NoOpContext()' | |||
|
115 | 118 | |
|
116 | 119 | class SpaceInInput(Exception): pass |
|
117 | 120 | |
|
121 | @undoc | |
|
118 | 122 | class Bunch: pass |
|
119 | 123 | |
|
120 | 124 |
@@ -44,3 +44,11 b' def flag_calls(func):' | |||
|
44 | 44 | wrapper.__doc__ = func.__doc__ |
|
45 | 45 | return wrapper |
|
46 | 46 | |
|
47 | def undoc(func): | |
|
48 | """Mark a function or class as undocumented. | |
|
49 | ||
|
50 | This is found by inspecting the AST, so for now it must be used directly | |
|
51 | as @undoc, not as e.g. @decorators.undoc | |
|
52 | """ | |
|
53 | return func | |
|
54 |
@@ -18,6 +18,7 b" PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed" | |||
|
18 | 18 | project.""" |
|
19 | 19 | |
|
20 | 20 | # Stdlib imports |
|
21 | import ast | |
|
21 | 22 | import os |
|
22 | 23 | import re |
|
23 | 24 | |
@@ -94,21 +95,6 b' class ApiDocWriter(object):' | |||
|
94 | 95 | package_name = property(get_package_name, set_package_name, None, |
|
95 | 96 | 'get/set package_name') |
|
96 | 97 | |
|
97 | def _get_object_name(self, line): | |
|
98 | ''' Get second token in line | |
|
99 | >>> docwriter = ApiDocWriter('sphinx') | |
|
100 | >>> docwriter._get_object_name(" def func(): ") | |
|
101 | 'func' | |
|
102 | >>> docwriter._get_object_name(" class Klass(object): ") | |
|
103 | 'Klass' | |
|
104 | >>> docwriter._get_object_name(" class Klass: ") | |
|
105 | 'Klass' | |
|
106 | ''' | |
|
107 | name = line.split()[1].split('(')[0].strip() | |
|
108 | # in case we have classes which are not derived from object | |
|
109 | # ie. old style classes | |
|
110 | return name.rstrip(':') | |
|
111 | ||
|
112 | 98 | def _uri2path(self, uri): |
|
113 | 99 | ''' Convert uri to absolute filepath |
|
114 | 100 | |
@@ -164,30 +150,31 b' class ApiDocWriter(object):' | |||
|
164 | 150 | if filename is None: |
|
165 | 151 | # nothing that we could handle here. |
|
166 | 152 | return ([],[]) |
|
167 |
|
|
|
168 | functions, classes = self._parse_lines(f) | |
|
169 | f.close() | |
|
170 | return functions, classes | |
|
171 | ||
|
172 | def _parse_lines(self, linesource): | |
|
173 | ''' Parse lines of text for functions and classes ''' | |
|
174 | functions = [] | |
|
175 | classes = [] | |
|
176 | for line in linesource: | |
|
177 | if line.startswith('def ') and line.count('('): | |
|
178 | # exclude private stuff | |
|
179 | name = self._get_object_name(line) | |
|
180 | if not name.startswith('_'): | |
|
181 | functions.append(name) | |
|
182 | elif line.startswith('class '): | |
|
183 | # exclude private stuff | |
|
184 | name = self._get_object_name(line) | |
|
185 | if not name.startswith('_'): | |
|
186 |
|
|
|
187 | else: | |
|
188 | pass | |
|
189 | functions.sort() | |
|
190 | classes.sort() | |
|
153 | with open(filename, 'rb') as f: | |
|
154 | mod = ast.parse(f.read()) | |
|
155 | return self._find_functions_classes(mod) | |
|
156 | ||
|
157 | @staticmethod | |
|
158 | def _find_functions_classes(mod): | |
|
159 | """Extract top-level functions and classes from a module AST. | |
|
160 | ||
|
161 | Skips objects with an @undoc decorator, or a name starting with '_'. | |
|
162 | """ | |
|
163 | def has_undoc_decorator(node): | |
|
164 | return any(isinstance(d, ast.Name) and d.id == 'undoc' \ | |
|
165 | for d in node.decorator_list) | |
|
166 | ||
|
167 | functions, classes = [], [] | |
|
168 | for node in mod.body: | |
|
169 | if isinstance(node, ast.FunctionDef) and \ | |
|
170 | not node.name.startswith('_') and \ | |
|
171 | not has_undoc_decorator(node): | |
|
172 | functions.append(node.name) | |
|
173 | elif isinstance(node, ast.ClassDef) and \ | |
|
174 | not node.name.startswith('_') and \ | |
|
175 | not has_undoc_decorator(node): | |
|
176 | classes.append(node.name) | |
|
177 | ||
|
191 | 178 | return functions, classes |
|
192 | 179 | |
|
193 | 180 | def generate_api_doc(self, uri): |
General Comments 0
You need to be logged in to leave comments.
Login now