Updated numpydoc files from the github package numpy/numpydoc

This commit is contained in:
emmanuelle
2014-12-14 18:02:46 +01:00
parent 53bb6f9369
commit 9395464122
4 changed files with 703 additions and 720 deletions
+66 -27
View File
@@ -1,17 +1,16 @@
"""Extract reference documentation from the NumPy source tree.
"""
from __future__ import division, absolute_import, print_function
import inspect
import textwrap
import re
import pydoc
try:
from StringIO import StringIO
except ImportError:
import io as StringIO
from warnings import warn
import collections
import sys
class Reader(object):
"""A line-based string reader.
@@ -117,7 +116,7 @@ class NumpyDocString(object):
return self._parsed_data[key]
def __setitem__(self,key,val):
if not key in self._parsed_data:
if key not in self._parsed_data:
warn("Unknown section %s" % key)
else:
self._parsed_data[key] = val
@@ -269,13 +268,17 @@ class NumpyDocString(object):
if self._is_at_section():
return
summary = self._doc.read_to_next_empty_line()
summary_str = " ".join([s.strip() for s in summary]).strip()
if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
self['Signature'] = summary_str
if not self._is_at_section():
self['Summary'] = self._doc.read_to_next_empty_line()
else:
# If several signatures present, take the last one
while True:
summary = self._doc.read_to_next_empty_line()
summary_str = " ".join([s.strip() for s in summary]).strip()
if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
self['Signature'] = summary_str
if not self._is_at_section():
continue
break
if summary is not None:
self['Summary'] = summary
if not self._is_at_section():
@@ -332,7 +335,10 @@ class NumpyDocString(object):
if self[name]:
out += self._str_header(name)
for param,param_type,desc in self[name]:
out += ['%s : %s' % (param, param_type)]
if param_type:
out += ['%s : %s' % (param, param_type)]
else:
out += [param]
out += self._str_indent(desc)
out += ['']
return out
@@ -374,7 +380,7 @@ class NumpyDocString(object):
idx = self['index']
out = []
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
for section, references in idx.items():
if section == 'default':
continue
out += [' :%s: %s' % (section, ', '.join(references))]
@@ -428,7 +434,10 @@ class FunctionDoc(NumpyDocString):
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
if sys.version_info[0] >= 3:
argspec = inspect.getfullargspec(func)
else:
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
@@ -454,7 +463,7 @@ class FunctionDoc(NumpyDocString):
'meth': 'method'}
if self._role:
if not roles.has_key(self._role):
if self._role not in roles:
print("Warning: invalid role %s" % self._role)
out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''),
func_name)
@@ -464,12 +473,18 @@ class FunctionDoc(NumpyDocString):
class ClassDoc(NumpyDocString):
extra_public_methods = ['__call__']
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
self.show_inherited_members = config.get('show_inherited_class_members',
True)
if modulename and not modulename.endswith('.'):
modulename += '.'
self._mod = modulename
@@ -482,23 +497,47 @@ class ClassDoc(NumpyDocString):
NumpyDocString.__init__(self, doc)
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)]
def splitlines_x(s):
if not s:
return []
else:
return s.splitlines()
for field, items in [('Methods', self.methods),
('Attributes', self.properties)]:
if not self[field]:
doc_list = []
for name in sorted(items):
try:
doc_item = pydoc.getdoc(getattr(self._cls, name))
doc_list.append((name, '', splitlines_x(doc_item)))
except AttributeError:
pass # method doesn't exist
self[field] = doc_list
@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)]
return [name for name, func in inspect.getmembers(self._cls)
if ((not name.startswith('_')
or name in self.extra_public_methods)
and isinstance(func, collections.Callable)
and self._is_show_member(name))]
@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]
return [name for name, func in inspect.getmembers(self._cls)
if (not name.startswith('_') and
(func is None or isinstance(func, property) or
inspect.isgetsetdescriptor(func))
and self._is_show_member(name))]
def _is_show_member(self, name):
if self.show_inherited_members:
return True # show all class members
if name not in self._cls.__dict__:
return False # class member is inherited, we do not show it
return True
+71 -24
View File
@@ -1,11 +1,24 @@
import re, inspect, textwrap, pydoc
from __future__ import division, absolute_import, print_function
import sys, re, inspect, textwrap, pydoc
import sphinx
import collections
from docscrape import NumpyDocString, FunctionDoc, ClassDoc
if sys.version_info[0] >= 3:
sixu = lambda s: s
else:
sixu = lambda s: unicode(s, 'unicode_escape')
class SphinxDocString(NumpyDocString):
def __init__(self, docstring, config={}):
self.use_plots = config.get('use_plots', False)
NumpyDocString.__init__(self, docstring, config=config)
self.load_config(config)
def load_config(self, config):
self.use_plots = config.get('use_plots', False)
self.class_members_toctree = config.get('class_members_toctree', True)
# string conversion routines
def _str_header(self, name, symbol='`'):
@@ -33,16 +46,37 @@ class SphinxDocString(NumpyDocString):
def _str_extended_summary(self):
return self['Extended Summary'] + ['']
def _str_returns(self):
out = []
if self['Returns']:
out += self._str_field_list('Returns')
out += ['']
for param, param_type, desc in self['Returns']:
if param_type:
out += self._str_indent(['**%s** : %s' % (param.strip(),
param_type)])
else:
out += self._str_indent([param.strip()])
if desc:
out += ['']
out += self._str_indent(desc, 8)
out += ['']
return out
def _str_param_list(self, name):
out = []
if self[name]:
out += self._str_field_list(name)
out += ['']
for param,param_type,desc in self[name]:
out += self._str_indent(['**%s** : %s' % (param.strip(),
param_type)])
out += ['']
out += self._str_indent(desc,8)
for param, param_type, desc in self[name]:
if param_type:
out += self._str_indent(['**%s** : %s' % (param.strip(),
param_type)])
else:
out += self._str_indent(['**%s**' % param.strip()])
if desc:
out += ['']
out += self._str_indent(desc, 8)
out += ['']
return out
@@ -72,25 +106,36 @@ class SphinxDocString(NumpyDocString):
others = []
for param, param_type, desc in self[name]:
param = param.strip()
if not self._obj or hasattr(self._obj, param):
# Check if the referenced member can have a docstring or not
param_obj = getattr(self._obj, param, None)
if not (callable(param_obj)
or isinstance(param_obj, property)
or inspect.isgetsetdescriptor(param_obj)):
param_obj = None
if param_obj and (pydoc.getdoc(param_obj) or not desc):
# Referenced object has a docstring
autosum += [" %s%s" % (prefix, param)]
else:
others.append((param, param_type, desc))
if autosum:
out += ['.. autosummary::', ' :toctree:', '']
out += autosum
out += ['.. autosummary::']
if self.class_members_toctree:
out += [' :toctree:']
out += [''] + autosum
if others:
maxlen_0 = max([len(x[0]) for x in others])
maxlen_1 = max([len(x[1]) for x in others])
hdr = "="*maxlen_0 + " " + "="*maxlen_1 + " " + "="*10
fmt = '%%%ds %%%ds ' % (maxlen_0, maxlen_1)
n_indent = maxlen_0 + maxlen_1 + 4
out += [hdr]
maxlen_0 = max(3, max([len(x[0]) for x in others]))
hdr = sixu("=")*maxlen_0 + sixu(" ") + sixu("=")*10
fmt = sixu('%%%ds %%s ') % (maxlen_0,)
out += ['', hdr]
for param, param_type, desc in others:
out += [fmt % (param.strip(), param_type)]
out += self._str_indent(desc, n_indent)
desc = sixu(" ").join(x.strip() for x in desc).strip()
if param_type:
desc = "(%s) %s" % (param_type, desc)
out += [fmt % (param.strip(), desc)]
out += [hdr]
out += ['']
return out
@@ -127,7 +172,7 @@ class SphinxDocString(NumpyDocString):
return out
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
for section, references in idx.items():
if section == 'default':
continue
elif section == 'refguide':
@@ -178,8 +223,9 @@ class SphinxDocString(NumpyDocString):
out += self._str_index() + ['']
out += self._str_summary()
out += self._str_extended_summary()
for param_list in ('Parameters', 'Returns', 'Other Parameters',
'Raises', 'Warns'):
out += self._str_param_list('Parameters')
out += self._str_returns()
for param_list in ('Other Parameters', 'Raises', 'Warns'):
out += self._str_param_list(param_list)
out += self._str_warnings()
out += self._str_see_also(func_role)
@@ -193,17 +239,18 @@ class SphinxDocString(NumpyDocString):
class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
def __init__(self, obj, doc=None, config={}):
self.use_plots = config.get('use_plots', False)
self.load_config(config)
FunctionDoc.__init__(self, obj, doc=doc, config=config)
class SphinxClassDoc(SphinxDocString, ClassDoc):
def __init__(self, obj, doc=None, func_doc=None, config={}):
self.use_plots = config.get('use_plots', False)
self.load_config(config)
ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config)
class SphinxObjDoc(SphinxDocString):
def __init__(self, obj, doc=None, config={}):
self._f = obj
self.load_config(config)
SphinxDocString.__init__(self, doc, config=config)
def get_doc_object(obj, what=None, doc=None, config={}):
@@ -212,7 +259,7 @@ def get_doc_object(obj, what=None, doc=None, config={}):
what = 'class'
elif inspect.ismodule(obj):
what = 'module'
elif callable(obj):
elif isinstance(obj, collections.Callable):
what = 'function'
else:
what = 'object'
+51 -29
View File
@@ -12,51 +12,68 @@ It will:
- Renumber references.
- Extract the signature from the docstring, if it can't be determined otherwise.
.. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
.. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
"""
from __future__ import division, absolute_import, print_function
import sys
import re
import pydoc
import sphinx
import inspect
import collections
if sphinx.__version__ < '1.0.1':
raise RuntimeError("Sphinx 1.0.1 or newer is required")
import os, re, sys, pydoc
from docscrape_sphinx import get_doc_object, SphinxDocString
from sphinx.util.compat import Directive
import inspect
if sys.version.startswith('3'):
u = str
if sys.version_info[0] >= 3:
sixu = lambda s: s
else:
u = unicode
sixu = lambda s: unicode(s, 'unicode_escape')
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)
cfg = dict(
use_plots=app.config.numpydoc_use_plots,
show_class_members=app.config.numpydoc_show_class_members,
show_inherited_class_members=app.config.numpydoc_show_inherited_class_members,
class_members_toctree=app.config.numpydoc_class_members_toctree,
)
if what == 'module':
# Strip top title
title_re = re.compile(u(r'^\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")
title_re = re.compile(sixu('^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*'),
re.I|re.S)
lines[:] = title_re.sub(sixu(''), sixu("\n").join(lines)).split(sixu("\n"))
else:
doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg)
lines[:] = u(doc).split(u"\n")
doc = get_doc_object(obj, what, sixu("\n").join(lines), config=cfg)
if sys.version_info[0] >= 3:
doc = str(doc)
else:
doc = unicode(doc)
lines[:] = doc.split(sixu("\n"))
if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
obj.__name__:
if hasattr(obj, '__module__'):
v = dict(full_name=u"%s.%s" % (obj.__module__, obj.__name__))
v = dict(full_name=sixu("%s.%s") % (obj.__module__, obj.__name__))
else:
v = dict(full_name=obj.__name__)
lines += [u'', u'.. htmlonly::', '']
lines += [u' %s' % x for x in
lines += [sixu(''), sixu('.. htmlonly::'), sixu('')]
lines += [sixu(' %s') % x for x in
(app.config.numpydoc_edit_link % v).split("\n")]
# replace reference numbers so that there are no duplicates
references = []
for line in lines:
line = line.strip()
m = re.match(u(r'^.. \[([a-z0-9_.-])\]'), line, re.I)
m = re.match(sixu('^.. \\[([a-z0-9_.-])\\]'), line, re.I)
if m:
references.append(m.group(1))
@@ -65,14 +82,14 @@ def mangle_docstrings(app, what, name, obj, options, lines,
if references:
for i, line in enumerate(lines):
for r in references:
if re.match(u(r'^\d+$'), r):
new_r = u"R%d" % (reference_offset[0] + int(r))
if re.match(sixu('^\\d+$'), r):
new_r = sixu("R%d") % (reference_offset[0] + int(r))
else:
new_r = u"%s%d" % (r, reference_offset[0])
lines[i] = lines[i].replace(u'[%s]_' % r,
u'[%s]_' % new_r)
lines[i] = lines[i].replace(u'.. [%s]' % r,
u'.. [%s]' % new_r)
new_r = sixu("%s%d") % (r, reference_offset[0])
lines[i] = lines[i].replace(sixu('[%s]_') % r,
sixu('[%s]_') % new_r)
lines[i] = lines[i].replace(sixu('.. [%s]') % r,
sixu('.. [%s]') % new_r)
reference_offset[0] += len(references)
@@ -83,15 +100,18 @@ def mangle_signature(app, what, name, obj, options, sig, retann):
'initializes x; see ' in pydoc.getdoc(obj.__init__))):
return '', ''
if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
if not (isinstance(obj, collections.Callable) or hasattr(obj, '__argspec_is_invalid_')): return
if not hasattr(obj, '__doc__'): return
doc = SphinxDocString(pydoc.getdoc(obj))
if doc['Signature']:
sig = re.sub(u"^[^(]*", u"", doc['Signature'])
return sig, u''
sig = re.sub(sixu("^[^(]*"), sixu(""), doc['Signature'])
return sig, sixu('')
def setup(app, get_doc_object_=get_doc_object):
if not hasattr(app, 'add_config_value'):
return # probably called by nose, better bail out
global get_doc_object
get_doc_object = get_doc_object_
@@ -100,6 +120,8 @@ def setup(app, get_doc_object_=get_doc_object):
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)
app.add_config_value('numpydoc_show_inherited_class_members', True, True)
app.add_config_value('numpydoc_class_members_toctree', True, True)
# Extra mangling domains
app.add_domain(NumpyPythonDomain)
@@ -121,7 +143,7 @@ class ManglingDomainBase(object):
self.wrap_mangling_directives()
def wrap_mangling_directives(self):
for name, objtype in self.directive_mangling_map.items():
for name, objtype in list(self.directive_mangling_map.items()):
self.directives[name] = wrap_mangling_directive(
self.directives[name], objtype)
@@ -136,6 +158,7 @@ class NumpyPythonDomain(ManglingDomainBase, PythonDomain):
'staticmethod': 'function',
'attribute': 'attribute',
}
indices = []
class NumpyCDomain(ManglingDomainBase, CDomain):
name = 'np-c'
@@ -167,4 +190,3 @@ def wrap_mangling_directive(base_directive, objtype):
return base_directive.run(self)
return directive
+515 -640
View File
File diff suppressed because it is too large Load Diff