Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Autodocument classes defined inside if blocks, such as in py3compat

  • Loading branch information...
commit 3928675c5ce0c53622abeaf52ae2452c3542d79e 1 parent e44cbbd
@takluyver authored
Showing with 35 additions and 27 deletions.
  1. +35 −27 docs/sphinxext/apigen.py
View
62 docs/sphinxext/apigen.py
@@ -27,6 +27,40 @@ class Obj(object):
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
+
+class FuncClsScanner(ast.NodeVisitor):
+ """Scan a module for top-level functions and classes.
+
+ Skips objects with an @undoc decorator, or a name starting with '_'.
+ """
+ def __init__(self):
+ ast.NodeVisitor.__init__(self)
+ self.classes = []
+ self.classes_seen = set()
+ self.functions = []
+
+ @staticmethod
+ def has_undoc_decorator(node):
+ return any(isinstance(d, ast.Name) and d.id == 'undoc' \
+ for d in node.decorator_list)
+
+ def visit_FunctionDef(self, node):
+ if not (node.name.startswith('_') or self.has_undoc_decorator(node)) \
+ and node.name not in self.functions:
+ self.functions.append(node.name)
+
+ def visit_ClassDef(self, node):
+ if not (node.name.startswith('_') or self.has_undoc_decorator(node)) \
+ and node.name not in self.classes_seen:
+ cls = Obj(name=node.name)
+ cls.has_init = any(isinstance(n, ast.FunctionDef) and \
+ n.name=='__init__' for n in node.body)
+ self.classes.append(cls)
+ self.classes_seen.add(node.name)
+
+ def scan(self, mod):
+ self.visit(mod)
+ return self.functions, self.classes
# Functions and classes
class ApiDocWriter(object):
@@ -158,33 +192,7 @@ def _parse_module(self, uri):
return ([],[])
with open(filename, 'rb') as f:
mod = ast.parse(f.read())
- return self._find_functions_classes(mod)
-
- @staticmethod
- def _find_functions_classes(mod):
- """Extract top-level functions and classes from a module AST.
-
- Skips objects with an @undoc decorator, or a name starting with '_'.
- """
- def has_undoc_decorator(node):
- return any(isinstance(d, ast.Name) and d.id == 'undoc' \
- for d in node.decorator_list)
-
- functions, classes = [], []
- for node in mod.body:
- if isinstance(node, ast.FunctionDef) and \
- not node.name.startswith('_') and \
- not has_undoc_decorator(node):
- functions.append(node.name)
- elif isinstance(node, ast.ClassDef) and \
- not node.name.startswith('_') and \
- not has_undoc_decorator(node):
- cls = Obj(name=node.name)
- cls.has_init = any(isinstance(n, ast.FunctionDef) and \
- n.name=='__init__' for n in node.body)
- classes.append(cls)
-
- return functions, classes
+ return FuncClsScanner().scan(mod)
def generate_api_doc(self, uri):
'''Make autodoc documentation template string for a module
Please sign in to comment.
Something went wrong with that request. Please try again.