Permalink
Browse files

sphinxext: add numpydoc_show_class_members option (from Michael Droet…

…tboom)
  • Loading branch information...
1 parent 66313a3 commit 9d48a39d23b507e18ca8fa7c5786b5eaea926d0e @pv pv committed Nov 13, 2009
View
26 doc/sphinxext/README.txt
@@ -24,3 +24,29 @@ The following extensions are available:
Available in Sphinx 0.6.2 and (to-be) 1.0 as ``sphinx.ext.autosummary``,
and it the Sphinx 1.0 version is recommended over that included in
Numpydoc.
+
+
+numpydoc
+========
+
+Numpydoc inserts a hook into Sphinx's autodoc that converts docstrings
+following the Numpy/Scipy format to a form palatable to Sphinx.
+
+Options
+-------
+
+The following options can be set in conf.py:
+
+- numpydoc_use_plots: bool
+
+ Whether to produce ``plot::`` directives for Examples sections that
+ contain ``import matplotlib``.
+
+- numpydoc_show_class_members: bool
+
+ Whether to show all members of a class in the Methods and Attributes
+ sections automatically.
+
+- numpydoc_edit_link: bool (DEPRECATED -- edit your HTML template instead)
+
+ Whether to insert an edit link after docstrings.
View
30 doc/sphinxext/docscrape.py
@@ -84,7 +84,7 @@ def is_empty(self):
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 @@ def _parse_param_list(self,content):
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 @@ def push_item(name, rest):
current_func = None
rest = []
-
+
for line in content:
if not line.strip(): continue
@@ -258,7 +258,7 @@ def strip_each_in(lst):
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 @@ def _parse_summary(self):
if not self._is_at_section():
self['Extended Summary'] = self._read_to_next_section()
-
+
def _parse(self):
self._doc.reset()
self._parse_summary()
@@ -408,7 +408,7 @@ 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:
@@ -442,7 +442,7 @@ def get_func(self):
else:
func = self._f
return func, func_name
-
+
def __str__(self):
out = ''
@@ -463,7 +463,8 @@ def __str__(self):
class ClassDoc(NumpyDocString):
- def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
+ 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)
self._cls = cls
@@ -479,12 +480,13 @@ def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
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):
View
25 doc/sphinxext/docscrape_sphinx.py
@@ -3,7 +3,9 @@
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 @@ def __str__(self, indent=0, func_role="obj"):
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, config={}):
+ self.use_plots = config.get('use_plots', False)
+ ClassDoc.__init__(self, obj, doc=doc, 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)
View
13 doc/sphinxext/numpydoc.py
@@ -24,14 +24,16 @@
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 \
@@ -91,11 +93,12 @@ def initialize(app):
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_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 = {
@@ -114,7 +117,7 @@ def setup(app, get_doc_object_=get_doc_object):
for name, objtype in name_type.items():
app.add_directive('np-' + name, wrap_mangling_directive(name, objtype))
-
+
#------------------------------------------------------------------------------
# Input-mangling directives
#------------------------------------------------------------------------------
View
42 doc/sphinxext/tests/test_docscrape.py
@@ -3,8 +3,8 @@
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from docscrape import NumpyDocString, FunctionDoc
-from docscrape_sphinx import SphinxDocString
+from docscrape import NumpyDocString, FunctionDoc, ClassDoc
+from docscrape_sphinx import SphinxDocString, SphinxClassDoc
from nose.tools import *
doc_txt = '''\
@@ -329,6 +329,10 @@ def test_sphinx_str():
.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
2nd ed., Wiley, 2001.
+.. only:: latex
+
+ [1]_, [2]_
+
.. rubric:: Examples
>>> mean = (1,2)
@@ -490,13 +494,15 @@ def test_unicode():
assert doc['Summary'][0] == u'öäöäöäöäöåååå'.encode('utf-8')
def test_plot_examples():
+ cfg = dict(use_plots=True)
+
doc = SphinxDocString("""
Examples
--------
>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3],[4,5,6])
>>> plt.show()
- """)
+ """, config=cfg)
assert 'plot::' in str(doc), str(doc)
doc = SphinxDocString("""
@@ -507,5 +513,33 @@ def test_plot_examples():
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6])
plt.show()
- """)
+ """, config=cfg)
assert str(doc).count('plot::') == 1, str(doc)
+
+def test_class_members():
+
+ class Dummy(object):
+ """
+ Dummy class.
+
+ """
+ def spam(self, a, b):
+ """Spam\n\nSpam spam."""
+ pass
+ def ham(self, c, d):
+ """Cheese\n\nNo cheese."""
+ pass
+
+ for cls in (ClassDoc, SphinxClassDoc):
+ doc = cls(Dummy, config=dict(show_class_members=False))
+ assert 'Methods' not in str(doc), (cls, str(doc))
+ assert 'spam' not in str(doc), (cls, str(doc))
+ assert 'ham' not in str(doc), (cls, str(doc))
+
+ doc = cls(Dummy, config=dict(show_class_members=True))
+ assert 'Methods' in str(doc), (cls, str(doc))
+ assert 'spam' in str(doc), (cls, str(doc))
+ assert 'ham' in str(doc), (cls, str(doc))
+
+ if cls is SphinxClassDoc:
+ assert '.. autosummary::' in str(doc), str(doc)
View
8 doc/sphinxext/traitsdoc.py
@@ -111,7 +111,7 @@ def looks_like_issubclass(obj, classname):
return True
return False
-def get_doc_object(obj, what=None):
+def get_doc_object(obj, what=None, config=None):
if what is None:
if inspect.isclass(obj):
what = 'class'
@@ -122,17 +122,17 @@ def get_doc_object(obj, what=None):
else:
what = 'object'
if what == 'class':
- doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc)
+ doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc, config=config)
if looks_like_issubclass(obj, 'HasTraits'):
for name, trait, comment in comment_eater.get_class_traits(obj):
# Exclude private traits.
if not name.startswith('_'):
doc['Traits'].append((name, trait, comment.splitlines()))
return doc
elif what in ('function', 'method'):
- return SphinxFunctionDoc(obj, '')
+ return SphinxFunctionDoc(obj, '', config=config)
else:
- return SphinxDocString(pydoc.getdoc(obj))
+ return SphinxDocString(pydoc.getdoc(obj), config=config)
def setup(app):
# init numpydoc

0 comments on commit 9d48a39

Please sign in to comment.