Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e7eaf44

Browse files
committed
added support for ReST-based documentation using Sphinx
svn path=/trunk/matplotlib/; revision=5217
1 parent b61419a commit e7eaf44

25 files changed

Lines changed: 2702 additions & 1169 deletions

doc/CODING_GUIDE

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
***************
2+
Version Control
3+
***************
4+
5+
svn checkouts
6+
=============
7+
8+
Checking out everything in the trunk (matplotlib and toolkits)::
9+
10+
svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk \
11+
matplotlib --username=youruser --password=yourpass
12+
13+
Checking out the main source::
14+
15+
svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/\
16+
matplotlib matplotlib --username=youruser --password=yourpass
17+
18+
Branch checkouts, eg the maintenance branch::
19+
20+
svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/\
21+
v0_91_maint mplv0_91_maint
22+
23+
Committing changes
24+
==================
25+
26+
When committing changes to matplotlib, there are a few things to bear
27+
in mind.
28+
29+
* if your changes are non-trivial, please make an entry in the
30+
CHANGELOG
31+
* if you change the API, please document it in API_CHANGES, and
32+
consider posting to mpl-devel
33+
* Are your changes python2.3 compatible? We are still trying to
34+
support 2.3, so avoid 2.4 only features like decorators until we
35+
remove 2.3 support
36+
* Can you pass examples/backend_driver.py? This is our poor man's
37+
unit test.
38+
* If you have altered extension code, do you pass
39+
unit/memleak_hawaii.py?
40+
* if you have added new files or directories, or reorganized
41+
existing ones, are the new files included in the match patterns in
42+
MANIFEST.in. This file determines what goes into the src
43+
distribution of the mpl build.
44+
* Keep the maintenance branch and trunk in sync where it makes sense.
45+
If there is a bug on both that needs fixing, use svnmerge.py to
46+
keep them in sync. http://www.orcaware.com/svn/wiki/Svnmerge.py. The
47+
basic procedure is:
48+
49+
* install svnmerge.py in your PATH::
50+
51+
wget http://svn.collab.net/repos/svn/trunk/contrib/client-side/\
52+
svnmerge/svnmerge.py
53+
54+
* get a svn copy of the maintenance branch and the trunk (see above)
55+
* Michael advises making the change on the branch and committing
56+
it. Make sure you svn upped on the trunk and have no local
57+
modifications, and then from the svn trunk do::
58+
59+
> svnmerge.py merge -rNNN1,NNN2
60+
61+
where the NNN* are the revision numbers. Ranges arealso acceptable.
62+
svnmergy.py automatically creates a file containing the commit messages,
63+
so you are ready to make the commit::
64+
65+
> svn commit -F svnmerge-commit-message.txt
66+
67+
***********
68+
Style Guide
69+
***********
70+
71+
Importing and name spaces
72+
=========================
73+
74+
For numpy, use::
75+
76+
import numpy as np
77+
a = np.array([1,2,3])
78+
79+
For masked arrays, use::
80+
81+
from numpy import ma
82+
83+
(The earlier recommendation, 'import matplotlib.numerix.npyma as ma',
84+
was needed temporarily during the development of the maskedarray
85+
implementation as a separate package. As of numpy 1.1, it replaces the
86+
old implementation. Note: "from numpy import ma" works with numpy < 1.1
87+
*and* with numpy >= 1.1. "import numpy.ma as ma" works *only* with
88+
numpy >= 1.1, so for now we must not use it.)
89+
90+
For matplotlib main module, use::
91+
92+
import matplotlib as mpl
93+
mpl.rcParams['xtick.major.pad'] = 6
94+
95+
For matplotlib modules (or any other modules), use::
96+
97+
import matplotlib.cbook as cbook
98+
99+
if cbook.iterable(z):
100+
pass
101+
102+
We prefer this over the equivalent 'from matplotlib import cbook'
103+
because the latter is ambiguous whether cbook is a module or a
104+
function to the new developer. The former makes it explcit that
105+
you are importing a module or package.
106+
107+
Naming, spacing, and formatting conventions
108+
===========================================
109+
110+
In general, we want to hew as closely as possible to the standard
111+
coding guidelines for python written by Guido in
112+
http://www.python.org/dev/peps/pep-0008, though we do not do this
113+
throughout.
114+
115+
* functions and class methods: lower or lower_underscore_separated
116+
117+
* attributes and variables: lower or lowerUpper
118+
119+
* classes: Upper or MixedCase
120+
121+
Personally, I prefer the shortest names that are still readable.
122+
123+
Also, use an editor that does not put tabs in files. Four spaces
124+
should be used for indentation everywhere and if there is a file with
125+
tabs or more or less spaces it is a bug -- please fix it.
126+
127+
Please avoid spurious invisible spaces at the ends of lines.
128+
(Tell your editor to strip whitespace from line ends when saving
129+
a file.)
130+
131+
Keep docstrings uniformly indented as in the example below, with
132+
nothing to the left of the triple quotes. The dedent() function
133+
is needed to remove excess indentation only if something will be
134+
interpolated into the docstring, again as in the example above.
135+
136+
Limit line length to 80 characters. If a logical line needs to be
137+
longer, use parentheses to break it; do not use an escaped
138+
newline. It may be preferable to use a temporary variable
139+
to replace a single long line with two shorter and more
140+
readable lines.
141+
142+
Please do not commit lines with trailing white space, as it causes
143+
noise in svn diffs. If you are an emacs user, the following in your
144+
.emacs will cause emacs to strip trailing white space on save for
145+
python, C and C++::
146+
147+
; and similarly for c++-mode-hook and c-mode-hook
148+
(add-hook 'python-mode-hook
149+
(lambda ()
150+
(add-hook 'write-file-functions 'delete-trailing-whitespace)))
151+
152+
for older versions of emacs (emacs<22) you need to do::
153+
154+
(add-hook 'python-mode-hook
155+
(lambda ()
156+
(add-hook 'local-write-file-hooks 'delete-trailing-whitespace)))
157+
158+
Keyword argument processing
159+
===========================
160+
161+
Matplotlib makes extensive use of ``**kwargs`` for pass through
162+
customizations from one function to another. A typical example is in
163+
pylab.text, The definition of the pylab text function is a simple
164+
pass-through to axes.Axes.text::
165+
166+
# in pylab.py
167+
def text(*args, **kwargs):
168+
ret = gca().text(*args, **kwargs)
169+
draw_if_interactive()
170+
return ret
171+
172+
axes.Axes.text in simplified form looks like this, ie it just passes
173+
them on to text.Text.__init__::
174+
175+
# in axes.py
176+
def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
177+
t = Text(x=x, y=y, text=s, **kwargs)
178+
179+
and Text.__init__ (again with liberties for illustration) just passes
180+
them on to the artist.Artist.update method::
181+
182+
# in text.py
183+
def __init__(self, x=0, y=0, text='', **kwargs):
184+
Artist.__init__(self)
185+
self.update(kwargs)
186+
187+
'update' does the work looking for methods named like 'set_property'
188+
if 'property' is a keyword argument. Ie, noone looks at the keywords,
189+
they just get passed through the API to the artist constructor which
190+
looks for suitably named methods and calls them with the value.
191+
192+
As a general rule, the use of ``**kwargs`` should be reserved for
193+
pass-through keyword arguments, as in the examaple above. If I intend
194+
for all the keyword args to be used in some function and not passed
195+
on, I just use the key/value keyword args in the function definition
196+
rather than the ``**kwargs`` idiom.
197+
198+
In some cases I want to consume some keys and pass through the others,
199+
in which case I pop the ones I want to use locally and pass on the
200+
rest, eg I pop scalex and scaley in Axes.plot and assume the rest are
201+
Line2D keyword arguments. As an example of a pop, passthrough
202+
usage, see Axes.plot::
203+
204+
# in axes.py
205+
def plot(self, *args, **kwargs):
206+
scalex = kwargs.pop('scalex', True)
207+
scaley = kwargs.pop('scaley', True)
208+
if not self._hold: self.cla()
209+
lines = []
210+
for line in self._get_lines(*args, **kwargs):
211+
self.add_line(line)
212+
lines.append(line)
213+
214+
The matplotlib.cbook function popd() is rendered
215+
obsolete by the pop() dictionary method introduced in Python 2.3,
216+
so it should not be used for new code.
217+
218+
Note there is a use case when kwargs are meant to be used locally in
219+
the function (not passed on), but you still need the ``**kwargs`` idiom.
220+
That is when you want to use ``*args`` to allow variable numbers of
221+
non-keyword args. In this case, python will not allow you to use
222+
named keyword args after the ``*args`` usage, so you will be forced to use
223+
``**kwargs``. An example is matplotlib.contour.ContourLabeler.clabel::
224+
225+
# in contour.py
226+
def clabel(self, *args, **kwargs):
227+
fontsize = kwargs.get('fontsize', None)
228+
inline = kwargs.get('inline', 1)
229+
self.fmt = kwargs.get('fmt', '%1.3f')
230+
colors = kwargs.get('colors', None)
231+
if len(args) == 0:
232+
levels = self.levels
233+
indices = range(len(self.levels))
234+
elif len(args) == 1:
235+
...etc...
236+
237+
Documentation and Docstrings
238+
============================
239+
240+
matplotlib uses artist instrospection of docstrings to support
241+
properties. All properties that you want to support through setp and
242+
getp should have a set_property and get_property method in the Artist
243+
class. Yes, this is not ideal given python properties or enthought
244+
traits, but it is a historical legacy for now. The setter methods use
245+
the docstring with the ACCEPTS token to indicate the type of argument
246+
the method accepts. Eg in matplotlib.lines.Line2D::
247+
248+
# in lines.py
249+
def set_linestyle(self, linestyle):
250+
"""
251+
Set the linestyle of the line
252+
253+
ACCEPTS: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' | ' ' | '' ]
254+
"""
255+
256+
Since matplotlib uses a lot of pass through kwargs, eg in every
257+
function that creates a line (plot, semilogx, semilogy, etc...), it
258+
can be difficult for the new user to know which kwargs are supported.
259+
I have developed a docstring interpolation scheme to support
260+
documentation of every function that takes a ``**kwargs``. The
261+
requirements are:
262+
263+
1. single point of configuration so changes to the properties don't
264+
require multiple docstring edits
265+
266+
2. as automated as possible so that as properties change the docs
267+
are updated automagically.
268+
269+
I have added a matplotlib.artist.kwdocd and kwdoc() to faciliate this.
270+
They combines python string interpolation in the docstring with the
271+
matplotlib artist introspection facility that underlies setp and getp.
272+
The kwdocd is a single dictionary that maps class name to a docstring
273+
of kwargs. Here is an example from matplotlib.lines::
274+
275+
# in lines.py
276+
artist.kwdocd['Line2D'] = artist.kwdoc(Line2D)
277+
278+
Then in any function accepting Line2D passthrough kwargs, eg
279+
matplotlib.axes.Axes.plot::
280+
281+
# in axes.py
282+
def plot(self, *args, **kwargs):
283+
"""
284+
Some stuff omitted
285+
286+
The kwargs are Line2D properties:
287+
%(Line2D)s
288+
289+
kwargs scalex and scaley, if defined, are passed on
290+
to autoscale_view to determine whether the x and y axes are
291+
autoscaled; default True. See Axes.autoscale_view for more
292+
information
293+
"""
294+
pass
295+
plot.__doc__ = cbook.dedent(plot.__doc__) % artist.kwdocd
296+
297+
Note there is a problem for Artist __init__ methods, eg Patch.__init__
298+
which supports Patch kwargs, since the artist inspector cannot work
299+
until the class is fully defined and we can't modify the
300+
Patch.__init__.__doc__ docstring outside the class definition. I have
301+
made some manual hacks in this case which violates the "single entry
302+
point" requirement above; hopefully we'll find a more elegant solution
303+
before too long
304+
305+
********
306+
Licenses
307+
********
308+
309+
Matplotlib only uses BSD compatible code. If you bring in code from
310+
another project make sure it has a PSF, BSD, MIT or compatible
311+
license. If not, you may consider contacting the author and asking
312+
them to relicense it. GPL and LGPL code are not acceptible in the
313+
main code base, though we are considering an alternative way of
314+
distributing L/GPL code through an separate channel, possibly a
315+
toolkit. If you include code, make sure you include a copy of that
316+
code's license in the license directory if the code's license requires
317+
you to distribute the license with it.

