mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-05 13:21:12 +08:00
Update the numpy sphinx extensions from http://projects.scipy.org/numpy/browser/trunk/doc/sphinxext/
This commit is contained in:
+31
-30
@@ -84,7 +84,7 @@ class Reader(object):
|
||||
|
||||
|
||||
class NumpyDocString(object):
|
||||
def __init__(self,docstring):
|
||||
def __init__(self, docstring, config={}):
|
||||
docstring = textwrap.dedent(docstring).split('\n')
|
||||
|
||||
self._doc = Reader(docstring)
|
||||
@@ -183,7 +183,7 @@ class NumpyDocString(object):
|
||||
|
||||
return params
|
||||
|
||||
|
||||
|
||||
_name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
|
||||
r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
|
||||
def _parse_see_also(self, content):
|
||||
@@ -216,7 +216,7 @@ class NumpyDocString(object):
|
||||
|
||||
current_func = None
|
||||
rest = []
|
||||
|
||||
|
||||
for line in content:
|
||||
if not line.strip(): continue
|
||||
|
||||
@@ -258,7 +258,7 @@ class NumpyDocString(object):
|
||||
if len(line) > 2:
|
||||
out[line[1]] = strip_each_in(line[2].split(','))
|
||||
return out
|
||||
|
||||
|
||||
def _parse_summary(self):
|
||||
"""Grab signature (if given) and summary"""
|
||||
if self._is_at_section():
|
||||
@@ -275,7 +275,7 @@ class NumpyDocString(object):
|
||||
|
||||
if not self._is_at_section():
|
||||
self['Extended Summary'] = self._read_to_next_section()
|
||||
|
||||
|
||||
def _parse(self):
|
||||
self._doc.reset()
|
||||
self._parse_summary()
|
||||
@@ -408,22 +408,17 @@ def header(text, style='-'):
|
||||
|
||||
|
||||
class FunctionDoc(NumpyDocString):
|
||||
def __init__(self, func, role='func', doc=None):
|
||||
def __init__(self, func, role='func', doc=None, config={}):
|
||||
self._f = func
|
||||
self._role = role # e.g. "func" or "meth"
|
||||
if doc is None:
|
||||
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']:
|
||||
if doc is None:
|
||||
if func is None:
|
||||
raise ValueError("No function or docstring given")
|
||||
doc = inspect.getdoc(func) or ''
|
||||
NumpyDocString.__init__(self, doc)
|
||||
|
||||
if not self['Signature'] and func is not None:
|
||||
func, func_name = self.get_func()
|
||||
try:
|
||||
# try to read signature
|
||||
@@ -442,7 +437,7 @@ class FunctionDoc(NumpyDocString):
|
||||
else:
|
||||
func = self._f
|
||||
return func, func_name
|
||||
|
||||
|
||||
def __str__(self):
|
||||
out = ''
|
||||
|
||||
@@ -463,35 +458,41 @@ class FunctionDoc(NumpyDocString):
|
||||
|
||||
|
||||
class ClassDoc(NumpyDocString):
|
||||
def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
|
||||
if not inspect.isclass(cls):
|
||||
raise ValueError("Initialise using a class. Got %r" % cls)
|
||||
def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc,
|
||||
config={}):
|
||||
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)
|
||||
|
||||
if not self['Methods']:
|
||||
self['Methods'] = [(name, '', '') for name in sorted(self.methods)]
|
||||
|
||||
if not self['Attributes']:
|
||||
self['Attributes'] = [(name, '', '')
|
||||
for name in sorted(self.properties)]
|
||||
if config.get('show_class_members', True):
|
||||
if not self['Methods']:
|
||||
self['Methods'] = [(name, '', '')
|
||||
for name in sorted(self.methods)]
|
||||
if not self['Attributes']:
|
||||
self['Attributes'] = [(name, '', '')
|
||||
for name in sorted(self.properties)]
|
||||
|
||||
@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]
|
||||
|
||||
@@ -3,7 +3,9 @@ import sphinx
|
||||
from docscrape import NumpyDocString, FunctionDoc, ClassDoc
|
||||
|
||||
class SphinxDocString(NumpyDocString):
|
||||
use_plots = False
|
||||
def __init__(self, docstring, config={}):
|
||||
self.use_plots = config.get('use_plots', False)
|
||||
NumpyDocString.__init__(self, docstring, config=config)
|
||||
|
||||
# string conversion routines
|
||||
def _str_header(self, name, symbol='`'):
|
||||
@@ -189,17 +191,21 @@ class SphinxDocString(NumpyDocString):
|
||||
return '\n'.join(out)
|
||||
|
||||
class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
|
||||
pass
|
||||
def __init__(self, obj, doc=None, config={}):
|
||||
self.use_plots = config.get('use_plots', False)
|
||||
FunctionDoc.__init__(self, obj, doc=doc, config=config)
|
||||
|
||||
class SphinxClassDoc(SphinxDocString, ClassDoc):
|
||||
pass
|
||||
def __init__(self, obj, doc=None, func_doc=None, config={}):
|
||||
self.use_plots = config.get('use_plots', False)
|
||||
ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config)
|
||||
|
||||
class SphinxObjDoc(SphinxDocString):
|
||||
def __init__(self, obj, doc):
|
||||
def __init__(self, obj, doc=None, config={}):
|
||||
self._f = obj
|
||||
SphinxDocString.__init__(self, doc)
|
||||
SphinxDocString.__init__(self, doc, config=config)
|
||||
|
||||
def get_doc_object(obj, what=None, doc=None):
|
||||
def get_doc_object(obj, what=None, doc=None, config={}):
|
||||
if what is None:
|
||||
if inspect.isclass(obj):
|
||||
what = 'class'
|
||||
@@ -210,10 +216,11 @@ def get_doc_object(obj, what=None, doc=None):
|
||||
else:
|
||||
what = 'object'
|
||||
if what == 'class':
|
||||
return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc)
|
||||
return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc,
|
||||
config=config)
|
||||
elif what in ('function', 'method'):
|
||||
return SphinxFunctionDoc(obj, '', doc=doc)
|
||||
return SphinxFunctionDoc(obj, doc=doc, config=config)
|
||||
else:
|
||||
if doc is None:
|
||||
doc = pydoc.getdoc(obj)
|
||||
return SphinxObjDoc(obj, doc)
|
||||
return SphinxObjDoc(obj, doc, config=config)
|
||||
|
||||
+53
-88
@@ -24,14 +24,16 @@ import inspect
|
||||
def mangle_docstrings(app, what, name, obj, options, lines,
|
||||
reference_offset=[0]):
|
||||
|
||||
cfg = dict(use_plots=app.config.numpydoc_use_plots,
|
||||
show_class_members=app.config.numpydoc_show_class_members)
|
||||
|
||||
if what == 'module':
|
||||
# Strip top title
|
||||
title_re = re.compile(ur'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*',
|
||||
re.I|re.S)
|
||||
lines[:] = title_re.sub(u'', u"\n".join(lines)).split(u"\n")
|
||||
else:
|
||||
doc = get_doc_object(obj, what, u"\n".join(lines))
|
||||
doc.use_plots = app.config.numpydoc_use_plots
|
||||
doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg)
|
||||
lines[:] = unicode(doc).split(u"\n")
|
||||
|
||||
if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
|
||||
@@ -71,7 +73,8 @@ def mangle_docstrings(app, what, name, obj, options, lines,
|
||||
def mangle_signature(app, what, name, obj, options, sig, retann):
|
||||
# Do not try to inspect classes that don't define `__init__`
|
||||
if (inspect.isclass(obj) and
|
||||
'initializes x; see ' in pydoc.getdoc(obj.__init__)):
|
||||
(not hasattr(obj, '__init__') or
|
||||
'initializes x; see ' in pydoc.getdoc(obj.__init__))):
|
||||
return '', ''
|
||||
|
||||
if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
|
||||
@@ -82,80 +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.add_config_value('numpydoc_edit_link', None, True)
|
||||
app.add_config_value('numpydoc_use_plots', None, False)
|
||||
|
||||
# Extra mangling directives
|
||||
name_type = {
|
||||
'cfunction': 'function',
|
||||
'cmember': 'attribute',
|
||||
'cmacro': 'function',
|
||||
'ctype': 'class',
|
||||
'cvar': 'object',
|
||||
'class': 'class',
|
||||
app.connect('autodoc-process-docstring', mangle_docstrings)
|
||||
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 domains
|
||||
app.add_domain(NumpyPythonDomain)
|
||||
app.add_domain(NumpyCDomain)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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',
|
||||
'attribute': 'attribute',
|
||||
'class': 'class',
|
||||
'exception': 'class',
|
||||
'method': 'function',
|
||||
'staticmethod': 'function',
|
||||
'classmethod': 'function',
|
||||
'staticmethod': 'function',
|
||||
'attribute': 'attribute',
|
||||
}
|
||||
|
||||
for name, objtype in name_type.items():
|
||||
app.add_directive('np-' + name, wrap_mangling_directive(name, objtype))
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Input-mangling directives
|
||||
#------------------------------------------------------------------------------
|
||||
from docutils.statemachine import ViewList
|
||||
|
||||
def get_directive(name):
|
||||
from docutils.parsers.rst import directives
|
||||
try:
|
||||
return directives.directive(name, None, None)[0]
|
||||
except AttributeError:
|
||||
if "method" in name:
|
||||
name = "automethod"
|
||||
else:
|
||||
name = "auto"+name
|
||||
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
|
||||
@@ -176,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)
|
||||
|
||||
Reference in New Issue
Block a user