merge with pv/sphinx-work

This commit is contained in:
Georg Brandl 2009-04-13 09:45:56 +02:00
commit b13f61bc42
7 changed files with 464 additions and 198 deletions

View File

@ -6,7 +6,8 @@ import sys, os, re
# Add any Sphinx extension module names here, as strings. They can be extensions # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.addons.*') or your custom ones. # coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
'sphinx.ext.autosummary']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@ -6,4 +6,103 @@
.. module:: sphinx.ext.autosummary .. module:: sphinx.ext.autosummary
:synopsis: Generate autodoc summaries :synopsis: Generate autodoc summaries
TBW. .. versionadded: 0.6
This extension generates function/method/attribute summary lists,
similar to those output eg. by Epydoc and other API doc generation
tools. This is especially useful when your docstrings are long and
detailed, and putting each one of them on a separate page makes
them easier to read.
The :mod:`sphinx.ext.autosummary` extension does this in two parts:
1. There is an :dir:`autosummary` directive for generating summary
listings that contain links to the documented items, and short
summary blurbs extracted from their docstrings.
2. The convenience script :program:`sphinx-autogen` can be used to
generate short "stub" files for the entries listed in the
:dir:`autosummary` directives. These by default contain only the
corresponding :mod:`sphinx.ext.autodoc` directive.
.. directive:: autosummary
Insert a table that contains links to documented items, and a short
summary blurb (the first sentence of the docstring) for each of them.
The :dir:`autosummary` directive can also optionally serve as
a :dir:`toctree` entry for the included items.
For example,::
.. currentmodule:: sphinx
.. autosummary::
environment.BuildEnvironment
util.relative_uri
produces a table like this:
.. currentmodule:: sphinx
.. autosummary::
environment.BuildEnvironment
util.relative_uri
.. currentmodule:: sphinx.ext.autosummary
Autosummary preprocesses the docstrings and signatures with the same
:event:`autodoc-process-docstring` and
:event:`autodoc-process-signature` hooks as *autodoc*.
**Options**
* If you want the :dir:`autosummary` table to also serve as a
:dir:`toctree` entry, use the ``toctree`` option, for example::
.. autosummary::
:toctree: DIRNAME
sphinx.environment.BuildEnvironment
sphinx.util.relative_uri
The ``toctree`` option also signals to the :program:`sphinx-autogen`
script that stub pages should be generated for the entries listed
in this directive. The option accepts a directory name as an
argument; :program:`sphinx-autogen` will by default place its output
in this directory.
* If you don't want the :dir:`autosummary` to show function signatures
in the listing, include the ``nosignatures`` option::
.. autosummary::
:nosignatures:
sphinx.environment.BuildEnvironment
sphinx.util.relative_uri
:program:`sphinx-autogen` -- generate autodoc stub pages
--------------------------------------------------------
The :program:`sphinx-autogen` script can be used to conveniently
generate stub documentation pages for items included in
:dir:`autosummary` listings.
For example, the command::
$ sphinx-autogen -o generated *.rst
will read all :dir:`autosummary` tables in the :file:`*.rst` files
that have the ``:toctree:`` option set, and output corresponding stub
pages in directory ``generated`` for all documented items.
The generated pages by default contain text of the form::
sphinx.util.relative_uri
========================
.. autofunction:: sphinx.util.relative_uri
If the ``-o`` option is not given, the script will place the output
files to the directories specified in the ``:toctree:`` options.

View File

