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

« back to all changes in this revision

Viewing changes to doc/CodingStandard.html

  • Committer: Bazaar Package Importer
  • Author(s): Moshe Zadka
  • Date: 2002-03-08 07:14:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020308071416-oxvuw76tpcpi5v1q
Tags: upstream-0.15.5
ImportĀ upstreamĀ versionĀ 0.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
  <html>
 
2
    <head>
 
3
      <title>Twisted Coding Standard</title>
 
4
    </head>
 
5
    
 
6
    <body>
 
7
      <h1>Twisted Coding Standard</h1>
 
8
      <h3>Naming</h3>
 
9
      <p>
 
10
        Try to choose names which are both easy to remember and meaningful.
 
11
        Some silliness is OK at the module naming level (see twisted.spread...)
 
12
        but when choosing class names, be as precise as possible.  Write code
 
13
        with a dictionary and thesaurus open on the table next to you.
 
14
      </p>
 
15
      <p>
 
16
        Try to avoid overloaded terms.  This rule is often broken, since it is
 
17
        incredibly difficult, as most normal words have already been taken by
 
18
        some other software.  More importantly, try to avoid meaningless words.
 
19
        In particular, words like "handler", "processor", "engine", "manager",
 
20
        and "component" don't really indicate what something does, only that it
 
21
        does <b>something</b>.
 
22
      </p>
 
23
      <h3>Testing</h3>
 
24
      <p>
 
25
        Unit tests are written using the PyUnit framework.  Many examples are
 
26
        in the twisted.test package, and all tests should be integrated through
 
27
        the main test suite builder in twisted.test.test_all.
 
28
      </p>
 
29
      <p>
 
30
        Acceptance tests are all automated by the bin/accepttests script
 
31
        currently.  (TODO: real acceptance tests strategy!)
 
32
      </p>
 
33
      <h3>Whitespace</h3>
 
34
      <p>
 
35
        Indentation is 4 spaces per indent.  Tabs are not allowed.  It is
 
36
        preferred that every block appear on a new line, so that control
 
37
        structure indentation is always visible.
 
38
      </p>
 
39
      <h3>Modules</h3>
 
40
      <p>
 
41
        Modules must be named in all lower-case, preferably short, single
 
42
        words.  If a module name contains multiple words, they may be separated
 
43
        by underscores or not separated at all.
 
44
      </p>
 
45
      <p>
 
46
        In most cases, modules should contain more than one class, function, or
 
47
        method; if a module contains only one object, consider refactoring to
 
48
        include more related functionality in that module.
 
49
      </p>
 
50
      <p>
 
51
        <em>Note that this rule is a change from previous versions of Twisted,
 
52
        so a lot of code does not yet adhere to it.</em>
 
53
      </p>
 
54
      <p>
 
55
        By default, objects from modules in Twisted ought to be imported
 
56
        directly into the namespace of the module that uses them, like this:
 
57
        <code>from twisted.python.defer import Deferred</code>
 
58
      </p>
 
59
      <p>
 
60
        In some cases, however, Twisted takes advantage of the dynamic binding
 
61
        of Python in order to provide an interface through a module that may be
 
62
        imported -- we call these "volatile" modules, because their internals
 
63
        are subject to change without warning.  In these cases, it is
 
64
        desireable to import the module itself into the user's namespace, so
 
65
        that things bound to it will be looked up on each call.  For obvious
 
66
        reasons, classes in volatile modules should never be subclassed.
 
67
      </p>
 
68
      <p>
 
69
        Volatile modules will have a __volatile__ attribute set to 1, and
 
70
        should always have a docstring snippet like the one that follows:
 
71
        
 
72
        <blockquote>
 
73
          <pre>
 
74
"""
 
75
NOTE: this is a __volatile__ module.  This means that if you are using it
 
76
externally, you should know that its contents may change at any time.  In
 
77
general, all this means is that you must not use it like this::
 
78
 
 
79
    from twisted.package.module import Class
 
80
    Class()
 
81
 
 
82
but instead like this::
 
83
 
 
84
    from twisted.package import module
 
85
    module.Class()
 
86
"""
 
87
          </pre>
 
88
        </blockquote>
 
89
      </p>
 
90
      <h3>Packages</h3>
 
91
      <p>
 
92
        Package names should follow the same conventions as module names.  All
 
93
        modules must be encapsulated in some package.  Nested packages may be
 
94
        used to further organize related modules.
 
95
      </p>
 
96
      <p>
 
97
        __init__.py must never contain anything other than a docstring and
 
98
        (optionally) an __all__ attribute.  Packages are not modules and should
 
99
        be treated differently.  This rule may be broken to preserve backwards
 
100
        compatibility if a module is made into a nested package as part of a
 
101
        refactoring.
 
102
      </p>
 
103
      <p>
 
