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

Skip to content

Commit 1657003

Browse files
committed
updated coding guide
svn path=/trunk/matplotlib/; revision=2960
1 parent 7b693ed commit 1657003

File tree

1 file changed

+82
-35
lines changed

1 file changed

+82
-35
lines changed

CODING_GUIDE

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
Devs, feel free to edit this document. This is meant to be a guide to
2-
developers on the mpl coding practices and standards
1+
= The matplotlib developer's guide =
32

3+
This is meant to be a guide to developers on the mpl coding practices
4+
and standards. Please edit and extend this document.
45

5-
== Committing Changes ==
6+
== Committing changes ==
67

78
When committing changes to matplotlib, there are a few things to bear
89
in mind.
910

10-
* if your changes are nontrivial, please make an entry in the
11+
* if your changes are non-trivial, please make an entry in the
1112
CHANGELOG
1213

1314
* if you change the API, please document it in API_CHANGES, and
14-
consider posing to mpl-devel
15+
consider posting to mpl-devel
1516

1617
* Are your changes python2.3 compatible? We are still trying to
1718
support 2.3, so avoid 2.4 only features like decorators until we
@@ -30,7 +31,7 @@ in mind.
3031
unit/memleak_hawaii.py?
3132

3233

33-
== Naming conventions ==
34+
== Naming and spacing conventions ==
3435

3536
functions and class methods : lower or lower_underscore_separated
3637

@@ -40,28 +41,72 @@ in mind.
4041

4142
Personally, I prefer the shortest names that are still readable.
4243

43-
== kwargs processing ==
44+
Also, use an editor that does not put tabs in files. Four spaces
45+
should be used for indentation everywhere and if there is a file with
46+
tabs or more or less spaces it is a bug -- please fix it.
4447

45-
Matplotlib makes extensive use of **kwargs for pass through
46-
customizations from one function to another, eg the pylab plot ->
47-
Axes.plot pass through. As a general rule, the use of **kwargs should
48-
be reserved for pass-through keyword arguments, eg
49-
50-
def somefunc(x, k1='something', **kwargs):
51-
# do some thing with x, k1
52-
return some_other_func(..., **kwargs)
53-
54-
If I intend for all the keyword args to be used in somefunc alone, I
55-
just use the key/value keyword args in the function definition rather
56-
than the **kwargs idiom. In some cases I want to consume some keys
57-
and pass through the others, in which case I pop the ones I want to
58-
use locally and pass on the rest, eg I pop scalex and scaley in
59-
Axes.plot and assume the rest are Line2D keyword arguments. Whenever
60-
you mutate a kwargs dictionary (eg by popping it), you must first copy
61-
it since the user may be explitly passing in a dictionary which is
62-
used across many function calls. As an example of a copy, pop,
63-
passthrough usage, see Axes.plot:
48+
== Licenses ==
49+
50+
matplotlib only uses BSD compatible code. If you bring in code from
51+
another project make sure it has a PSF, BSD, MIT or compatible
52+
license. If not, you may consider contacting the author and asking
53+
them to relicense it. GPL and LGPL code are not acceptible in the
54+
main code base, though we are considering an alternative way of
55+
distributing L/GPL code through an separate channel, possibly a
56+
toolkit. If you include code, make sure you include a copy of that
57+
code's license in the license directory if the code's license requires
58+
you to distribute the license with it.
59+
60+
61+
== Keyword argument processing ==
6462