@ -372,8 +372,7 @@ class Documenter(object):
else: else:
# try to introspect the signature # try to introspect the signature
args = self.format_args() args = self.format_args()
if args is None:
return ''
retann = self.retann retann = self.retann
result = self.env.app.emit_firstresult( result = self.env.app.emit_firstresult(

View File

@ -108,6 +108,29 @@ def autosummary_toc_visit_latex(self, node):
def autosummary_noop(self, node): def autosummary_noop(self, node):
pass pass
# -- autodoc integration -------------------------------------------------------
def get_documenter(obj):
"""
Get an autodoc.Documenter class suitable for documenting the given object
"""
import sphinx.ext.autodoc as autodoc
if inspect.isclass(obj):
if issubclass(obj, Exception):
return autodoc.ExceptionDocumenter
return autodoc.ClassDocumenter
elif inspect.ismodule(obj):
return autodoc.ModuleDocumenter
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
return autodoc.MethodDocumenter
elif (inspect.ismemberdescriptor(obj) or inspect.isgetsetdescriptor(obj)
or inspect.isdatadescriptor(obj)):
return autodoc.AttributeDocumenter
elif inspect.isroutine(obj):
return autodoc.FunctionDocumenter
else:
return autodoc.DataDocumenter
# -- .. autosummary:: ---------------------------------------------------------- # -- .. autosummary:: ----------------------------------------------------------
@ -127,33 +150,35 @@ class Autosummary(Directive):
'nosignatures': directives.flag, 'nosignatures': directives.flag,
} }
def warn(self, msg):
self.warnings.append(self.state.document.reporter.warning(
msg, line=self.lineno))
def run(self): def run(self):
names = [] self.env = env = self.state.document.settings.env
names += [x.strip() for x in self.content if x.strip()] self.genopt = {}
self.warnings = []
table, warnings, real_names = get_autosummary( names = [x.strip().split()[0] for x in self.content
names, self.state, 'nosignatures' in self.options) if x.strip() and re.search(r'^[a-zA-Z_]', x.strip()[0])]
node = table items = self.get_items(names)
nodes = [self.get_table(items)]
env = self.state.document.settings.env
suffix = env.config.source_suffix
all_docnames = env.found_docs.copy()
dirname = posixpath.dirname(env.docname)
if 'toctree' in self.options: if 'toctree' in self.options:
suffix = env.config.source_suffix
all_docnames = env.found_docs.copy()
dirname = posixpath.dirname(env.docname)
tree_prefix = self.options['toctree'].strip() tree_prefix = self.options['toctree'].strip()
docnames = [] docnames = []
for name in names: for name, sig, summary, real_name in items:
name = real_names.get(name, name) docname = posixpath.join(tree_prefix, real_name)
docname = posixpath.join(tree_prefix, name)
if docname.endswith(suffix): if docname.endswith(suffix):
docname = docname[:-len(suffix)] docname = docname[:-len(suffix)]
docname = posixpath.normpath(posixpath.join(dirname, docname)) docname = posixpath.normpath(posixpath.join(dirname, docname))
if docname not in env.found_docs: if docname not in env.found_docs:
warnings.append(self.state.document.reporter.warning( self.warn('toctree references unknown document %r'
'toctree references unknown document %r' % docname, % docname)
line=self.lineno))
docnames.append(docname) docnames.append(docname)
tocnode = addnodes.toctree() tocnode = addnodes.toctree()
@ -163,63 +188,146 @@ class Autosummary(Directive):
tocnode['glob'] = None tocnode['glob'] = None
tocnode = autosummary_toc('', '', tocnode) tocnode = autosummary_toc('', '', tocnode)
return warnings + [node] + [tocnode] nodes.append(tocnode)
return self.warnings + nodes
def get_items(self, names):
"""
Try to import the given names, and return a list of
``[(name, signature, summary_string, real_name), ...]``
"""
prefixes = ['']
prefixes.insert(0, self.state.document.settings.env.currmodule)
items = []
for name in names:
try:
obj, real_name = import_by_name(name, prefixes=prefixes)
except ImportError:
self.warn('failed to import %s' % name)
items.append((name, '', '', name))
continue
# NB. using real_name here is important, since Documenters
# don't handle module prefixes slightly differently
documenter = get_documenter(obj)(self, real_name)
if not documenter.parse_name():
self.warn('failed to parse name %s' % real_name)
items.append((name, '', '', real_name))
continue
if not documenter.import_object():
self.warn('failed to import object %s' % real_name)
items.append((name, '', '', real_name))
continue
# -- Grab the signature
sig = documenter.format_signature()
if not sig:
sig = ''
else:
sig = mangle_signature(sig).replace('*', r'\*')
# -- Grab the summary
doc = list(documenter.process_doc(documenter.get_doc()))
while doc and not doc[0].strip():
doc.pop(0)
m = re.search(r"^([A-Z][^A-Z]*?\.\s)", " ".join(doc).strip())
if m:
summary = m.group(1).strip()
elif doc:
summary = doc[0].strip()
else:
summary = ''
items.append((name, sig, summary, real_name))
return items
def get_table(self, items):
"""
Generate a proper table node for autosummary:: directive.
*items* is a list produced by :meth:`get_items`
"""
table = nodes.table('')
group = nodes.tgroup('', cols=2)
table.append(group)
group.append(nodes.colspec('', colwidth=10))
group.append(nodes.colspec('', colwidth=90))
body = nodes.tbody('')
group.append(body)
def append_row(*column_texts):
row = nodes.row('')
for text in column_texts:
node = nodes.paragraph('')
vl = ViewList()
vl.append(text, '<autosummary>')
self.state.nested_parse(vl, 0, node)
try:
if isinstance(node[0], nodes.paragraph):
node = node[0]
except IndexError:
pass
row.append(nodes.entry('', node))
body.append(row)
for name, sig, summary, real_name in items:
qualifier = 'obj'
if 'nosignatures' not in self.options:
col1 = ':%s:`%s <%s>`\ %s' % (qualifier, name, real_name, sig)
else:
col1 = ':%s:`%s <%s>`' % (qualifier, name, real_name)
col2 = summary
append_row(col1, col2)
return table
def mangle_signature(sig, max_chars=30):
"""
Reformat function signature to a more compact form.
"""
sig = re.sub(r"^\((.*)\)$", r"\1", sig) + ", "
r = re.compile(r"(?P<name>[a-zA_Z0-9_*]+)(?P<default>=.*?)?, ")
items = r.findall(sig)
args = []
opts = []
total_len = 4
for name, default in items:
if default:
opts.append(name)
else: else:
return warnings + [node] args.append(name)
total_len += len(name) + 2
if total_len > max_chars:
if opts:
opts.append('...')
else:
args.append('...')
break
def get_autosummary(names, state, no_signatures=False): if opts and args:
""" sig = ", ".join(args) + "[, " + ", ".join(opts) + "]"
Generate a proper table node for autosummary:: directive. elif opts and not args:
sig = "[" + ", ".join(opts) + "]"
else:
sig = ", ".join(args)
*names* is a list of names of Python objects to be imported and added to the sig = unicode(sig).replace(u" ", u"\u00a0")
table. *document* is the Docutils document object. return u"(%s)" % sig
""" # -- Importing items -----------------------------------------------------------
document = state.document
real_names = {}
warnings = []
prefixes = ['']
prefixes.insert(0, document.settings.env.currmodule)
table = nodes.table('')
group = nodes.tgroup('', cols=2)
table.append(group)
group.append(nodes.colspec('', colwidth=30))
group.append(nodes.colspec('', colwidth=70))
body = nodes.tbody('')
group.append(body)
def append_row(*column_texts):
row = nodes.row('')
for text in column_texts:
node = nodes.paragraph('')
vl = ViewList()
vl.append(text, '<autosummary>')
state.nested_parse(vl, 0, node)
row.append(nodes.entry('', node))
body.append(row)
for name in names:
try:
obj, real_name = import_by_name(name, prefixes=prefixes)
except ImportError:
warnings.append(document.reporter.warning(
'failed to import %s' % name))
append_row(':obj:`%s`' % name, '')
continue
real_names[name] = real_name
title = ''
qualifier = 'obj'
col1 = ':'+qualifier+':`%s <%s>`' % (name, real_name)
col2 = title
append_row(col1, col2)
return table, warnings, real_names
def import_by_name(name, prefixes=[None]): def import_by_name(name, prefixes=[None]):
""" """

