Skip to content

Commit 25d8896

Browse files
committed
Updated numpydocs
1 parent 7742fff commit 25d8896

12 files changed

+1099
-383
lines changed

doc/conf.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@
2828

2929
# Add any Sphinx extension module names here, as strings. They can be extensions
3030
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
31-
extensions = ['sphinx.ext.autodoc',
32-
'sphinx.ext.doctest',
33-
#'sphinx.ext.intersphinx',
34-
'sphinx.ext.todo',
31+
extensions = ['sphinx.ext.todo',
3532
'sphinx.ext.pngmath',
3633
'sphinx.ext.inheritance_diagram',
3734
'sphinx.ext.graphviz',
38-
'numpydoc',
39-
'ipython_console_highlighting',
40-
'only_directives',
35+
'sphinx.ext.autodoc',
36+
'sphinx.ext.doctest',
37+
'sphinx.ext.pngmath',
38+
'sphinx.ext.autosummary',
39+
'inheritance_diagram',
40+
'numpy_ext.numpydoc',
41+
'matplotlib.sphinxext.plot_directive',
42+
'matplotlib.sphinxext.only_directives'
4143
]
4244

4345
# Add any paths that contain templates here, relative to this directory.

doc/sphinxext/README.txt

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,15 @@
55
We've copied these sphinx extensions over from nipy-core. Any edits
66
should be done upstream in nipy-core, not here in nipype!
77

8-
These are a few sphinx extensions we are using to build the nipy
8+
Thesea are a few sphinx extensions we are using to build the nipy
99
documentation. In this file we list where they each come from, since we intend
1010
to always push back upstream any modifications or improvements we make to them.
1111

12-
It's worth noting that some of these are being carried (as copies) by more
13-
than one project. Hopefully once they mature a little more, they will be
14-
incorproated back into sphinx itself, so that all projects can use a common
15-
base.
12+
* From matploltlib:
13+
* inheritance_diagram.py
1614

1715
* From numpy:
18-
* docscrape.py
19-
* docscrape_sphinx.py
20-
* numpydoc.py
16+
* numpy_ext
2117

22-
* From matplotlib:
23-
* inheritance_diagram.py
24-
* ipython_console_highlighting.py
25-
* only_directives.py
18+
* From ipython
19+
* ipython_console_highlighting

doc/sphinxext/autosummary_generate.py

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#!/usr/bin/env python
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
r"""
5+
autosummary_generate.py OPTIONS FILES
6+
7+
Generate automatic RST source files for items referred to in
8+
autosummary:: directives.
9+
10+
Each generated RST file contains a single auto*:: directive which
11+
extracts the docstring of the referred item.
12+
13+
Example Makefile rule::
14+
15+
generate:
16+
./ext/autosummary_generate.py -o source/generated source/*.rst
17+
18+
"""
19+
import glob, re, inspect, os, optparse, pydoc
20+
from autosummary import import_by_name
21+
22+
try:
23+
from phantom_import import import_phantom_module
24+
except ImportError:
25+
import_phantom_module = lambda x: x
26+
27+
def main():
28+
p = optparse.OptionParser(__doc__.strip())
29+
p.add_option("-p", "--phantom", action="store", type="string",
30+
dest="phantom", default=None,
31+
help="Phantom import modules from a file")
32+
p.add_option("-o", "--output-dir", action="store", type="string",
33+
dest="output_dir", default=None,
34+
help=("Write all output files to the given directory (instead "
35+
"of writing them as specified in the autosummary:: "
36+
"directives)"))
37+
options, args = p.parse_args()
38+
39+
if len(args) == 0:
40+
p.error("wrong number of arguments")
41+
42+
if options.phantom and os.path.isfile(options.phantom):
43+
import_phantom_module(options.phantom)
44+
45+
# read
46+
names = {}
47+
for name, loc in get_documented(args).items():
48+
for (filename, sec_title, keyword, toctree) in loc:
49+
if toctree is not None:
50+
path = os.path.join(os.path.dirname(filename), toctree)
51+
names[name] = os.path.abspath(path)
52+
53+
# write
54+
for name, path in sorted(names.items()):
55+
if options.output_dir is not None:
56+
path = options.output_dir
57+
58+
if not os.path.isdir(path):
59+
os.makedirs(path)
60+
61+
try:
62+
obj, name = import_by_name(name)
63+
except ImportError, e:
64+
print "Failed to import '%s': %s" % (name, e)
65+
continue
66+
67+
fn = os.path.join(path, '%s.rst' % name)
68+
69+
if os.path.exists(fn):
70+
# skip
71+
continue
72+
73+
f = open(fn, 'w')
74+
75+
try:
76+
f.write('%s\n%s\n\n' % (name, '='*len(name)))
77+
78+
if inspect.isclass(obj):
79+
if issubclass(obj, Exception):
80+
f.write(format_modulemember(name, 'autoexception'))
81+
else:
82+
f.write(format_modulemember(name, 'autoclass'))
83+
elif inspect.ismodule(obj):
84+
f.write(format_modulemember(name, 'automodule'))
85+
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
86+
f.write(format_classmember(name, 'automethod'))
87+
elif callable(obj):
88+
f.write(format_modulemember(name, 'autofunction'))
89+
elif hasattr(obj, '__get__'):
90+
f.write(format_classmember(name, 'autoattribute'))
91+
else:
92+
f.write(format_modulemember(name, 'autofunction'))
93+
finally:
94+
f.close()
95+
96+
def format_modulemember(name, directive):
97+
parts = name.split('.')
98+
mod, name = '.'.join(parts[:-1]), parts[-1]
99+
return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
100+
101+
def format_classmember(name, directive):
102+
parts = name.split('.')
103+
mod, name = '.'.join(parts[:-2]), '.'.join(parts[-2:])
104+
return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
105+
106+
def get_documented(filenames):
107+
"""
108+
Find out what items are documented in source/*.rst
109+
See `get_documented_in_lines`.
110+
111+
"""
112+
documented = {}
113+
for filename in filenames:
114+
f = open(filename, 'r')
115+
lines = f.read().splitlines()
116+
documented.update(get_documented_in_lines(lines, filename=filename))
117+
f.close()
118+
return documented
119+
120+
def get_documented_in_docstring(name, module=None, filename=None):
121+
"""
122+
Find out what items are documented in the given object's docstring.
123+
See `get_documented_in_lines`.
124+
125+
"""
126+
try:
127+
obj, real_name = import_by_name(name)
128+
lines = pydoc.getdoc(obj).splitlines()
129+
return get_documented_in_lines(lines, module=name, filename=filename)
130+
except AttributeError:
131+
pass
132+
except ImportError, e:
133+
print "Failed to import '%s': %s" % (name, e)
134+
return {}
135+
136+
def get_documented_in_lines(lines, module=None, filename=None):
137+
"""
138+
Find out what items are documented in the given lines
139+
140+
Returns
141+
-------
142+
documented : dict of list of (filename, title, keyword, toctree)
143+
Dictionary whose keys are documented names of objects.
144+
The value is a list of locations where the object was documented.
145+
Each location is a tuple of filename, the current section title,
146+
the name of the directive, and the value of the :toctree: argument
147+
(if present) of the directive.
148+
149+
"""
150+
title_underline_re = re.compile("^[-=*_^#]{3,}\s*$")
151+
autodoc_re = re.compile(".. auto(function|method|attribute|class|exception|module)::\s*([A-Za-z0-9_.]+)\s*$")
152+
autosummary_re = re.compile(r'^\.\.\s+autosummary::\s*')
153+
module_re = re.compile(r'^\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
154+
autosummary_item_re = re.compile(r'^\s+([_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?')
155+
toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
156+
157+
documented = {}
158+
159+
current_title = []
160+
last_line = None
161+
toctree = None
162+
current_module = module
163+
in_autosummary = False
164+
165+
for line in lines:
166+
try:
167+
if in_autosummary:
168+
m = toctree_arg_re.match(line)
169+
if m:
170+
toctree = m.group(1)
171+
continue
172+
173+
if line.strip().startswith(':'):
174+
continue # skip options
175+
176+
m = autosummary_item_re.match(line)
177+
if m:
178+
name = m.group(1).strip()
179+
if current_module and not name.startswith(current_module + '.'):
180+
name = "%s.%s" % (current_module, name)
181+
documented.setdefault(name, []).append(
182+
(filename, current_title, 'autosummary', toctree))
183+
continue
184+
if line.strip() == '':
185+
continue
186+
in_autosummary = False
187+
188+
m = autosummary_re.match(line)
189+
if m:
190+
in_autosummary = True
191+
continue
192+
193+
m = autodoc_re.search(line)
194+
if m:
195+
name = m.group(2).strip()
196+
if m.group(1) == "module":
197+
current_module = name
198+
documented.update(get_documented_in_docstring(
199+
name, filename=filename))
200+
elif current_module and not name.startswith(current_module+'.'):
201+
name = "%s.%s" % (current_module, name)
202+
documented.setdefault(name, []).append(
203+
(filename, current_title, "auto" + m.group(1), None))
204+
continue
205+
206+
m = title_underline_re.match(line)
207+
if m and last_line:
208+
current_title = last_line.strip()
209+
continue
210+
211+
m = module_re.match(line)
212+
if m:
213+
current_module = m.group(2)
214+
continue
215+
finally:
216+
last_line = line
217+
218+
return documented
219+
220+
if __name__ == "__main__":
221+
main()

0 commit comments

Comments
 (0)