63+
Matplotlib makes extensive use of **kwargs for pass through
64+
customizations from one function to another. A typical example is in
65+
pylab.text, The definition of the pylab text function is a simple
66+
pass-through to axes.Axes.text
67+
68+
# in pylab.py
69+
def text(*args, **kwargs):
70+
ret = gca().text(*args, **kwargs)
71+
draw_if_interactive()
72+
return ret
73+
74+
75+
axes.Axes.text in simplified form looks like this, ie it just passes
76+
them on to text.Text.__init__
77+
# in axes.py
78+
def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
79+
t = Text(x=x, y=y, text=s, **kwargs)
80+
81+
82+
and Text.__init__ (again with liberties for illustration) just passes
83+
them on to the artist.Artist.update method
84+
85+
# in text.py
86+
def __init__(self, x=0, y=0, text='', **kwargs):
87+
Artist.__init__(self)
88+
self.update(kwargs)
89+
90+
'update' does the work looking for methods named like 'set_property'
91+
if 'property' is a keyword argument. Ie, noone looks at the keywords,
92+
they just get passed through the API to the artist constructor which
93+
looks for suitably named methods and calls them with the value.
94+
95+
As a general rule, the use of **kwargs should be reserved for
96+
pass-through keyword arguments, as in the exmaple above. If I intend
97+
for all the keyword args to be used in some function and not passed
98+
on, I just use the key/value keyword args in the function definition
99+
rather than the **kwargs idiom.
100+
101+
In some cases I want to consume some keys and pass through the others,
102+
in which case I pop the ones I want to use locally and pass on the
103+
rest, eg I pop scalex and scaley in Axes.plot and assume the rest are
104+
Line2D keyword arguments. Whenever you mutate a kwargs dictionary (eg
105+
by popping it), you must first copy it since the user may be explitly
106+
passing in a dictionary which is used across many function calls. As
107+
an example of a copy, pop, passthrough usage, see Axes.plot:
108+
109+
# in axes.py
65110
def plot(self, *args, **kwargs):
66111
kwargs = kwargs.copy()
67112
scalex = popd(kwargs, 'scalex', True)
@@ -82,6 +127,7 @@ non-keyword args. In this case, python will not allow you to use
82127
named keyword args after the *args usage, so you will be forced to use
83128
**kwargs. An example is matplotlib.contour.ContourLabeler.clabel
84129

130+
# in contour.py
85131
def clabel(self, *args, **kwargs):
86132
fontsize = kwargs.get('fontsize', None)
87133
inline = kwargs.get('inline', 1)
@@ -93,18 +139,17 @@ named keyword args after the *args usage, so you will be forced to use
93139
elif len(args) == 1:
94140
...etc...
95141

96-
97-
98-
== class documentation ==
142+
== Class documentation ==
99143

100144
matplotlib uses artist instrospection of docstrings to support
101145
properties. All properties that you want to support through setp and
102146
getp should have a set_property and get_property method in the Artist
103-
class. Yes this is not ideal given python properties or enthought
147+
class. Yes, this is not ideal given python properties or enthought
104148
traits, but it is a historical legacy for now. The setter methods use
105149
the docstring with the ACCEPTS token to indicate the type of argument
106150
the method accepts. Eg in matplotlib.lines.Line2D
107151

152+
# in lines.py
108153
def set_linestyle(self, linestyle):
109154
"""
110155
Set the linestyle of the line
@@ -130,13 +175,15 @@ I have added a matplotlib.artist.kwdocd to faciliate this. This
130175
combines python string interpolation in the docstring with the
131176
matplotlib artist introspection facility that underlies setp and getp.
132177
The kwdocd is a single dictionary that maps class name to a docstring
133-
of kwargs. Here is an example at the bottom of matplotlib.lines
178+
of kwargs. Here is an example from matplotlib.lines
134179

135-
artist.kwdocd['Line2D'] = '\n'.join(artist.ArtistInspector(Line2D).pprint_setters(leadingspace=12))
180+
# in lines.py
181+
artist.kwdocd['Line2D'] = '\n'.join(artist.ArtistInspector(Line2D).pprint_setters(leadingspace=12))
136182

137183
Then in any function accepting Line2D passthrough kwargs, eg
138184
matplotlib.axes.Axes.plot
139185

186+
# in axes.py
140187
def plot(self, *args, **kwargs):
141188
"""
142189
Some stuff omitted
@@ -152,9 +199,9 @@ matplotlib.axes.Axes.plot
152199
pass
153200
plot.__doc__ = plot.__doc__ % artist.kwdocd
154201

155-
Note there is a problem for Artist __init__ methods, eg
156-
Patch.__init__ which supports Patch kwargs, since the artist inspector
157-
cannot work until the class is fully defined and we can't modify the
202+
Note there is a problem for Artist __init__ methods, eg Patch.__init__
203+
which supports Patch kwargs, since the artist inspector cannot work
204+
until the class is fully defined and we can't modify the
158205
Patch.__init__.__doc__ docstring outside the class definition. I have
159206
made some manual hacks in this case which violates the "single entry
160207
point" requirement above; hopefully we'll find a more elegant solution

0 commit comments

Comments
 (0)