diff options
Diffstat (limited to 'doc/sphinxext')
-rw-r--r-- | doc/sphinxext/README.txt | 2 | ||||
-rw-r--r-- | doc/sphinxext/docscrape.py | 29 | ||||
-rw-r--r-- | doc/sphinxext/numpydoc.py | 116 |
3 files changed, 57 insertions, 90 deletions
diff --git a/doc/sphinxext/README.txt b/doc/sphinxext/README.txt index 455a709fb..f3d782c95 100644 --- a/doc/sphinxext/README.txt +++ b/doc/sphinxext/README.txt @@ -9,7 +9,7 @@ of them in third-party projects. The following extensions are available: - ``numpydoc``: support for the Numpy docstring format in Sphinx, and add - the code description directives ``np-function``, ``np-cfunction``, etc. + the code description directives ``np:function``, ``np-c:function``, etc. that support the Numpy docstring syntax. - ``numpydoc.traitsdoc``: For gathering documentation about Traits attributes. diff --git a/doc/sphinxext/docscrape.py b/doc/sphinxext/docscrape.py index f36f7ceb7..ad5998cc6 100644 --- a/doc/sphinxext/docscrape.py +++ b/doc/sphinxext/docscrape.py @@ -411,19 +411,14 @@ class FunctionDoc(NumpyDocString): def __init__(self, func, role='func', doc=None, config={}): self._f = func self._role = role # e.g. "func" or "meth" + if doc is None: + if func is None: + raise ValueError("No function or docstring given") doc = inspect.getdoc(func) or '' - try: - NumpyDocString.__init__(self, doc) - except ValueError, e: - print '*'*78 - print "ERROR: '%s' while parsing `%s`" % (e, self._f) - print '*'*78 - #print "Docstring follows:" - #print doclines - #print '='*78 - - if not self['Signature']: + NumpyDocString.__init__(self, doc) + + if not self['Signature'] and func is not None: func, func_name = self.get_func() try: # try to read signature @@ -465,17 +460,17 @@ class FunctionDoc(NumpyDocString): class ClassDoc(NumpyDocString): def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, config={}): - if not inspect.isclass(cls): - raise ValueError("Initialise using a class. Got %r" % cls) + if not inspect.isclass(cls) and cls is not None: + raise ValueError("Expected a class or None, but got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename - self._name = cls.__name__ - self._func_doc = func_doc if doc is None: + if cls is None: + raise ValueError("No class or documentation string given") doc = pydoc.getdoc(cls) NumpyDocString.__init__(self, doc) @@ -490,10 +485,14 @@ class ClassDoc(NumpyDocString): @property def methods(self): + if self._cls is None: + return [] return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and callable(func)] @property def properties(self): + if self._cls is None: + return [] return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and func is None] diff --git a/doc/sphinxext/numpydoc.py b/doc/sphinxext/numpydoc.py index 5eb8c439c..aa390056b 100644 --- a/doc/sphinxext/numpydoc.py +++ b/doc/sphinxext/numpydoc.py @@ -85,74 +85,63 @@ def mangle_signature(app, what, name, obj, options, sig, retann): sig = re.sub(u"^[^(]*", u"", doc['Signature']) return sig, u'' -def initialize(app): - try: - app.connect('autodoc-process-signature', mangle_signature) - except: - monkeypatch_sphinx_ext_autodoc() - def setup(app, get_doc_object_=get_doc_object): global get_doc_object get_doc_object = get_doc_object_ app.connect('autodoc-process-docstring', mangle_docstrings) - app.connect('builder-inited', initialize) + app.connect('autodoc-process-signature', mangle_signature) app.add_config_value('numpydoc_edit_link', None, False) app.add_config_value('numpydoc_use_plots', None, False) app.add_config_value('numpydoc_show_class_members', True, True) - # Extra mangling directives - name_type = { - 'cfunction': 'function', - 'cmember': 'attribute', - 'cmacro': 'function', - 'ctype': 'class', - 'cvar': 'object', - 'class': 'class', - 'function': 'function', - 'attribute': 'attribute', - 'method': 'function', - 'staticmethod': 'function', - 'classmethod': 'function', - } - - for name, objtype in name_type.items(): - app.add_directive('np-' + name, wrap_mangling_directive(name, objtype)) + # Extra mangling domains + app.add_domain(NumpyPythonDomain) + app.add_domain(NumpyCDomain) #------------------------------------------------------------------------------ -# Input-mangling directives +# Docstring-mangling domains #------------------------------------------------------------------------------ + from docutils.statemachine import ViewList +from sphinx.domains.c import CDomain +from sphinx.domains.python import PythonDomain + +class ManglingDomainBase(object): + directive_mangling_map = {} + + def __init__(self, *a, **kw): + super(ManglingDomainBase, self).__init__(*a, **kw) + self.wrap_mangling_directives() + + def wrap_mangling_directives(self): + for name, objtype in self.directive_mangling_map.items(): + self.directives[name] = wrap_mangling_directive( + self.directives[name], objtype) + +class NumpyPythonDomain(ManglingDomainBase, PythonDomain): + name = 'np' + directive_mangling_map = { + 'function': 'function', + 'class': 'class', + 'exception': 'class', + 'method': 'function', + 'classmethod': 'function', + 'staticmethod': 'function', + 'attribute': 'attribute', + } -def get_directive(name): - from docutils.parsers.rst import directives - try: - return directives.directive(name, None, None)[0] - except AttributeError: - pass - try: - # docutils 0.4 - return directives._directives[name] - except (AttributeError, KeyError): - raise RuntimeError("No directive named '%s' found" % name) - -def wrap_mangling_directive(base_directive_name, objtype): - base_directive = get_directive(base_directive_name) - - if inspect.isfunction(base_directive): - base_func = base_directive - class base_directive(Directive): - required_arguments = base_func.arguments[0] - optional_arguments = base_func.arguments[1] - final_argument_whitespace = base_func.arguments[2] - option_spec = base_func.options - has_content = base_func.content - def run(self): - return base_func(self.name, self.arguments, self.options, - self.content, self.lineno, - self.content_offset, self.block_text, - self.state, self.state_machine) +class NumpyCDomain(ManglingDomainBase, CDomain): + name = 'np-c' + directive_mangling_map = { + 'function': 'function', + 'member': 'attribute', + 'macro': 'function', + 'type': 'class', + 'var': 'object', + } +def wrap_mangling_directive(base_directive, objtype): class directive(base_directive): def run(self): env = self.state.document.settings.env @@ -173,24 +162,3 @@ def wrap_mangling_directive(base_directive_name, objtype): return directive -#------------------------------------------------------------------------------ -# Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5) -#------------------------------------------------------------------------------ - -def monkeypatch_sphinx_ext_autodoc(): - global _original_format_signature - import sphinx.ext.autodoc - - if sphinx.ext.autodoc.format_signature is our_format_signature: - return - - print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..." - _original_format_signature = sphinx.ext.autodoc.format_signature - sphinx.ext.autodoc.format_signature = our_format_signature - -def our_format_signature(what, obj): - r = mangle_signature(None, what, None, obj, None, None, None) - if r is not None: - return r[0] - else: - return _original_format_signature(what, obj) |