1
<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: Twisted Coding Standard</title><link href="../howto/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">Twisted Coding Standard</h1><div class="toc"><ol><li><a href="#auto0">Naming</a></li><li><a href="#auto1">Testing</a></li><li><a href="#auto2">Whitespace</a></li><li><a href="#auto3">Modules</a></li><li><a href="#auto4">Packages</a></li><li><a href="#auto5">Docstrings</a></li><li><a href="#auto6">Scripts</a></li><li><a href="#auto7">Standard Library Extension Modules</a></li><li><a href="#auto8">ChangeLog</a></li><li><a href="#auto9">Classes</a></li><li><a href="#auto10">Methods</a></li><li><a href="#auto11">Callback Arguments</a></li><li><a href="#auto12">Special Methods</a></li><li><a href="#auto13">Functions</a></li><li><a href="#auto14">Attributes</a></li><li><a href="#auto15">Database</a></li><li><a href="#auto16">C Code</a></li><li><a href="#auto17">Commit Messages</a></li><li><a href="#auto18">Source Control</a></li><li><a href="#auto19">Recommendations</a></li></ol></div><div class="content"><span></span><h2>Naming<a name="auto0"></a></h2><p>Try to choose names which are both easy to remember and
3
meaningful. Some silliness is OK at the module naming level
4
(see <code class="API">twisted.spread</code>...) but when
5
choosing class names, be as precise as possible. Write code
6
with a dictionary and thesaurus open on the table next to
7
you.</p><p>Try to avoid overloaded terms. This rule is often broken,
8
since it is incredibly difficult, as most normal words have
9
already been taken by some other software. More importantly,
10
try to avoid meaningless words. In particular, words like
11
<q>handler</q>, <q>processor</q>, <q>engine</q>, <q>manager</q>
12
and <q>component</q> don't really indicate what something does,
14
<em>something</em>.</p><p>Use American spelling in both names and docstrings. For compound
15
technical terms such as 'filesystem', use a non-hyphenated spelling in
16
both docstrings and code in order to avoid unnecessary
17
capitalization. </p><h2>Testing<a name="auto1"></a></h2><p>Unit tests are written using the <code class="API">twisted.trial</code> framework. Many examples are in the
18
<code class="API">twisted.test</code> package. Test modules should start
19
with 'test_' in their name. Source files should have <a href="test-standard.html"><code>test-case-name</code></a> tags that
20
point to their related tests.</p><p>Acceptance tests are all automated by the admin/accepttests
21
script currently. (TODO: real acceptance tests strategy!)</p><p>Run the unit tests tests before you check anything in.</p><p>Let me repeat that, for emphasis: <em>run the unit tests before you
22
check <strong>anything</strong> in</em>. Code which breaks
23
functionality is unfortunate and unavoidable. The acceptance tests
24
are highly nonportable and sometimes a pain to run, so this is pardonable.
25
Code which breaks the unit tests in a way that you could have prevented
26
by running them yourself, however, may be grounds for anything from
27
merciless taunting through revertion of the breakage to revocation
28
of SVN commit privileges.</p><p>It is strongly suggested that developers learn to use Emacs, and use
29
the <code>twisted-dev.el</code> file included in the TwistedEmacs
30
package to bind the F9 key to <q>run unit tests</q> and bang on it
31
frequently. Support for other editors is unavailable at this time
32
but we would love to provide it.</p><p>If you modify, or write a new, HOWTO, please read the <a href="http://twistedmatrix.com/projects/lore">Lore</a>
33
documentation to learn the format the docs.</p><h2>Whitespace<a name="auto2"></a></h2><p>Indentation is 4 spaces per indent. Tabs are not allowed. It
34
is preferred that every block appear on a new line, so that
35
control structure indentation is always visible.</p><p>Lines are flowed at 79 columns.</p><h2>Modules<a name="auto3"></a></h2><p>Modules must be named in all lower-case, preferably short,
36
single words. If a module name contains multiple words, they
37
may be separated by underscores or not separated at all.</p><p>In most cases, modules should contain more than one class,
38
function, or method; if a module contains only one object,
39
consider refactoring to include more related functionality in
40
that module.</p><p>Depending on the situation, it is acceptable to have imports that
43
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">defer</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Deferred</span>
47
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">defer</span>
49
That is, modules should import <em>modules</em> or <em>classes and
50
functions</em>, but not <em>packages</em>.</p><p>Wildcard import syntax may not be used by code in Twisted. These
51
imports lead to code which is difficult to read and maintain by
52
introducing complexity which strains human readers and automated tools
53
alike. If you find yourself with many imports to make from a single
54
module and wish to save typing, consider importing the module itself,
55
rather than its attributes.</p><p><em>Relative imports</em> (or <em>sibling imports</em>) may not be
56
used by code in Twisted. Relative imports allow certain circularities
57
to be introduced which can ultimately lead to unimportable modules or
58
duplicate instances of a single module. Relative imports also make the
59
task of refactoring more difficult.</p><h2>Packages<a name="auto4"></a></h2><p>Package names should follow the same conventions as module
60
names. All modules must be encapsulated in some package. Nested
61
packages may be used to further organize related modules.</p><p><code>__init__.py</code> must never contain anything other than a
62
docstring and (optionally) an <code>__all__</code> attribute. Packages are
63
not modules and should be treated differently. This rule may be
64
broken to preserve backwards compatibility if a module is made
65
into a nested package as part of a refactoring.</p><p>If you wish to promote code from a module to a package, for
66
example, to break a large module out into several smaller
67
files, the accepted way to do this is to promote from within
68
the module. For example,</p><pre class="python">
69
<span class="py-src-comment"># parent/
70
</span><span class="py-src-comment"># --- __init__.py ---
71
</span><span class="py-src-keyword">import</span> <span class="py-src-variable">child</span>
73
<span class="py-src-comment"># --- child.py ---
74
</span><span class="py-src-keyword">import</span> <span class="py-src-variable">parent</span>
75
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Foo</span>:
76
<span class="py-src-keyword">pass</span>
77
<span class="py-src-variable">parent</span>.<span class="py-src-variable">Foo</span> = <span class="py-src-variable">Foo</span>
78
</pre><p>Every package should be added to the list in
79
<code class="shell">setup.py</code>.</p><p>Packages must not depend circularly upon each other. To simplify
80
maintaining this state, packages must also not import each other
81
circularly. While this applies to all packages within Twisted, one
82
<code>twisted.python</code> deserves particular attention, as it may
83
not depend on any other Twisted package.</p><h2>Docstrings<a name="auto5"></a></h2><p>Wherever possible, docstrings should be used to describe the
84
purpose of methods, functions, classes, and modules. In cases
85
where it's desirable to avoid documenting thoroughly -- for
86
example, an evolving interface -- insert a placeholder
87
docstring (<code class="py-src-string">"UNDOCUMENTED"</code> is preferred),
89
auto-generated API documentation will not pick up an extraneous
90
comment as the documentation for that
91
module/class/function.</p><p>Docstrings are <em>never</em> to be used to provide semantic
92
information about an object; this rule may be violated if the
93
code in question is to be used in a system where this is a
94
requirement (such as Zope).</p><p>Docstrings should be indented to the level of the code they
95
are documenting.</p><p>Docstrings should be triple-quoted.</p><p>Docstrings should be written in epytext format; more
96
documentation is available in the
97
<a href="http://epydoc.sourceforge.net/epytext.html">Epytext Markup Language documentation</a>.</p><p>Additionally, to accommodate emacs users:</p><ul><li>Single quotes of the type of the docstring's triple-quote
98
should be escaped. This will prevent font-lock from
99
accidentally fontifying large portions of the file as a
100
string.</li><li>Code examples in docstrings should be prefixed by the |
101
character. This will prevent IM-Python from regarding sample
102
code as real functions, methods, and classes.</li></ul><p>For example,</p><pre class="python">
103
<span class="py-src-keyword">def</span> <span class="py-src-identifier">foo2bar</span>(<span class="py-src-parameter">f</span>):
104
<span class="py-src-string">"""I am a function to convert foos to bars.
106
I should be used when you have a foo but you want a bar; note that this is
107
a non-destructive operation. If I can\'t convert the foo to a bar I will
108
raise a FooException().
113
| def sample(something):
114
| f = something.getFoo()
116
| b = wombat.foo2bar(f)
120
"""</span>
121
<span class="py-src-comment"># Optionally, actual code can go here.
122
</span></pre><h2>Scripts<a name="auto6"></a></h2><p>For each <q>script</q>, that is, a program you expect a Twisted user
123
to run from the command-line, the following things must be done:</p><ol><li>Write a module in <code class="API">twisted.scripts</code>
124
which contains a callable global named <code>run</code>. This
125
will be called by the command line part with no arguments (it
126
will usually read <code>sys.argv</code>). Feel free to write more
127
functions or classes in this module, if you feel they are useful
128
to others.</li><li>Write a file in <code class="shell">bin/</code> which contains the
129
Twisted running-from-SVN header, and ending with
132
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">scripts</span>.<span class="py-src-variable">yourmodule</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">run</span>
133
<span class="py-src-variable">run</span>()
134
</pre></li><li>Write a manpage in <code class="shell">doc/man</code>.
135
On debian systems you can find a skeleton example of a manpage in
136
<code>/usr/share/doc/man-db/examples/manpage.example</code>.</li><li>Add your script to the script list in
137
<code class="shell">setup.py</code>.</li></ol><p>This will insure your program will work correctly for users of SVN,
138
Windows releases and Debian packages.</p><h2>Standard Library Extension Modules<a name="auto7"></a></h2><p>When using the extension version of a module for which there is also
139
a Python version, place the import statement inside a try/except block,
140
and import the Python version if the import fails. This allows code to
141
work on platforms where the extension version is not available. For
145
<span class="py-src-keyword">try</span>:
146
<span class="py-src-keyword">import</span> <span class="py-src-variable">cPickle</span> <span class="py-src-variable">as</span> <span class="py-src-variable">pickle</span>
147
<span class="py-src-keyword">except</span> <span class="py-src-variable">ImportError</span>:
148
<span class="py-src-keyword">import</span> <span class="py-src-variable">pickle</span>
151
Use the "as" syntax of the import statement as well, to set
152
the name of the extension module to the name of the Python module.</p><h2>ChangeLog<a name="auto8"></a></h2><p>All changes that will affect the way end-users see Twisted should come
153
with an appropriate entry in the ChangeLog that summarizes that impact.</p><p>The correct format for the ChangeLog is GNU changelog format. There is
154
an emacs mode for editing this, use <code>M-x add-change-log-entry</code>.
155
If you are, for whatever absurd reason, using an editor other than emacs
156
to edit Twisted, you can use Moshe Zadka's helpfully provided
157
<code>admin/change</code> script to add a properly-formatted entry.</p><h2>Classes<a name="auto9"></a></h2><p>Classes are to be named in mixed case, with the first letter
158
capitalized; each word separated by having its first letter
159
capitalized. Acronyms should be capitalized in their entirety.
160
Class names should not be prefixed with the name of the module they are
161
in. Examples of classes meeting this criteria:</p><ul><li>twisted.spread.pb.ViewPoint</li><li>twisted.parser.patterns.Pattern</li></ul><p>Examples of classes <strong>not</strong> meeting this criteria:</p><ul><li>event.EventHandler</li><li>main.MainGadget</li></ul><p>An effort should be made to prevent class names from clashing
162
with each other between modules, to reduce the need for
163
qualification when importing. For example, a Service subclass
164
for Forums might be named twisted.forum.service.ForumService,
165
and a Service subclass for Words might be
166
twisted.words.service.WordsService. Since neither of these
167
modules are volatile <em>(see above)</em> the classes may be
168
imported directly into the user's namespace and not cause
169
confusion.</p><h2>Methods<a name="auto10"></a></h2><p>Methods should be in mixed case, with the first letter lower
170
case, each word separated by having its first letter
171
capitalized. For example, <code>someMethodName</code>,
172
<code>method</code>.</p><p>Sometimes, a class will dispatch to a specialized sort of
173
method using its name; for example, twisted.reflect.Accessor.
174
In those cases, the type of method should be a prefix in all
175
lower-case with a trailing underscore, so method names will
176
have an underscore in them. For example, <code>get_someAttribute</code>.
177
Underscores in method names in twisted code are therefore
178
expected to have some semantic associated with them.</p><p>Some methods, in particular <code>addCallback</code> and its
179
cousins return self to allow for chaining calls. In this case,
180
wrap the chain in parenthesis, and start each chained call on
181
a separate line, for example:</p><pre class="python">
182
<span class="py-src-keyword">return</span> (<span class="py-src-variable">foo</span>()
183
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">bar</span>)
184
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">thud</span>)
185
.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">wozers</span>))
186
</pre><h2>Callback Arguments<a name="auto11"></a></h2><p>There are several methods whose purpose is to help the user set up
187
callback functions, for example <code base="twisted.internet.defer" class="API">Deferred.addCallback</code> or the
188
reactor's <code base="twisted.internet.base.ReactorBase" class="API">callLater</code> method. To make
189
access to the callback as transparent as possible, most of these methods
190
use <code class="python">**kwargs</code> to capture arbitrary arguments
191
that are destined for the user's callback. This allows the call to the
192
setup function to look very much like the eventual call to the target
193
callback function.</p><p>In these methods, take care to not have other argument names that will
194
<q>steal</q> the user's callback's arguments. When sensible, prefix these
195
<q>internal</q> argument names with an underscore. For example, <code base="twisted.spread.pb" class="API">RemoteReference.callRemote</code> is
196
meant to be called like this:</p><pre class="python">
197
<span class="py-src-variable">myref</span>.<span class="py-src-variable">callRemote</span>(<span class="py-src-string">"addUser"</span>, <span class="py-src-string">"bob"</span>, <span class="py-src-string">"555-1212"</span>)
199
<span class="py-src-comment"># on the remote end, the following method is invoked:
200
</span><span class="py-src-keyword">def</span> <span class="py-src-identifier">addUser</span>(<span class="py-src-parameter">name</span>, <span class="py-src-parameter">phone</span>):
202
</pre><p>where <q>addUser</q> is the remote method name. The user might also
203
choose to call it with named parameters like this:</p><pre class="python">
204
<span class="py-src-variable">myref</span>.<span class="py-src-variable">callRemote</span>(<span class="py-src-string">"addUser"</span>, <span class="py-src-variable">name</span>=<span class="py-src-string">"bob"</span>, <span class="py-src-variable">phone</span>=<span class="py-src-string">"555-1212"</span>)
205
</pre><p>In this case, <code>callRemote</code> (and any code that uses the
206
**kwargs syntax) must be careful to not use <q>name</q>, <q>phone</q>, or
207
any other name that might overlap with a user-provided named parameter.
208
Therefore, <code>callRemote</code> is implemented with the following
209
signature:</p><pre class="python">
210
<span class="py-src-keyword">def</span> <span class="py-src-identifier">callRemote</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">_name</span>, *<span class="py-src-parameter">args</span>, **<span class="py-src-parameter">kw</span>):
212
</pre><p>Do whatever you can to reduce user confusion. It may also be
213
appropriate to <code class="python">assert</code> that the kwargs
214
dictionary does not contain parameters with names that will eventually
215
cause problems.</p><h2>Special Methods<a name="auto12"></a></h2><p>The augmented assignment protocol, defined by __iadd__ and other
216
similarly named methods, can be used to allow objects to be modified in
217
place or to rebind names if an object is immutable -- both through use
218
of the same operator. This can lead to confusing code, which in turn
219
leads to buggy code. For this reason, methods of the augmented
220
assignment protocol should not be used in Twisted.</p><h2>Functions<a name="auto13"></a></h2><p>Functions should be named similiarly to methods.</p><p>Functions or methods which are responding to events to
221
complete a callback or errback should be named <code>_cbMethodName</code> or
222
<code>_ebMethodName</code>, in order to distinguish them from normal
223
methods.</p><h2>Attributes<a name="auto14"></a></h2><p>Attributes should be named similarly to functions and
224
methods. Attributes should be named descriptively; attribute
225
names like <code>mode</code>, <code>type</code>, and
226
<code>buf</code> are generally discouraged. Instead, use
227
<code>displayMode</code>, <code>playerType</code>, or
228
<code>inputBuffer</code>.</p><p>Do not use Python's <q>private</q> attribute syntax; prefix
229
non-public attributes with a single leading underscore. Since
230
several classes have the same name in Twisted, and they are
231
distinguished by which package they come from, Python's
232
double-underscore name mangling will not work reliably in some
233
cases. Also, name-mangled private variables are more difficult
234
to address when unit testing or persisting a class.</p><p>An attribute (or function, method or class) should be
235
considered private when one or more of the following conditions
236
are true:</p><ul><li>The attribute represents intermediate state which is not
237
always kept up-to-date.</li><li>Referring to the contents of the attribute or otherwise
238
maintaining a reference to it may cause resources to
239
leak.</li><li>Assigning to the attribute will break internal
240
assumptions.</li><li>The attribute is part of a known-to-be-sub-optimal
241
interface and will certainly be removed in a future
242
release.</li></ul><h2>Database<a name="auto15"></a></h2><p>Database tables will be named with plural nouns.</p><p>Database columns will be named with underscores between
243
words, all lower case, since most databases do not distinguish
244
between case.</p><p>Any attribute, method argument, or method name that
245
corresponds <em>directly</em> to a column in the database will
246
be named exactly the same as that column, regardless of other
247
coding conventions surrounding that circumstance.</p><p>All SQL keywords should be in upper case.</p><h2>C Code<a name="auto16"></a></h2><p>Wherever possible, C code should be optional, and the
248
default python implementation should be maintained in tandem
249
with it. C code should be strict ANSI C, and
250
<strong>must</strong> build using GCC as well as Visual Studio
251
for Windows, and really shouldn't have any problems with other
252
compilers either. Don't do anything tricky.</p><p>C code should only be used for efficiency, not for binding
253
to external libraries. If your particular code is not
254
frequently run, write it in Python. If you require the use of
255
an external library, develop a separate, external bindings
256
package and make your twisted code depend on it.</p><h2>Commit Messages<a name="auto17"></a></h2><p>The commit messages are being distributed in a myriad of ways. Because
257
of that, you need to observe a few simple rules when writing a commit
258
message.</p><p>The first line of the message is being used as both the subject of
259
the commit email and the announcement on #twisted. Therefore, it should
260
be short (aim for < 80 characters) and descriptive -- and must be
261
able to stand alone (it is best if it is a complete sentence). The rest
262
of the e-mail should be separated with <em>hard line breaks</em> into
263
short lines (< 70 characters). This is free-format, so you can do
264
whatever you like here.</p><p>Commit messages should be about <em>what</em>, not <em>how</em>: we can
265
get how from SVN diff. Explain reasons for commits, and what they
266
affect.</p><p>Each commit should be a single logical change, which is internally
267
consistent. If you can't summarize your changes in one short line, this
268
is probably a sign that they should be broken into multiple checkins.</p><h2>Source Control<a name="auto18"></a></h2><p>Twisted currently uses Subversion for source control. All
269
development <strong>should</strong> occur using branches; when a task is
270
considered complete another Twisted developer may review it and if no
271
problems are found, it may be merged into trunk (TODO: Describe this
272
more thoroughly (Divmod wiki has <a href="http://divmod.org/trac/wiki/BranchBasedDevelopment">a start</a>)).
273
Branches <strong>must</strong> be used for major development. Branches
274
should be managed using <a href="http://divmod.org/trac/wiki/DivmodCombinator">Combinator</a> (but
275
if you can manage them in some other way without anyone noticing, knock
276
yourself out).</p><p>Certain features of Subversion should be avoided.</p><ul><li><p>Do not set the <code class="shell">svn:ignore</code> property on any
277
file or directory. What you wish to ignore, others may wish to examine.
278
What others may wish you ignore, <em>you</em> may wish you examine.
279
<code class="shell"> svn:ignore </code> will affect everyone who uses
280
the repository, and so it is not the right mechanism to express personal
281
preferences.</p><p>If you wish to ignore certain files use the <code class="shell">
282
global-ignores </code> feature of <code class="shell">
283
~/.subversion/config </code>, for example:</p><pre class="shell">
285
global-ignores = dropin.cache *.pyc *.pyo *.o *.lo *.la #*# .*.rej *.rej .*~
286
</pre></li></ul><h2>Recommendations<a name="auto19"></a></h2><p>These things aren't necessarily standardizeable (in that
287
code can't be easily checked for compliance) but are a good
288
idea to keep in mind while working on Twisted.</p><p>If you're going to work on a fragment of the Twisted
289
codebase, please consider finding a way that you would <em>use</em>
290
such a fragment in daily life. I use the Twisted Web server on
291
the main TML website, and aside from being good PR, this
292
encourages you to actively maintain and improve your code, as
293
the little everyday issues with using it become apparent.</p><p>Twisted is a <strong>big</strong> codebase! If you're
294
refactoring something, please make sure to recursively grep for
295
the names of functions you're changing. You may be surprised to
296
learn where something is called. Especially if you are moving
297
or renaming a function, class, method, or module, make sure
298
that it won't instantly break other code.</p></div><p><a href="../howto/index.html">Index</a></p><span class="version">Version: 2.5.0</span></body></html>
b'\\ No newline at end of file'