104
        If you wish to promote code from a module to a package, for
 
105
        example, to break a large module out into several smaller
 
106
        files, the accepted way to do this is to promote from within
 
107
        the module.  For example,
 
108
<pre>
 
109
# parent/
 
110
# --- __init__.py ---
 
111
import child
 
112
 
 
113
# --- child.py ---
 
114
import parent
 
115
class Foo:
 
116
    pass
 
117
parent.Foo = Foo
 
118
</pre>
 
119
      </p>
 
120
      
 
121
      <h3>Docstrings</h3>
 
122
      <p>
 
123
        Wherever possible, docstrings should be used to describe the purpose of
 
124
        methods, functions, classes, and modules.  In cases where it's
 
125
        desirable to avoid documenting thoroughly -- for example, and evolving
 
126
        interface -- insert a placeholder docstring ("UNDOCUMENTED" is
 
127
        preferred), so that the auto-generated API documentation will not pick
 
128
        up an extraneous comment as the documentation for that
 
129
        module/class/function.
 
130
      </p>
 
131
      <p>
 
132
        Docstrings are <em>never</em> to be used to provide semantic
 
133
        information about an object; this rule may be violated if the code in
 
134
        question is to be used in a system where this is a requirement (such as
 
135
        Zope).
 
136
      </p>
 
137
      <p>
 
138
        Docstrings should be indented to the level of the code they are
 
139
        documenting.
 
140
      </p>
 
141
      <p>
 
142
        Docstrings should be triple-quoted.
 
143
      </p>
 
144
      <p>
 
145
        Docstrings should be written in StructuredText format; more
 
146
        documentation is available on the <a
 
147
        href="http://happydoc.sourceforge.net">HappyDoc website</a>.
 
148
      </p>
 
149
      <p>
 
150
        Additionally, to accommodate emacs users:
 
151
        
 
152
        <ul>
 
153
          <li>
 
154
            Single quotes of the type of the docstring's triple-quote should be
 
155
            escaped.  This will prevent font-lock from accidentally fontifying
 
156
            large portions of the file as a string.
 
157
          </li>
 
158
          <li>
 
159
            Code examples in docstrings should be prefixed by the | character.
 
160
            This will prevent IM-Python from regarding sample code as real
 
161
            functions, methods, and classes.
 
162
          </li>
 
163
        </ul>
 
164
      </p>
 
165
      <p>
 
166
        For example,
 
167
        <pre>
 
168
def foo2bar(f):
 
169
    """I am a function to convert foos to bars.
 
170
 
 
171
    I should be used when you have a foo but you want a bar; note that this is a
 
172
    non-destructive operation.  If I can\'t convert the foo to a bar I will raise a
 
173
    FooException().
 
174
 
 
175
    For example::
 
176
 
 
177
      |  import wombat
 
178
      |  def sample(something):
 
179
      |      f = something.getFoo()
 
180
      |      f.doFooThing()
 
181
      |      b = wombat.foo2bar(f)
 
182
      |      b.doBarThing()
 
183
      |      return b
 
184
 
 
185
    """
 
186
    # Optionally, actual code can go here.
 
187
        </pre>
 
188
      </p>
 
189
      
 
190
      <h3>Classes</h3>
 
191
      <p>
 
192
        Classes are to be named in mixed case, with the first letter
 
193
        capitalized; each word separated by having its first letter
 
194
        capitalized.  Acronyms should be capitalized in their entirety.  Class
 
195
        names should not include the name of the module they are a part of.
 
196
        Examples:
 
197
        <ul>
 
198
          <li> twisted.reality.thing.Thing </li>
 
199
          <li> twisted.web.Handler </li>
 
200
          <li> twisted.spread.pb.ViewPoint </li>
 
201
          <li> twisted.parser.patterns.Pattern </li>
 
202
        </ul>
 
203
        An effort should be made to prevent class names from clashing with each
 
204
        other between modules, to reduce the need for qualification when
 
205
        importing.  For example, a Service subclass for Forums might be named
 
206
        twisted.forum.service.ForumService, and a Service subclass for Words
 
207
        might be twisted.words.service.WordsService.  Since neither of these
 
208
        modules are volatile <i>(see above)</i> the classes may be imported
 
209
        directly into the user's namespace and not cause confusion.
 
210
      </p>
 
211
 
 
212
      <h3>Methods</h3>
 
213
      <p>
 
214
        Methods should be in mixed case, with the first letter lower case, each
 
215
        word separated by having its first letter capitalized.  For example,
 
216
        "someMethodName", "method".
 
217
      </p>
 
218
      <p>
 
219
        Sometimes, a class will dispatch to a specialized sort of method using
 
220
        its name; for example, twisted.reflect.Accessor.  In those cases, the
 
221
        type of method should be a prefix in all lower-case with a trailing
 
