autosummary.py :  » Math » Numerical-Python » numpy » doc » sphinxext » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Math » Numerical Python 
Numerical Python » numpy » doc » sphinxext » autosummary.py
"""
===========
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.

An :autolink: role is also provided.

autosummary directive
---------------------

The autosummary directive has the form::

    .. autosummary::
       :nosignatures:
       :toctree: generated/
       
       module.function_1
       module.function_2
       ...

and it generates an output table (containing signatures, optionally)

    ========================  =============================================
    module.function_1(args)   Summary line from the docstring of function_1
    module.function_2(args)   Summary line from the docstring
    ...
    ========================  =============================================

If the :toctree: option is specified, files matching the function names
are inserted to the toctree with the given prefix:

    generated/module.function_1
    generated/module.function_2
    ...

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'.

"""
import sys, os, posixpath, re

from docutils.parsers.rst import directives
from docutils.statemachine import ViewList
from docutils import nodes

import sphinx.addnodes, sphinx.roles
from sphinx.util import patfilter

from docscrape_sphinx import get_doc_object

import warnings
warnings.warn(
    "The numpydoc.autosummary extension can also be found as "
    "sphinx.ext.autosummary in Sphinx >= 0.6, and the version in "
    "Sphinx >= 0.7 is superior to the one in numpydoc. This numpydoc "
    "version of autosummary is no longer maintained.",
    DeprecationWarning, stacklevel=2)

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
#------------------------------------------------------------------------------

class autosummary_toc(nodes.comment):
    pass

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 = {}
    def crawl_toc(node, depth=1):
        crawled[node] = True
        for j, subnode in enumerate(node):
            try:
                if (isinstance(subnode, autosummary_toc)
                    and isinstance(subnode[0], sphinx.addnodes.toctree)):
                    env.note_toctree(env.docname, subnode[0])
                    continue
            except IndexError:
                continue
            if not isinstance(subnode, nodes.section):
                continue
            if subnode not in crawled:
                crawl_toc(subnode, depth+1)
    crawl_toc(doctree)

def autosummary_toc_visit_html(self, node):
    """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"""
    pass

def autosummary_toc_depart_noop(self, node):
    pass

#------------------------------------------------------------------------------
# .. autosummary::
#------------------------------------------------------------------------------

def autosummary_directive(dirname, arguments, options, content, lineno,
                          content_offset, block_text, state, state_machine):
    """
    Pretty table containing short signatures and summaries of functions etc.

    autosummary also generates a (hidden) toctree:: node.

    """

    names = []
    names += [x.strip().split()[0] for x in content
              if x.strip() and re.search(r'^[a-zA-Z_]', x.strip()[0])]

    table, warnings, real_names = get_autosummary(names, state,
                                                  'nosignatures' in options)
    node = table

    env = state.document.settings.env
    suffix = env.config.source_suffix
    all_docnames = env.found_docs.copy()
    dirname = posixpath.dirname(env.docname)

    if 'toctree' in options:
        tree_prefix = options['toctree'].strip()
        docnames = []
        for name in names:
            name = real_names.get(name, name)

            docname = tree_prefix + name
            if docname.endswith(suffix):
                docname = docname[:-len(suffix)]
            docname = posixpath.normpath(posixpath.join(dirname, docname))
            if docname not in env.found_docs:
                warnings.append(state.document.reporter.warning(
                    'toctree references unknown document %r' % docname,
                    line=lineno))
            docnames.append(docname)

        tocnode = sphinx.addnodes.toctree()
        tocnode['includefiles'] = docnames
        tocnode['maxdepth'] = -1
        tocnode['glob'] = None
        tocnode['entries'] = [(None, docname) for docname in docnames]

        tocnode = autosummary_toc('', '', tocnode)
        return warnings + [node] + [tocnode]
    else:
        return warnings + [node]

def get_autosummary(names, state, no_signatures=False):
    """
    Generate a proper table node for autosummary:: directive.

    Parameters
    ----------
    names : list of str
        Names of Python objects to be imported and added to the table.
    document : document
        Docutils document object
    
    """
    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=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>')
            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 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

        doc = get_doc_object(obj)

        if doc['Summary']:
            title = " ".join(doc['Summary'])
        else:
            title = ""
        
        col1 = u":obj:`%s <%s>`" % (name, real_name)
        if doc['Signature']:
            sig = re.sub('^[^(\[]*', '', doc['Signature'].strip())
            if '=' in sig:
                # abbreviate optional arguments
                sig = re.sub(r', ([a-zA-Z0-9_]+)=', r'[, \1=', sig, count=1)
                sig = re.sub(r'\(([a-zA-Z0-9_]+)=', r'([\1=', sig, count=1)
                sig = re.sub(r'=[^,)]+,', ',', sig)
                sig = re.sub(r'=[^,)]+\)$', '])', sig)
                # shorten long strings
                sig = re.sub(r'(\[.{16,16}[^,]*?),.*?\]\)', r'\1, ...])', sig)
            else:
                sig = re.sub(r'(\(.{16,16}[^,]*?),.*?\)', r'\1, ...)', sig)
            # make signature contain non-breaking spaces
            col1 += u"\\ \u00a0" + unicode(sig).replace(u" ", u"\u00a0")
        col2 = title
        append_row(col1, col2)

    return table, warnings, real_names

def import_by_name(name, prefixes=[None]):
    """
    Import a Python object that has the given name, under one of the prefixes.

    Parameters
    ----------
    name : str
        Name of a Python object, eg. 'numpy.ndarray.view'
    prefixes : list of (str or None), optional
        Prefixes to prepend to the name (None implies no prefix).
        The first prefixed name that results to successful import is used.

    Returns
    -------
    obj
        The imported object
    name
        Name of the imported object (useful if `prefixes` was used)
    
    """
    for prefix in prefixes:
        try:
            if prefix:
                prefixed_name = '.'.join([prefix, name])
            else:
                prefixed_name = name
            return _import_by_name(prefixed_name), prefixed_name
        except ImportError:
            pass
    raise ImportError

def _import_by_name(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)):
            last_j = j
            modname = '.'.join(name_parts[:j])
            try:
                __import__(modname)
            except ImportError:
                continue
            if modname in sys.modules:
                break

        if last_j < len(name_parts):
            obj = sys.modules[modname]
            for obj_name in name_parts[last_j:]:
                obj = getattr(obj, obj_name)
            return obj
        else:
            return sys.modules[modname]
    except (ValueError, ImportError, AttributeError, KeyError), e:
        raise ImportError(e)

#------------------------------------------------------------------------------
# :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*".
    """
    r = sphinx.roles.xfileref_role('obj', rawtext, etext, lineno, inliner,
                                   options, content)
    pnode = r[0][0]

    prefixes = [None]
    #prefixes.insert(0, inliner.document.settings.env.currmodule)
    try:
        obj, name = import_by_name(pnode['reftarget'], prefixes)
    except ImportError:
        content = pnode[0]
        r[0][0] = nodes.emphasis(rawtext, content[0].astext(),
                                 classes=content['classes'])
    return r
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.