doc/api_reference/make.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python
2+
import fileinput
3+
import glob
4+
import os
5+
import shutil
6+
import sys
7+
8+
def check_build():
9+
build_dirs = ['build', 'build/doctrees', 'build/html', 'build/latex',
10+
'source/_static', 'source/_templates']
11+
for d in build_dirs:
12+
try:
13+
os.mkdir(d)
14+
except OSError:
15+
pass
16+
17+
def figs():
18+
os.system('cd source/figures/ && python make.py')
19+
20+
def html():
21+
check_build()
22+
os.system('sphinx-build -b html -d build/doctrees source build/html')
23+
24+
def latex():
25+
if sys.platform != 'win32':
26+
# LaTeX format.
27+
os.system('sphinx-build -b latex -d build/doctrees source build/latex')
28+
29+
# Produce pdf.
30+
os.chdir('build/latex')
31+
32+
# Copying the makefile produced by sphinx...
33+
os.system('pdflatex Matplotlib_API_Reference.tex')
34+
os.system('pdflatex Matplotlib_API_Reference.tex')
35+
os.system('makeindex -s python.ist Matplotlib_API_Reference.idx')
36+
os.system('makeindex -s python.ist modMatplotlib_API_Reference.idx')
37+
os.system('pdflatex Matplotlib_API_Reference.tex')
38+
39+
os.chdir('../..')
40+
else:
41+
print 'latex build has not been tested on windows'
42+
43+
def clean():
44+
shutil.rmtree('build')
45+
46+
def all():
47+
figs()
48+
html()
49+
latex()
50+
51+
52+
funcd = {'figs':figs,
53+
'html':html,
54+
'latex':latex,
55+
'clean':clean,
56+
'all':all,
57+
}
58+
59+
60+
if len(sys.argv)>1:
61+
for arg in sys.argv[1:]:
62+
func = funcd.get(arg)
63+
if func is None:
64+
raise SystemExit('Do not know how to handle %s; valid args are'%(
65+
arg, funcd.keys()))
66+
func()
67+
else:
68+
all()

0 commit comments

Comments
 (0)