~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to doc/development/policy/coding-standard.html

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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,
 
13
    only that it 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
 
41
    look like this:
 
42
    <pre class="python">
 
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>
 
44
</pre>
 
45
    or like this:
 
46
    <pre class="python">
 
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>
 
48
</pre>
 
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>
 
72
 
 
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">&quot;UNDOCUMENTED&quot;</code> is preferred),
 
88
    so that the
 
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">&quot;&quot;&quot;I am a function to convert foos to bars.
 
105
 
 
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().
 
109
 
 
110
    For example::
 
111
 
 
112
      |  import wombat
 
113
      |  def sample(something):
 
114
      |      f = something.getFoo()
 
115
      |      f.doFooThing()
 
116
      |      b = wombat.foo2bar(f)
 
117
      |      b.doBarThing()
 
118
      |      return b
 
119
 
 
120
    &quot;&quot;&quot;</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 
 
130
 
 
131
<pre class="python">
 
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
 
142
    example:
 
143
 
 
144
<pre class="python">
 
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>
 
149
</pre>
 
150
 
 
151
    Use the &quot;as&quot; 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">&quot;addUser&quot;</span>, <span class="py-src-string">&quot;bob&quot;</span>, <span class="py-src-string">&quot;555-1212&quot;</span>)
 
198
 
 
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>):
 
201
    ...
 
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">&quot;addUser&quot;</span>, <span class="py-src-variable">name</span>=<span class="py-src-string">&quot;bob&quot;</span>, <span class="py-src-variable">phone</span>=<span class="py-src-string">&quot;555-1212&quot;</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>):
 
211
   ...
 
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 &lt; 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 (&lt; 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">
 
284
[miscellany]
 
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'