View File

@ -20,16 +20,31 @@
import os import os
import re import re
import sys import sys
import getopt import optparse
import inspect import inspect
import pydoc
from jinja2 import Environment, PackageLoader from jinja2 import Environment, PackageLoader
from sphinx.ext.autosummary import import_by_name from sphinx.ext.autosummary import import_by_name, get_documenter
from sphinx.util import ensuredir from sphinx.util import ensuredir
# create our own templating environment, for module template only def main(argv):
env = Environment(loader=PackageLoader('sphinx.ext.autosummary', 'templates')) usage = """%prog [OPTIONS] SOURCEFILE ..."""
p = optparse.OptionParser(usage.strip())
p.add_option("-o", "--output-dir", action="store", type="string",
dest="output_dir", default=None,
help="Directory to place all output in")
p.add_option("-s", "--suffix", action="store", type="string",
dest="suffix", default="rst",
help="Default suffix for files (default: %default)")
options, args = p.parse_args(argv[1:])
if len(args) < 1:
p.error('no input files given')
generate_autosummary_docs(args, options.output_dir,
"." + options.suffix)
def _simple_info(msg): def _simple_info(msg):
@ -38,14 +53,22 @@ def _simple_info(msg):
def _simple_warn(msg): def _simple_warn(msg):
print >>sys.stderr, 'WARNING: ' + msg print >>sys.stderr, 'WARNING: ' + msg
def generate_autosummary_docs(sources, output_dir=None, suffix=None, #------------------------------------------------------------------------------
# Generating output
#------------------------------------------------------------------------------
# create our own templating environment, for module template only
env = Environment(loader=PackageLoader('sphinx.ext.autosummary', 'templates'))
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
warn=_simple_warn, info=_simple_info): warn=_simple_warn, info=_simple_info):
info('generating autosummary for: %s' % ', '.join(sources)) info('generating autosummary for: %s' % ', '.join(sources))
if output_dir: if output_dir:
info('writing to %s' % output_dir) info('writing to %s' % output_dir)
# read # read
names = {} names = {}
for name, loc in get_documented(sources).items(): for name, loc in get_documented_in_files(sources).items():
for (filename, sec_title, keyword, toctree) in loc: for (filename, sec_title, keyword, toctree) in loc:
if toctree is not None: if toctree is not None:
path = os.path.join(os.path.dirname(filename), toctree) path = os.path.join(os.path.dirname(filename), toctree)
@ -62,7 +85,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix=None,
warn('failed to import %r: %s' % (name, e)) warn('failed to import %r: %s' % (name, e))
continue continue
fn = os.path.join(path, name + (suffix or '.rst')) fn = os.path.join(path, name + suffix)
# skip it if it exists # skip it if it exists
if os.path.isfile(fn): if os.path.isfile(fn):
continue continue
@ -73,17 +96,16 @@ def generate_autosummary_docs(sources, output_dir=None, suffix=None,
if inspect.ismodule(obj): if inspect.ismodule(obj):
# XXX replace this with autodoc's API? # XXX replace this with autodoc's API?
tmpl = env.get_template('module') tmpl = env.get_template('module')
functions = [getattr(obj, item).__name__
for item in dir(obj) def get_items(mod, typ):
if inspect.isfunction(getattr(obj, item))] return [getattr(mod, name).__name__
classes = [getattr(obj, item).__name__ for name in dir(mod)
for item in dir(obj) if get_documenter(getattr(mod,name)).objtype==typ]
if inspect.isclass(getattr(obj, item))
and not issubclass(getattr(obj, item), Exception)] functions = get_items(obj, 'function')
exceptions = [getattr(obj, item).__name__ classes = get_items(obj, 'class')
for item in dir(obj) exceptions = get_items(obj, 'exception')
if inspect.isclass(getattr(obj, item))
and issubclass(getattr(obj, item), Exception)]
rendered = tmpl.render(name=name, rendered = tmpl.render(name=name,
underline='='*len(name), underline='='*len(name),
functions=functions, functions=functions,
@ -96,19 +118,11 @@ def generate_autosummary_docs(sources, output_dir=None, suffix=None,
else: else:
f.write('%s\n%s\n\n' % (name, '='*len(name))) f.write('%s\n%s\n\n' % (name, '='*len(name)))
if inspect.isclass(obj): doc = get_documenter(obj)
if issubclass(obj, Exception): if doc.objtype in ('method', 'attribute'):
f.write(format_modulemember(name, 'autoexception')) f.write(format_classmember(name, 'auto%s' % doc.objtype))
else:
f.write(format_modulemember(name, 'autoclass'))
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
f.write(format_classmember(name, 'automethod'))
elif callable(obj):
f.write(format_modulemember(name, 'autofunction'))
elif hasattr(obj, '__get__'):
f.write(format_classmember(name, 'autoattribute'))
else: else:
f.write(format_modulemember(name, 'autofunction')) f.write(format_modulemember(name, 'auto%s' % doc.objtype))
finally: finally:
f.close() f.close()
@ -125,114 +139,125 @@ def format_classmember(name, directive):
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' # Finding documented entries in files
'|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): def get_documented_in_files(filenames):
""" """
Find out what items are documented in the given filenames. Find out what items are documented in source/*.rst
See `get_documented_in_lines`.
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.
""" """
documented = {} documented = {}
for filename in filenames: for filename in filenames:
current_title = []
last_line = None
toctree = None
current_module = None
in_autosummary = False
f = open(filename, 'r') f = open(filename, 'r')
for line in f: lines = f.read().splitlines()
try: documented.update(get_documented_in_lines(lines, filename=filename))
if in_autosummary: f.close()
m = toctree_arg_re.match(line)
if m:
toctree = m.group(1)
continue
if line.strip().startswith(':'):
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)
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()
# XXX look in newer generate.py
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))
continue
m = title_underline_re.match(line)
if m and last_line:
current_title = last_line.strip()
continue
m = module_re.match(line)
if m:
current_module = m.group(2)
continue
finally:
last_line = line
return documented return documented
def get_documented_in_docstring(name, module=None, filename=None):
def main(argv): """
usage = 'usage: %s [-o output_dir] [-s suffix] sourcefile ...' % sys.argv[0] Find out what items are documented in the given object's docstring.
See `get_documented_in_lines`.
"""
try: try:
opts, args = getopt.getopt(argv[1:], 'o:s:') obj, real_name = import_by_name(name)
except getopt.error: lines = pydoc.getdoc(obj).splitlines()
print >>sys.stderr, usage return get_documented_in_lines(lines, module=name, filename=filename)
return 1 except AttributeError:
pass
except ImportError, e:
print "Failed to import '%s': %s" % (name, e)
return {}
output_dir = None def get_documented_in_lines(lines, module=None, filename=None):
suffix = None """
for opt, val in opts: Find out what items are documented in the given lines
if opt == '-o':
output_dir = val Returns
elif opt == '-s': -------
suffix = val 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.
if len(args) < 1: """
print >>sys.stderr, usage title_underline_re = re.compile("^[-=*_^#]{3,}\s*$")
return 1 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 = {}
current_title = []
last_line = None
toctree = None
current_module = module
in_autosummary = False
for line in lines:
try:
if in_autosummary:
m = toctree_arg_re.match(line)
if m:
toctree = m.group(1)
continue
generate_autosummary_docs(args, output_dir, suffix) if line.strip().startswith(':'):
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)
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 m.group(1) == "module":
current_module = name
documented.update(get_documented_in_docstring(
name, filename=filename))
elif current_module and not name.startswith(current_module+'.'):
name = "%s.%s" % (current_module, name)
documented.setdefault(name, []).append(
(filename, current_title, "auto" + m.group(1), None))
continue
m = title_underline_re.match(line)
if m and last_line:
current_title = last_line.strip()
continue
m = module_re.match(line)
if m:
current_module = m.group(2)
continue
finally:
last_line = line
return documented
#------------------------------------------------------------------------------
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv) main()

View File

@ -30,6 +30,7 @@ from sphinx.util.smartypants import educateQuotesLatex
HEADER = r'''%% Generated by Sphinx. HEADER = r'''%% Generated by Sphinx.
\documentclass[%(papersize)s,%(pointsize)s%(classoptions)s]{%(docclass)s} \documentclass[%(papersize)s,%(pointsize)s%(classoptions)s]{%(docclass)s}
%(inputenc)s %(inputenc)s
%(utf8extra)s
%(fontenc)s %(fontenc)s
%(babel)s %(babel)s
%(fontpkg)s %(fontpkg)s
@ -136,6 +137,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
'pointsize': '10pt', 'pointsize': '10pt',
'classoptions': '', 'classoptions': '',
'inputenc': '\\usepackage[utf8]{inputenc}', 'inputenc': '\\usepackage[utf8]{inputenc}',
'utf8extra': '\\DeclareUnicodeCharacter{00A0}{\\nobreakspace}',
'fontenc': '\\usepackage[T1]{fontenc}', 'fontenc': '\\usepackage[T1]{fontenc}',
'babel': '\\usepackage{babel}', 'babel': '\\usepackage{babel}',
'fontpkg': '\\usepackage{times}', 'fontpkg': '\\usepackage{times}',

32
tests/test_autosummary.py Normal file
View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
"""
test_autosummary
~~~~~~~~~~~~~~~~
Test the autosummary extension.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import string
from util import *
from sphinx.ext.autosummary import mangle_signature
def test_mangle_signature():
TEST = """
() :: ()
(a, b, c, d, e) :: (a, b, c, d, e)
(a, b, c=1, d=2, e=3) :: (a, b[, c, d, e])
(a, b, aaa=1, bbb=1, ccc=1, eee=1, fff=1, ggg=1, hhh=1, iii=1, jjj=1) :: (a, b[, aaa, bbb, ccc, eee, fff, ...])
(a, b, c=(), d=<foo>) :: (a, b[, c, d])
(a, b, c='foobar()', d=123) :: (a, b[, c, d])
"""
TEST = [map(string.strip, x.split("::")) for x in TEST.split("\n")
if '::' in x]
for inp, outp in TEST:
res = mangle_signature(inp).strip().replace(u"\u00a0", " ")
assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))