222
        underscore, so method names will have an underscore in them.  For
 
223
        example, "get_someAttribute".  Underscores in method names in twisted
 
224
        code are therefore expected to have some semantic associated with them.
 
225
      </p>
 
226
      
 
227
      <h3>Functions</h3>
 
228
      <p>
 
229
        Functions should be named similiarly to methods.
 
230
      </p>
 
231
      <h3>Attributes</h3>
 
232
      <p>
 
233
        Attributes should be named similarly to functions and methods.
 
234
        Attributes should be named descriptively; attribute names like
 
235
        <code>mode</code>, <code>type</code>, and <code>buf</code> are
 
236
        generally discouraged.  Instead, use <code>displayMode</code>,
 
237
        <code>playerType</code>, or <code>inputBuffer</code>.
 
238
      </p>
 
239
      <p>
 
240
        Do not use Python's "private" attribute syntax; prefix non-public
 
241
        attributes with a single leading underscore.  Since several classes
 
242
        have the same name in Twisted, and they are distinguished by which
 
243
        package they come from, Python's double-underscore name mangling will
 
244
        not work reliably in some cases.  Also, name-mangled private variables
 
245
        are more difficult to address when unit testing or persisting a class.
 
246
      </p>
 
247
      <p>
 
248
        An attribute (or function, method or class) should be considered private
 
249
        when one or more of the following conditions are true:
 
250
        <ul>
 
251
          <li>The attribute represents intermediate state which is not always
 
252
          kept up-to-date.</li>
 
253
 
 
254
          <li>Referring to the contents of the attribute or otherwise
 
255
          maintaining a reference to it may cause resources to leak.</li>
 
256
 
 
257
          <li>Assigning to the attribute will break internal assumptions.</li>
 
258
          
 
259
          <li>The attribute is part of a known-to-be-sub-optimal interface and
 
260
          will certainly be removed in a future release.</li>
 
261
        </ul>
 
262
      </p>
 
263
      <h3>Database</h3>
 
264
      <p>
 
265
        Database tables will be named with plural nouns.
 
266
      </p>
 
267
      <p>
 
268
        Database columns will be named with underscores between words, all
 
269
        lower case, since most databases do not distinguish between case.
 
270
      </p>
 
271
      <p>
 
272
        Any attribute, method argument, or method name that corresponds
 
273
        <em>directly</em> to a column in the database will be named exactly the
 
274
        same as that column, regardless of other coding conventions surrounding
 
275
        that circumstance.
 
276
      </p>
 
277
      <p>
 
278
        All SQL keywords should be in upper case.
 
279
      </p>
 
280
      <h3>C Code</h3>
 
281
      <p>
 
282
        Wherever possible, C code should be optional, and the default python
 
283
        implementation should be maintained in tandem with it.  C code should
 
284
        be strict ANSI C, and <strong>must</strong> build using GCC as well as
 
285
        Visual Studio for Windows, and really shouldn't have any problems with
 
286
        other compilers either.  Don't do anything tricky.
 
287
      </p>
 
288
      <p>
 
289
        C code should only be used for efficiency, not for binding to external
 
290
        libraries.  If your particular code is not frequently run, write it in
 
291
        Python.  If you require the use of an external library, develop a
 
292
        separate, external bindings package and make your twisted code depend
 
293
        on it.
 
294
      </p>
 
295
      <h3>Recommendations</h3>
 
296
      <p>
 
297
        These things aren't necessarily standardizeable (in that code can't be
 
298
        easily checked for compliance) but are a good idea to keep in mind
 
299
        while working on Twisted.
 
300
      </p>
 
301
      <p>
 
302
        If you're going to work on a fragment of the Twisted codebase, please
 
303
        consider finding a way that you would *use* such a fragment in daily
 
304
        life.  I use the Twisted Web server on the main TML website, and aside
 
305
        from being good PR, this encourages you to actively maintain and
 
306
        improve your code, as the little everyday issues with using it become
 
307
        apparent.
 
308
      </p>
 
309
      <p>
 
310
        Twisted is a <strong>big</strong> codebase!  If you're refactoring
 
311
        something, please make sure to recursively grep for the names of
 
312
        functions you're changing.  You may be surprised to learn where
 
313
        something is called.  Especially if you are moving or renaming a
 
314
        function, class, method, or module, make sure that it won't instantly
 
315
        break other code.
 
316
      </p>
 
317
    <hr>
 
318
    <address><a href="mailto:glyph@helix.twistedmatrix.com">Glyph Lefkowitz</a></address>
 
319
<!-- Created: Thu Apr 26 07:53:26 CDT 2001 -->
 
320
<!-- hhmts start -->
 
321
Last modified: Fri Jan 25 18:04:28 CST 2002
 
322
<!-- hhmts end -->
 
323
  </body>
 
324
</html>