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