summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-03-14 21:08:52 +0100
committerGeorg Brandl <georg@python.org>2009-03-14 21:08:52 +0100
commitc85d4c2db2a31d451bbc1144de216689d1a3963f (patch)
treee3f66ea47b82e4b4f5195f3404c4336fe6dbbafa
parentce4d9c3665637c3b9644077c2bb32cb97ecdd061 (diff)
downloadsphinx-git-c85d4c2db2a31d451bbc1144de216689d1a3963f.tar.gz
Work a bit on coding style of autosummary.
-rwxr-xr-xsphinx-autogen.py15
-rw-r--r--sphinx/ext/autosummary/__init__.py160
-rw-r--r--sphinx/ext/autosummary/generate.py172
-rw-r--r--sphinx/ext/autosummary/templates/module (renamed from sphinx/ext/autosummary/templates/module.html)0
4 files changed, 197 insertions, 150 deletions
diff --git a/sphinx-autogen.py b/sphinx-autogen.py
new file mode 100755
index 000000000..494f4d85a
--- /dev/null
+++ b/sphinx-autogen.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+ Sphinx - Python documentation toolchain
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: 2007-2009 by Georg Brandl.
+ :license: BSD.
+"""
+
+import sys
+
+if __name__ == '__main__':
+ from sphinx.ext.autosummary.generate import main
+ sys.exit(main(sys.argv))
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index f26c46769..8775fe868 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -1,80 +1,73 @@
+# -*- coding: utf-8 -*-
"""
-===========
-autosummary
-===========
+ sphinx.ext.autosummary
+ ~~~~~~~~~~~~~~~~~~~~~~
-Sphinx extension that adds an autosummary:: directive, which can be
-used to generate function/method/attribute/etc. summary lists, similar
-to those output eg. by Epydoc and other API doc generation tools.
+ Sphinx extension that adds an autosummary:: directive, which can be
+ used to generate function/method/attribute/etc. summary lists, similar
+ to those output eg. by Epydoc and other API doc generation tools.
-An :autolink: role is also provided.
+ An :autolink: role is also provided.
-autosummary directive
----------------------
+ autosummary directive
+ ---------------------
-The autosummary directive has the form::
+ The autosummary directive has the form::
- .. autosummary::
- :nosignatures:
- :toctree: generated/
-
- module.function_1
- module.function_2
- ...
+ .. autosummary::
+ :nosignatures:
+ :toctree: generated/
-and it generates an output table (containing signatures, optionally)
+ module.function_1
+ module.function_2
+ ...
- ======================== =============================================
- module.function_1(args) Summary line from the docstring of function_1
- module.function_2(args) Summary line from the docstring
- ...
- ======================== =============================================
+ and it generates an output table (containing signatures, optionally)
-If the :toctree: option is specified, files matching the function names
-are inserted to the toctree with the given prefix:
+ ======================== =============================================
+ module.function_1(args) Summary line from the docstring of function_1
+ module.function_2(args) Summary line from the docstring
+ ...
+ ======================== =============================================
- generated/module.function_1
- generated/module.function_2
- ...
+ If the :toctree: option is specified, files matching the function names
+ are inserted to the toctree with the given prefix:
-Note: The file names contain the module:: or currentmodule:: prefixes.
+ generated/module.function_1
+ generated/module.function_2
+ ...
-.. seealso:: autosummary_generate.py
+ Note: The file names contain the module:: or currentmodule:: prefixes.
+ .. seealso:: autosummary_generate.py
-autolink role
--------------
-The autolink role functions as ``:obj:`` when the name referred can be
-resolved to a Python object, and otherwise it becomes simple emphasis.
-This can be used as the default role to make links 'smart'.
+ autolink role
+ -------------
+ The autolink role functions as ``:obj:`` when the name referred can be
+ resolved to a Python object, and otherwise it becomes simple emphasis.
+ This can be used as the default role to make links 'smart'.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
"""
-import sys, os, posixpath, re
+
+import os
+import re
+import sys
+import inspect
+import posixpath
from docutils.parsers.rst import directives
from docutils.statemachine import ViewList
from docutils import nodes
-import sphinx.addnodes, sphinx.roles, sphinx.builder
+from sphinx import addnodes, roles
from sphinx.util import patfilter
-import inspect
-
-def setup(app):
- app.add_directive('autosummary', autosummary_directive, True, (0, 0, False),
- toctree=directives.unchanged,
- nosignatures=directives.flag)
- app.add_role('autolink', autolink_role)
-
- app.add_node(autosummary_toc,
- html=(autosummary_toc_visit_html, autosummary_toc_depart_noop),
- latex=(autosummary_toc_visit_latex, autosummary_toc_depart_noop))
- app.connect('doctree-read', process_autosummary_toc)
-#------------------------------------------------------------------------------
-# autosummary_toc node
-#------------------------------------------------------------------------------
+# -- autosummary_toc node ------------------------------------------------------
class autosummary_toc(nodes.comment):
pass
@@ -83,7 +76,6 @@ def process_autosummary_toc(app, doctree):
"""
Insert items described in autosummary:: to the TOC tree, but do
not generate the toctree:: list.
-
"""
env = app.builder.env
crawled = {}
@@ -92,7 +84,7 @@ def process_autosummary_toc(app, doctree):
for j, subnode in enumerate(node):
try:
if (isinstance(subnode, autosummary_toc)
- and isinstance(subnode[0], sphinx.addnodes.toctree)):
+ and isinstance(subnode[0], addnodes.toctree)):
env.note_toctree(env.docname, subnode[0])
continue
except IndexError:
@@ -104,19 +96,18 @@ def process_autosummary_toc(app, doctree):
crawl_toc(doctree)
def autosummary_toc_visit_html(self, node):
- """Hide autosummary toctree list in HTML output"""
+ """Hide autosummary toctree list in HTML output."""
raise nodes.SkipNode
def autosummary_toc_visit_latex(self, node):
- """Show autosummary toctree (= put the referenced pages here) in Latex"""
+ """Show autosummary toctree (= put the referenced pages here) in Latex."""
pass
def autosummary_toc_depart_noop(self, node):
pass
-#------------------------------------------------------------------------------
-# .. autosummary::
-#------------------------------------------------------------------------------
+
+# -- .. autosummary:: ----------------------------------------------------------
def autosummary_directive(dirname, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
@@ -155,7 +146,7 @@ def autosummary_directive(dirname, arguments, options, content, lineno,
line=lineno))
docnames.append(docname)
- tocnode = sphinx.addnodes.toctree()
+ tocnode = addnodes.toctree()
tocnode['includefiles'] = docnames
tocnode['maxdepth'] = -1
tocnode['glob'] = None
@@ -165,6 +156,7 @@ def autosummary_directive(dirname, arguments, options, content, lineno,
else:
return warnings + [node]
+
def get_autosummary(names, state, no_signatures=False):
"""
Generate a proper table node for autosummary:: directive.
@@ -175,10 +167,10 @@ def get_autosummary(names, state, no_signatures=False):
Names of Python objects to be imported and added to the table.
document : document
Docutils document object
-
+
"""
document = state.document
-
+
real_names = {}
warnings = []
@@ -209,14 +201,14 @@ def get_autosummary(names, state, no_signatures=False):
except ImportError:
warnings.append(document.reporter.warning(
'failed to import %s' % name))
- append_row(":obj:`%s`" % name, "")
+ append_row(':obj:`%s`' % name, '')
continue
real_names[name] = real_name
- title = ""
+ title = ''
qualifier = 'obj'
- col1 = ":"+qualifier+":`%s <%s>`" % (name, real_name)
+ col1 = ':'+qualifier+':`%s <%s>`' % (name, real_name)
col2 = title
append_row(col1, col2)
@@ -240,7 +232,7 @@ def import_by_name(name, prefixes=[None]):
The imported object
name
Name of the imported object (useful if `prefixes` was used)
-
+
"""
for prefix in prefixes:
try:
@@ -254,9 +246,18 @@ def import_by_name(name, prefixes=[None]):
raise ImportError
def _import_by_name(name):
- """Import a Python object given its full name"""
+ """Import a Python object given its full name."""
try:
+ # try first interpret `name` as MODNAME.OBJ
name_parts = name.split('.')
+ try:
+ modname = '.'.join(name_parts[:-1])
+ __import__(modname)
+ return getattr(sys.modules[modname], name_parts[-1])
+ except (ImportError, IndexError, AttributeError):
+ pass
+
+ # ... then as MODNAME, MODNAME.OBJ1, MODNAME.OBJ1.OBJ2, ...
last_j = 0
modname = None
for j in reversed(range(1, len(name_parts)+1)):
@@ -279,20 +280,19 @@ def _import_by_name(name):
except (ValueError, ImportError, AttributeError, KeyError), e:
raise ImportError(e)
-#------------------------------------------------------------------------------
-# :autolink: (smart default role)
-#------------------------------------------------------------------------------
+
+# -- :autolink: (smart default role) -------------------------------------------
def autolink_role(typ, rawtext, etext, lineno, inliner,
options={}, content=[]):
"""
Smart linking role.
- Expands to ":obj:`text`" if `text` is an object that can be imported;
- otherwise expands to "*text*".
+ Expands to ':obj:`text`' if `text` is an object that can be imported;
+ otherwise expands to '*text*'.
"""
- r = sphinx.roles.xfileref_role('obj', rawtext, etext, lineno, inliner,
- options, content)
+ r = roles.xfileref_role('obj', rawtext, etext, lineno, inliner,
+ options, content)
pnode = r[0][0]
prefixes = [None]
@@ -304,3 +304,15 @@ def autolink_role(typ, rawtext, etext, lineno, inliner,
r[0][0] = nodes.emphasis(rawtext, content[0].astext(),
classes=content['classes'])
return r
+
+
+def setup(app):
+ app.add_directive('autosummary', autosummary_directive, True, (0, 0, False),
+ toctree=directives.unchanged,
+ nosignatures=directives.flag)
+ app.add_role('autolink', autolink_role)
+
+ app.add_node(autosummary_toc,
+ html=(autosummary_toc_visit_html, autosummary_toc_depart_noop),
+ latex=(autosummary_toc_visit_latex, autosummary_toc_depart_noop))
+ app.connect('doctree-read', process_autosummary_toc)
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index ce9e4c2d8..178a2870a 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -1,85 +1,91 @@
+# -*- coding: utf-8 -*-
"""
-autosummary_generate.py OPTIONS FILES
+ sphinx.ext.autosummary.generate
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Generate automatic RST source files for items referred to in
-autosummary:: directives.
+ Usable as a library or script to generate automatic RST source files for
+ items referred to in autosummary:: directives.
-Each generated RST file contains a single auto*:: directive which
-extracts the docstring of the referred item.
+ Each generated RST file contains a single auto*:: directive which
+ extracts the docstring of the referred item.
-Example Makefile rule::
+ Example Makefile rule::
- generate:
- sphinx-autogen source/*.rst source/generated
+ generate:
+ sphinx-autogen source/*.rst source/generated
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
"""
-import glob, re, inspect, os, optparse
+import os
+import re
+import sys
+import glob
+import inspect
+
+from jinja2 import Environment, PackageLoader
+
from sphinx.ext.autosummary import import_by_name
+from sphinx.util import ensuredir
-from jinja import Environment, PackageLoader
-env = Environment(loader=PackageLoader('sphinx.ext.autosummary', 'templates'))
+# create our own templating environment, for module template only
+env = Environment(loader=PackageLoader('sphinx.ext.autosummary', 'templates'))
-def main():
- p = optparse.OptionParser(__doc__.strip())
- options, args = p.parse_args()
-
- if len(args) <2:
- p.error("wrong number of arguments")
- print 'generating docs from:', args[:-1]
- generate_autosummary_docs(args[:-1], args[-1])
-
-def generate_autosummary_docs(source_dir, output_dir):
+def generate_autosummary_docs(sources, output_dir=None):
# read
names = {}
- for name, loc in get_documented(source_dir).items():
+ for name, loc in get_documented(sources).items():
for (filename, sec_title, keyword, toctree) in loc:
if toctree is not None:
path = os.path.join(os.path.dirname(filename), toctree)
names[name] = os.path.abspath(path)
-
+
# write
for name, path in sorted(names.items()):
- path = output_dir
-
- if not os.path.isdir(path):
- os.makedirs(path)
+ if output_dir is not None:
+ path = output_dir
+
+ ensuredir(path)
try:
obj, name = import_by_name(name)
except ImportError, e:
- print "Failed to import '%s': %s" % (name, e)
+ print >>sys.stderr, 'Failed to import %r: %s' % (name, e)
continue
fn = os.path.join(path, '%s.rst' % name)
-
- if os.path.exists(fn):
- # skip
+ # skip it if it exists
+ if os.path.isfile(fn):
continue
f = open(fn, 'w')
-
try:
-
if inspect.ismodule(obj):
- tmpl = env.get_template('module.html')
- functions = [getattr(obj, item).__name__ for item in dir(obj) if inspect.isfunction(getattr(obj, item))]
- classes = [getattr(obj, item).__name__ for item in dir(obj) if inspect.isclass(getattr(obj, item)) and not issubclass(getattr(obj, item), Exception)]
- exceptions = [getattr(obj, item).__name__ for item in dir(obj) if inspect.isclass(getattr(obj, item)) and issubclass(getattr(obj, item), Exception)]
- rendered = tmpl.render(name=name,
- functions=functions,
- classes=classes,
- exceptions=exceptions,
+ tmpl = env.get_template('module')
+ functions = [getattr(obj, item).__name__
+ for item in dir(obj)
+ if inspect.isfunction(getattr(obj, item))]
+ classes = [getattr(obj, item).__name__
+ for item in dir(obj)
+ if inspect.isclass(getattr(obj, item))
+ and not issubclass(getattr(obj, item), Exception)]
+ exceptions = [getattr(obj, item).__name__
+ for item in dir(obj)
+ if inspect.isclass(getattr(obj, item))
+ and issubclass(getattr(obj, item), Exception)]
+ rendered = tmpl.render(name=name,
+ functions=functions,
+ classes=classes,
+ exceptions=exceptions,
len_functions=len(functions),
len_classes=len(classes),
- len_exceptions=len(exceptions)
-
- )
+ len_exceptions=len(exceptions))
f.write(rendered)
else:
f.write('%s\n%s\n\n' % (name, '='*len(name)))
-
+
if inspect.isclass(obj):
if issubclass(obj, Exception):
f.write(format_modulemember(name, 'autoexception'))
@@ -96,40 +102,40 @@ def generate_autosummary_docs(source_dir, output_dir):
finally:
f.close()
+
def format_modulemember(name, directive):
parts = name.split('.')
mod, name = '.'.join(parts[:-1]), parts[-1]
- return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
+ return '.. currentmodule:: %s\n\n.. %s:: %s\n' % (mod, directive, name)
+
def format_classmember(name, directive):
parts = name.split('.')
mod, name = '.'.join(parts[:-2]), '.'.join(parts[-2:])
- return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
+ return '.. currentmodule:: %s\n\n.. %s:: %s\n' % (mod, directive, name)
+
+
+title_underline_re = re.compile('^[-=*_^#]{3,}\s*$')
+autodoc_re = re.compile(r'.. auto(function|method|attribute|class|exception'
+ '|module)::\s*([A-Za-z0-9_.]+)\s*$')
+autosummary_re = re.compile(r'^\.\.\s+autosummary::\s*')
+module_re = re.compile(r'^\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
+autosummary_item_re = re.compile(r'^\s+([_a-zA-Z][a-zA-Z0-9_.]*)\s*')
+toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
def get_documented(filenames):
"""
- Find out what items are documented in source/*.rst
-
- Returns
- -------
- documented : dict of list of (filename, title, keyword, toctree)
- Dictionary whose keys are documented names of objects.
- The value is a list of locations where the object was documented.
- Each location is a tuple of filename, the current section title,
- the name of the directive, and the value of the :toctree: argument
- (if present) of the directive.
+ Find out what items are documented in the given filenames.
+ Returns a dict of list of (filename, title, keyword, toctree) Keys are
+ documented names of objects. The value is a list of locations where the
+ object was documented. Each location is a tuple of filename, the current
+ section title, the name of the directive, and the value of the :toctree:
+ argument (if present) of the directive.
"""
-
- title_underline_re = re.compile("^[-=*_^#]{3,}\s*$")
- autodoc_re = re.compile(".. auto(function|method|attribute|class|exception|module)::\s*([A-Za-z0-9_.]+)\s*$")
- autosummary_re = re.compile(r'^\.\.\s+autosummary::\s*')
- module_re = re.compile(r'^\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
- autosummary_item_re = re.compile(r'^\s+([_a-zA-Z][a-zA-Z0-9_.]*)\s*')
- toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
-
+
documented = {}
-
+
for filename in filenames:
current_title = []
last_line = None
@@ -150,32 +156,34 @@ def get_documented(filenames):
continue # skip options
m = autosummary_item_re.match(line)
-
+
if m:
name = m.group(1).strip()
- if current_module and not name.startswith(current_module + '.'):
- name = "%s.%s" % (current_module, name)
+ if current_module and \
+ not name.startswith(current_module + '.'):
+ name = '%s.%s' % (current_module, name)
documented.setdefault(name, []).append(
(filename, current_title, 'autosummary', toctree))
continue
if line.strip() == '':
continue
in_autosummary = False
-
+
m = autosummary_re.match(line)
if m:
in_autosummary = True
continue
-
+
m = autodoc_re.search(line)
if m:
name = m.group(2).strip()
- if current_module and not name.startswith(current_module + '.'):
- name = "%s.%s" % (current_module, name)
- if m.group(1) == "module":
+ if current_module and \
+ not name.startswith(current_module + '.'):
+ name = '%s.%s' % (current_module, name)
+ if m.group(1) == 'module':
current_module = name
documented.setdefault(name, []).append(
- (filename, current_title, "auto" + m.group(1), None))
+ (filename, current_title, 'auto' + m.group(1), None))
continue
m = title_underline_re.match(line)
@@ -191,5 +199,17 @@ def get_documented(filenames):
last_line = line
return documented
-if __name__ == "__main__":
+
+def main(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ if len(args) < 2:
+ print >>sys.stderr, 'usage: %s sourcefile ... outputdir' % sys.argv[0]
+
+ print 'generating docs from:', ', '.join(args[:-1])
+ generate_autosummary_docs(args[:-1], args[-1])
+
+
+if __name__ == '__main__':
main()
diff --git a/sphinx/ext/autosummary/templates/module.html b/sphinx/ext/autosummary/templates/module
index 34dd8100a..34dd8100a 100644
--- a/sphinx/ext/autosummary/templates/module.html
+++ b/sphinx/ext/autosummary/templates/module