##// END OF EJS Templates
Add way to mark classes & functions as undocumented.
Thomas Kluyver -
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 f = open(filename, 'rt')
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 classes.append(name)
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