| 1 | <?xml version="1.0"?> |
|---|
| 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
|---|
| 3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|---|
| 4 | |
|---|
| 5 | <html xmlns="http://www.w3.org/1999/xhtml"> |
|---|
| 6 | <head> |
|---|
| 7 | <title>Twisted Coding Standard</title> |
|---|
| 8 | </head> |
|---|
| 9 | |
|---|
| 10 | <body> |
|---|
| 11 | <h1>Twisted Coding Standard</h1> |
|---|
| 12 | |
|---|
| 13 | <h2>Naming</h2> |
|---|
| 14 | |
|---|
| 15 | <p>Try to choose names which are both easy to remember and |
|---|
| 16 | meaningful. Some silliness is OK at the module naming level |
|---|
| 17 | (see <code class="API">twisted.spread</code>...) but when |
|---|
| 18 | choosing class names, be as precise as possible.</p> |
|---|
| 19 | |
|---|
| 20 | <p>Try to avoid overloaded terms. This rule is often broken, |
|---|
| 21 | since it is incredibly difficult, as most normal words have |
|---|
| 22 | already been taken by some other software. More importantly, |
|---|
| 23 | try to avoid meaningless words. In particular, words like |
|---|
| 24 | <q>handler</q>, <q>processor</q>, <q>engine</q>, <q>manager</q> |
|---|
| 25 | and <q>component</q> don't really indicate what something does, |
|---|
| 26 | only that it does <em>something</em>.</p> |
|---|
| 27 | |
|---|
| 28 | <p>Use American spelling in both names and docstrings. For compound |
|---|
| 29 | technical terms such as 'filesystem', use a non-hyphenated spelling in |
|---|
| 30 | both docstrings and code in order to avoid unnecessary |
|---|
| 31 | capitalization.</p> |
|---|
| 32 | |
|---|
| 33 | <h2>Testing</h2> |
|---|
| 34 | |
|---|
| 35 | <h3>Overview</h3> |
|---|
| 36 | |
|---|
| 37 | <p>Twisted development should always be |
|---|
| 38 | <a href="http://en.wikipedia.org/wiki/Test-driven_development"> |
|---|
| 39 | test-driven</a>. The complete test suite in the head of the SVN trunk is required to |
|---|
| 40 | be passing on <a href="http://buildbot.twistedmatrix.com/supported"> |
|---|
| 41 | supported platforms</a> at all times. Regressions in the test suite |
|---|
| 42 | are addressed by reverting whatever revisions introduced them. For |
|---|
| 43 | complete documentation about testing Twisted itself, refer to the |
|---|
| 44 | <a href="test-standard.xhtml">Test Standard</a>. What follows is |
|---|
| 45 | intended to be a synopsis of the most important points.</p> |
|---|
| 46 | |
|---|
| 47 | <h3>Test Suite</h3> |
|---|
| 48 | |
|---|
| 49 | <p>The Twisted test suite is spread across many subpackages of the |
|---|
| 50 | <code>twisted</code> package. Many older tests are in |
|---|
| 51 | <code>twisted.test</code>. Others can be found at places such as |
|---|
| 52 | <code>twisted.web.test</code> (for <code>twisted.web</code> tests) |
|---|
| 53 | or <code>twisted.internet.test</code> (for <code>twisted.internet</code> |
|---|
| 54 | tests). The latter arrangement, <code>twisted.somepackage.test</code>, |
|---|
| 55 | is preferred for new tests except when a test module already exists in |
|---|
| 56 | <code>twisted.test</code>. |
|---|
| 57 | </p> |
|---|
| 58 | |
|---|
| 59 | <p> |
|---|
| 60 | Parts of the Twisted test suite may serve as good examples of how to |
|---|
| 61 | write tests for Twisted or for Twisted-based libraries (newer parts of |
|---|
| 62 | the test suite are generally better examples than older parts - check |
|---|
| 63 | when the code you are looking at was written before you use it as an |
|---|
| 64 | example of what you should write). The names of test modules should |
|---|
| 65 | begin with <code>test_</code> so that they are automatically discoverable by |
|---|
| 66 | test runners such as Trial. Twisted's unit tests are written using |
|---|
| 67 | <code class="API">twisted.trial</code>, an xUnit library which has been |
|---|
| 68 | extensively customized for use in testing Twisted and Twisted-based |
|---|
| 69 | libraries.</p> |
|---|
| 70 | |
|---|
| 71 | <p>Implementation (ie, non-test) source files should begin with a |
|---|
| 72 | <code>test-case-name</code> tag which gives the name of any test |
|---|
| 73 | modules or packages which exercise them. This lets tools discover a |
|---|
| 74 | subset of the entire test suite which they can run first to find tests |
|---|
| 75 | which might be broken by a particular change.</p> |
|---|
| 76 | |
|---|
| 77 | <p>It is strongly suggested that developers learn to use Emacs, and use |
|---|
| 78 | the <code>twisted-dev.el</code> file included in |
|---|
| 79 | <a href="http://launchpad.net/twisted-emacs">twisted-emacs</a> |
|---|
| 80 | to bind the F9 key to <q>run unit tests</q> and bang on it |
|---|
| 81 | frequently. Support for other editors is unavailable at this time but |
|---|
| 82 | we would love to provide it.</p> |
|---|
| 83 | |
|---|
| 84 | <p>To run the whole Twisted test without using emacs, use trial:</p> |
|---|
| 85 | |
|---|
| 86 | <pre class="shell"> |
|---|
| 87 | $ bin/trial twisted |
|---|
| 88 | </pre> |
|---|
| 89 | |
|---|
| 90 | <p>To run an individual test module, such as |
|---|
| 91 | <code>twisted/mail/test/test_pop3.py</code>, specify the module |
|---|
| 92 | name:</p> |
|---|
| 93 | |
|---|
| 94 | <pre class="shell"> |
|---|
| 95 | $ bin/trial twisted.mail.test.test_pop3 |
|---|
| 96 | </pre> |
|---|
| 97 | |
|---|
| 98 | <p>To run the tests associated with a particular implementation file, |
|---|
| 99 | such as <code>twisted/mail/pop3.py</code>, use the |
|---|
| 100 | <code>testmodule</code> option:</p> |
|---|
| 101 | |
|---|
| 102 | <pre class="shell"> |
|---|
| 103 | $ bin/trial twisted/mail/pop3.py |
|---|
| 104 | </pre> |
|---|
| 105 | |
|---|
| 106 | <p>All unit test methods should have docstrings specifying at a high |
|---|
| 107 | level the intent of the test. That is, a description that users of the |
|---|
| 108 | method would understand.</p> |
|---|
| 109 | |
|---|
| 110 | <p>If you modify, or write a new, HOWTO, please read the <a |
|---|
| 111 | href="http://twistedmatrix.com/trac/wiki/TwistedLore">Lore</a> |
|---|
| 112 | documentation to learn how to format the docs.</p> |
|---|
| 113 | |
|---|
| 114 | <h2>Copyright Header</h2> |
|---|
| 115 | |
|---|
| 116 | <p>Whenever a new file is added to the repository, add the following |
|---|
| 117 | license header at the top of the file:</p> |
|---|
| 118 | |
|---|
| 119 | <pre class="python"> |
|---|
| 120 | # Copyright (c) Twisted Matrix Laboratories. |
|---|
| 121 | # See LICENSE for details. |
|---|
| 122 | </pre> |
|---|
| 123 | |
|---|
| 124 | <p>When you update existing files, if there is no copyright header, add |
|---|
| 125 | one.</p> |
|---|
| 126 | |
|---|
| 127 | <h2>Whitespace</h2> |
|---|
| 128 | |
|---|
| 129 | <p>Indentation is 4 spaces per indent. Tabs are not allowed. It |
|---|
| 130 | is preferred that every block appear on a new line, so that |
|---|
| 131 | control structure indentation is always visible.</p> |
|---|
| 132 | |
|---|
| 133 | <p>Lines are flowed at 79 columns. They must not have trailing |
|---|
| 134 | whitespace. Long lines must be wrapped using implied line continuation |
|---|
| 135 | inside parentheses; backslashes aren't allowed. To handle long import |
|---|
| 136 | lines, please repeat the import like this:</p> |
|---|
| 137 | |
|---|
| 138 | <pre class="python"> |
|---|
| 139 | from very.long.package import foo, bar, baz |
|---|
| 140 | from very.long.package import qux, quux, quuux |
|---|
| 141 | </pre> |
|---|
| 142 | |
|---|
| 143 | <p>Top-level classes and functions must be separated with 3 blank lines, |
|---|
| 144 | and class-level functions with 2 blank lines. The control-L (i.e. ^L) form |
|---|
| 145 | feed character must not be used.</p> |
|---|
| 146 | |
|---|
| 147 | <h2>Modules</h2> |
|---|
| 148 | |
|---|
| 149 | <p>Modules must be named in all lower-case, preferably short, |
|---|
| 150 | single words. If a module name contains multiple words, they |
|---|
| 151 | may be separated by underscores or not separated at all.</p> |
|---|
| 152 | |
|---|
| 153 | <p>Modules must have a copyright message, a docstring and a |
|---|
| 154 | reference to a test module that contains the bulk of its tests. |
|---|
| 155 | Use this template:</p> |
|---|
| 156 | |
|---|
| 157 | <a href="../listings/new_module_template.py" class="py-listing">new_module_template.py</a> |
|---|
| 158 | |
|---|
| 159 | <p>In most cases, modules should contain more than one class, |
|---|
| 160 | function, or method; if a module contains only one object, |
|---|
| 161 | consider refactoring to include more related functionality in |
|---|
| 162 | that module.</p> |
|---|
| 163 | |
|---|
| 164 | <p>Depending on the situation, it is acceptable to have imports that |
|---|
| 165 | look like this: |
|---|
| 166 | <pre class="python">from twisted.internet.defer import Deferred</pre> |
|---|
| 167 | or like this: |
|---|
| 168 | <pre class="python">from twisted.internet import defer</pre> |
|---|
| 169 | That is, modules should import <em>modules</em> or <em>classes and |
|---|
| 170 | functions</em>, but not <em>packages</em>.</p> |
|---|
| 171 | |
|---|
| 172 | <p>Wildcard import syntax may not be used by code in Twisted. These |
|---|
| 173 | imports lead to code which is difficult to read and maintain by |
|---|
| 174 | introducing complexity which strains human readers and automated tools |
|---|
| 175 | alike. If you find yourself with many imports to make from a single |
|---|
| 176 | module and wish to save typing, consider importing the module itself, |
|---|
| 177 | rather than its attributes.</p> |
|---|
| 178 | |
|---|
| 179 | <p><em>Relative imports</em> (or <em>sibling imports</em>) may not be |
|---|
| 180 | used by code in Twisted. Relative imports allow certain circularities |
|---|
| 181 | to be introduced which can ultimately lead to unimportable modules or |
|---|
| 182 | duplicate instances of a single module. Relative imports also make the |
|---|
| 183 | task of refactoring more difficult.</p> |
|---|
| 184 | |
|---|
| 185 | <p>In case of local names conflicts due to import, use the <code>as</code> |
|---|
| 186 | syntax, for example: |
|---|
| 187 | <pre class="python">from twisted.trial import util as trial_util</pre></p> |
|---|
| 188 | |
|---|
| 189 | <p>The encoding must always be ASCII, so no coding cookie is necessary.</p> |
|---|
| 190 | |
|---|
| 191 | <h2>Packages</h2> |
|---|
| 192 | |
|---|
| 193 | <p>Package names should follow the same conventions as module |
|---|
| 194 | names. All modules must be encapsulated in some package. Nested |
|---|
| 195 | packages may be used to further organize related modules.</p> |
|---|
| 196 | |
|---|
| 197 | <p><code>__init__.py</code> must never contain anything other than a |
|---|
| 198 | docstring and (optionally) an <code>__all__</code> attribute. Packages are |
|---|
| 199 | not modules and should be treated differently. This rule may be |
|---|
| 200 | broken to preserve backwards compatibility if a module is made |
|---|
| 201 | into a nested package as part of a refactoring.</p> |
|---|
| 202 | |
|---|
| 203 | <p>If you wish to promote code from a module to a package, for |
|---|
| 204 | example, to break a large module out into several smaller |
|---|
| 205 | files, the accepted way to do this is to promote from within |
|---|
| 206 | the module. For example,</p> |
|---|
| 207 | |
|---|
| 208 | <pre class="python"> |
|---|
| 209 | # parent/ |
|---|
| 210 | # --- __init__.py --- |
|---|
| 211 | import child |
|---|
| 212 | |
|---|
| 213 | # --- child.py --- |
|---|
| 214 | import parent |
|---|
| 215 | class Foo: |
|---|
| 216 | pass |
|---|
| 217 | parent.Foo = Foo |
|---|
| 218 | </pre> |
|---|
| 219 | |
|---|
| 220 | <p>Every package should be added to the list in |
|---|
| 221 | <code class="shell">setup.py</code>.</p> |
|---|
| 222 | |
|---|
| 223 | <p>Packages must not depend circularly upon each other. To simplify |
|---|
| 224 | maintaining this state, packages must also not import each other |
|---|
| 225 | circularly. While this applies to all packages within Twisted, one |
|---|
| 226 | <code>twisted.python</code> deserves particular attention, as it may |
|---|
| 227 | not depend on any other Twisted package.</p> |
|---|
| 228 | |
|---|
| 229 | <h2>String Formatting Operations</h2> |
|---|
| 230 | |
|---|
| 231 | <p>When using <a |
|---|
| 232 | href="http://docs.python.org/lib/typesseq-strings.html">string formatting |
|---|
| 233 | operations</a> like <code>formatString % values</code> you should always |
|---|
| 234 | use a tuple if you're using non-mapping <code>values</code>. This is to |
|---|
| 235 | avoid unexpected behavior when you think you're passing in a single value, |
|---|
| 236 | but the value is unexpectedly a tuple, e.g.:</p> |
|---|
| 237 | |
|---|
| 238 | <pre class="python"> |
|---|
| 239 | def foo(x): |
|---|
| 240 | return "Hi %s\n" % x |
|---|
| 241 | </pre> |
|---|
| 242 | |
|---|
| 243 | <p>The example shows you can pass in <code>foo("foo")</code> or |
|---|
| 244 | <code>foo(3)</code> fine, but if you pass in <code>foo((1,2))</code>, |
|---|
| 245 | it raises a <code>TypeError</code>. You should use this instead:</p> |
|---|
| 246 | |
|---|
| 247 | <pre class="python"> |
|---|
| 248 | def foo(x): |
|---|
| 249 | return "Hi %s\n" % (x,) |
|---|
| 250 | </pre> |
|---|
| 251 | |
|---|
| 252 | <h2>Docstrings</h2> |
|---|
| 253 | |
|---|
| 254 | <p>Docstrings should always be used to describe the |
|---|
| 255 | purpose of methods, functions, classes, and modules.</p> |
|---|
| 256 | |
|---|
| 257 | <p>Docstrings are <em>never</em> to be used to provide semantic |
|---|
| 258 | information about an object; this rule may be violated if the |
|---|
| 259 | code in question is to be used in a system where this is a |
|---|
| 260 | requirement (such as Zope).</p> |
|---|
| 261 | |
|---|
| 262 | <p>Docstrings should be indented to the level of the code they |
|---|
| 263 | are documenting.</p> |
|---|
| 264 | |
|---|
| 265 | <p>Docstrings should be triple-quoted. The opening and the closing of the |
|---|
| 266 | docstrings should be on a line by themselves. For example: |
|---|
| 267 | <pre class="python"> |
|---|
| 268 | class Ninja(object): |
|---|
| 269 | """ |
|---|
| 270 | A L{Ninja} is a warrior specializing in various unorthodox arts of war. |
|---|
| 271 | """ |
|---|
| 272 | def attack(self, someone): |
|---|
| 273 | """ |
|---|
| 274 | Attack C{someone} with this L{Ninja}'s shuriken. |
|---|
| 275 | """ |
|---|
| 276 | </pre> |
|---|
| 277 | </p> |
|---|
| 278 | |
|---|
| 279 | <p>Docstrings should be written in epytext format; more |
|---|
| 280 | documentation is available in the |
|---|
| 281 | <a href="http://epydoc.sourceforge.net/manual-epytext.html" |
|---|
| 282 | >Epytext Markup Language documentation</a>.</p> |
|---|
| 283 | |
|---|
| 284 | <p>Additionally, to accommodate emacs users, single quotes of the type of |
|---|
| 285 | the docstring's triple-quote should be escaped. This will prevent font-lock from |
|---|
| 286 | accidentally fontifying large portions of the file as a string.</p> |
|---|
| 287 | |
|---|
| 288 | <p>For example,</p> |
|---|
| 289 | <pre class="python"> |
|---|
| 290 | def foo2bar(f): |
|---|
| 291 | """ |
|---|
| 292 | Convert L{foo}s to L{bar}s. |
|---|
| 293 | |
|---|
| 294 | A function that should be used when you have a C{foo} but you want a |
|---|
| 295 | C{bar}; note that this is a non-destructive operation. If this method |
|---|
| 296 | can't convert the C{foo} to a C{bar} it will raise a L{FooException}. |
|---|
| 297 | |
|---|
| 298 | @param f: C{foo} |
|---|
| 299 | @type f: str |
|---|
| 300 | |
|---|
| 301 | For example:: |
|---|
| 302 | |
|---|
| 303 | import wombat |
|---|
| 304 | def sample(something): |
|---|
| 305 | f = something.getFoo() |
|---|
| 306 | f.doFooThing() |
|---|
| 307 | b = wombat.foo2bar(f) |
|---|
| 308 | b.doBarThing() |
|---|
| 309 | return b |
|---|
| 310 | |
|---|
| 311 | """ |
|---|
| 312 | # Optionally, actual code can go here. |
|---|
| 313 | </pre> |
|---|
| 314 | |
|---|
| 315 | <h2>Comments</h2> |
|---|
| 316 | |
|---|
| 317 | <p>Comments marked with XXX or TODO must contain a reference to the |
|---|
| 318 | associated ticket.</p> |
|---|
| 319 | |
|---|
| 320 | <h2>Versioning</h2> |
|---|
| 321 | |
|---|
| 322 | <p>The API documentation should be marked up with version information. |
|---|
| 323 | When a new API is added the class should be marked with the epytext |
|---|
| 324 | <code class="shell">@since:</code> field including the version number when |
|---|
| 325 | the change was introduced, eg. <code class="shell">@since: 8.1</code>.</p> |
|---|
| 326 | |
|---|
| 327 | <h2>Scripts</h2> |
|---|
| 328 | |
|---|
| 329 | <p>For each <q>script</q>, that is, a program you expect a Twisted user |
|---|
| 330 | to run from the command-line, the following things must be done:</p> |
|---|
| 331 | |
|---|
| 332 | <ol> |
|---|
| 333 | <li>Write a module in <code class="API">twisted.scripts</code> |
|---|
| 334 | which contains a callable global named <code>run</code>. This |
|---|
| 335 | will be called by the command line part with no arguments (it |
|---|
| 336 | will usually read <code>sys.argv</code>). Feel free to write more |
|---|
| 337 | functions or classes in this module, if you feel they are useful |
|---|
| 338 | to others.</li> |
|---|
| 339 | |
|---|
| 340 | <li>Create a file which contains a shebang line for Python. For Twisted |
|---|
| 341 | Core, this file should be placed in the <code>bin/</code> directory; for |
|---|
| 342 | example, <code>bin/twistd</code>. For sub-projects, it should be placed |
|---|
| 343 | in <code>bin/<subproject></code>; for example, the key-generation tool |
|---|
| 344 | for the Conch sub-project is in <code>bin/conch/ckeygen</code>. |
|---|
| 345 | <pre class="python"> |
|---|
| 346 | #!/usr/bin/env python |
|---|
| 347 | </pre></li> |
|---|
| 348 | |
|---|
| 349 | <p>To make sure that the script is portable across different UNIX like |
|---|
| 350 | operating systems we use the <code>/usr/bin/env</code> command. The env |
|---|
| 351 | command allows you to run a program in a modified environment. That way |
|---|
| 352 | you don't have to search for a program via the <code>PATH</code> environment |
|---|
| 353 | variable. This makes the script more portable but note that it is not a |
|---|
| 354 | foolproof method. Always make sure that <code>/usr/bin/env</code> exists or |
|---|
| 355 | use a softlink/symbolic link to point it to the correct path. Python's |
|---|
| 356 | distutils will rewrite the shebang line upon installation so this policy |
|---|
| 357 | only covers the source files in version control.</p> |
|---|
| 358 | |
|---|
| 359 | <li>For core scripts, add this Twisted running-from-SVN header: |
|---|
| 360 | <pre class="python"> |
|---|
| 361 | import sys |
|---|
| 362 | try: |
|---|
| 363 | import _preamble |
|---|
| 364 | except ImportError: |
|---|
| 365 | sys.clear_exc() |
|---|
| 366 | </pre> |
|---|
| 367 | |
|---|
| 368 | Or for sub-project scripts, add a modified version which also adjusts <code>sys.path</code>: |
|---|
| 369 | <pre class="python"> |
|---|
| 370 | import sys, os |
|---|
| 371 | extra = os.path.dirname(os.path.dirname(sys.argv[0])) |
|---|
| 372 | sys.path.insert(0, extra) |
|---|
| 373 | try: |
|---|
| 374 | import _preamble |
|---|
| 375 | except ImportError: |
|---|
| 376 | sys.clear_exc() |
|---|
| 377 | sys.path.remove(extra) |
|---|
| 378 | </pre></li> |
|---|
| 379 | |
|---|
| 380 | <li>And end with: |
|---|
| 381 | <pre class="python"> |
|---|
| 382 | from twisted.scripts.yourmodule import run |
|---|
| 383 | run() |
|---|
| 384 | </pre></li> |
|---|
| 385 | |
|---|
| 386 | <li>Write a manpage and add it to the <code class="shell">man</code> folder |
|---|
| 387 | of a subproject's <code class="shell">doc</code> folder. On Debian systems |
|---|
| 388 | you can find a skeleton example of a manpage in |
|---|
| 389 | <code>/usr/share/doc/man-db/examples/manpage.example</code>.</li> |
|---|
| 390 | </ol> |
|---|
| 391 | |
|---|
| 392 | <p>This will insure your program will work correctly for users of SVN, |
|---|
| 393 | Windows releases and Debian packages.</p> |
|---|
| 394 | |
|---|
| 395 | <h2>Examples</h2> |
|---|
| 396 | |
|---|
| 397 | <p>For example scripts you expect a Twisted user |
|---|
| 398 | to run from the command-line, add this Python shebang line at the top |
|---|
| 399 | of the file:</p> |
|---|
| 400 | <pre class="python"> |
|---|
| 401 | #!/usr/bin/env python |
|---|
| 402 | </pre> |
|---|
| 403 | |
|---|
| 404 | <h2>Standard Library Extension Modules</h2> |
|---|
| 405 | |
|---|
| 406 | <p>When using the extension version of a module for which there is also |
|---|
| 407 | a Python version, place the import statement inside a try/except block, |
|---|
| 408 | and import the Python version if the import fails. This allows code to |
|---|
| 409 | work on platforms where the extension version is not available. For |
|---|
| 410 | example: |
|---|
| 411 | |
|---|
| 412 | <pre class="python"> |
|---|
| 413 | try: |
|---|
| 414 | import cPickle as pickle |
|---|
| 415 | except ImportError: |
|---|
| 416 | import pickle |
|---|
| 417 | </pre> |
|---|
| 418 | |
|---|
| 419 | Use the "as" syntax of the import statement as well, to set |
|---|
| 420 | the name of the extension module to the name of the Python module.</p> |
|---|
| 421 | |
|---|
| 422 | <p>Some modules don't exist across all supported Python versions. For |
|---|
| 423 | example, Python 2.3's <code>sets</code> module was deprecated in Python 2.6 |
|---|
| 424 | in favor of the <code>set</code> and <code>frozenset</code> builtins. When |
|---|
| 425 | you need to use sets or frozensets in your code, please use |
|---|
| 426 | the <code>set</code> and <code>frozenset</code> provided |
|---|
| 427 | by <code class="API">twisted.python.compat</code>. There are some |
|---|
| 428 | differences between <code>sets.Set</code> and <code>set</code>, that are |
|---|
| 429 | explained in the <a href="http://www.python.org/dev/peps/pep-0218/">set |
|---|
| 430 | PEP</a>. Please be sure to not rely on the behavior of one or the other |
|---|
| 431 | implementation.</p> |
|---|
| 432 | |
|---|
| 433 | <h2>Classes</h2> |
|---|
| 434 | |
|---|
| 435 | <p>Classes are to be named in mixed case, with the first letter |
|---|
| 436 | capitalized; each word separated by having its first letter |
|---|
| 437 | capitalized. Acronyms should be capitalized in their entirety. |
|---|
| 438 | Class names should not be prefixed with the name of the module they are |
|---|
| 439 | in. Examples of classes meeting this criteria:</p> |
|---|
| 440 | |
|---|
| 441 | <ul> |
|---|
| 442 | <li>twisted.spread.pb.ViewPoint</li> |
|---|
| 443 | <li>twisted.parser.patterns.Pattern</li> |
|---|
| 444 | </ul> |
|---|
| 445 | |
|---|
| 446 | <p>Examples of classes <strong>not</strong> meeting this criteria:</p> |
|---|
| 447 | |
|---|
| 448 | <ul> |
|---|
| 449 | <li>event.EventHandler</li> |
|---|
| 450 | <li>main.MainGadget</li> |
|---|
| 451 | </ul> |
|---|
| 452 | |
|---|
| 453 | <p>An effort should be made to prevent class names from clashing |
|---|
| 454 | with each other between modules, to reduce the need for |
|---|
| 455 | qualification when importing. For example, a Service subclass |
|---|
| 456 | for Forums might be named twisted.forum.service.ForumService, |
|---|
| 457 | and a Service subclass for Words might be |
|---|
| 458 | twisted.words.service.WordsService. Since neither of these |
|---|
| 459 | modules are volatile <em>(see above)</em> the classes may be |
|---|
| 460 | imported directly into the user's namespace and not cause |
|---|
| 461 | confusion.</p> |
|---|
| 462 | |
|---|
| 463 | <h3>New-style Classes</h3> |
|---|
| 464 | |
|---|
| 465 | <p>Classes and instances in Python come in two flavors: old-style or |
|---|
| 466 | classic, and new-style. Up to Python 2.1, old-style classes were the |
|---|
| 467 | only flavour available to the user, new-style classes were introduced |
|---|
| 468 | in Python 2.2 to unify classes and types. All classes added to Twisted |
|---|
| 469 | should be written as new-style classes. If <code class="python">x</code> |
|---|
| 470 | is an instance of a new-style class, then <code class="python">type(x)</code> |
|---|
| 471 | is the same as <code class="python">x.__class__</code>.</p> |
|---|
| 472 | |
|---|
| 473 | <h2>Methods</h2> |
|---|
| 474 | |
|---|
| 475 | <p>Methods should be in mixed case, with the first letter lower |
|---|
| 476 | case, each word separated by having its first letter |
|---|
| 477 | capitalized. For example, <code>someMethodName</code>, |
|---|
| 478 | <code>method</code>.</p> |
|---|
| 479 | |
|---|
| 480 | <p>Sometimes, a class will dispatch to a specialized sort of |
|---|
| 481 | method using its name; for example, twisted.reflect.Accessor. |
|---|
| 482 | In those cases, the type of method should be a prefix in all |
|---|
| 483 | lower-case with a trailing underscore, so method names will |
|---|
| 484 | have an underscore in them. For example, <code>get_someAttribute</code>. |
|---|
| 485 | Underscores in method names in twisted code are therefore |
|---|
| 486 | expected to have some semantic associated with them.</p> |
|---|
| 487 | |
|---|
| 488 | <p>Some methods, in particular <code>addCallback</code> and its |
|---|
| 489 | cousins return self to allow for chaining calls. In this case, |
|---|
| 490 | wrap the chain in parenthesis, and start each chained call on |
|---|
| 491 | a separate line, for example:</p> |
|---|
| 492 | |
|---|
| 493 | <pre class="python"> |
|---|
| 494 | return (foo() |
|---|
| 495 | .addCallback(bar) |
|---|
| 496 | .addCallback(thud) |
|---|
| 497 | .addCallback(wozers)) |
|---|
| 498 | </pre> |
|---|
| 499 | |
|---|
| 500 | <h2>Callback Arguments</h2> |
|---|
| 501 | |
|---|
| 502 | <p>There are several methods whose purpose is to help the user set up |
|---|
| 503 | callback functions, for example <code class="API" |
|---|
| 504 | base="twisted.internet.defer">Deferred.addCallback</code> or the |
|---|
| 505 | reactor's <code class="API" |
|---|
| 506 | base="twisted.internet.base.ReactorBase">callLater</code> method. To make |
|---|
| 507 | access to the callback as transparent as possible, most of these methods |
|---|
| 508 | use <code class="python">**kwargs</code> to capture arbitrary arguments |
|---|
| 509 | that are destined for the user's callback. This allows the call to the |
|---|
| 510 | setup function to look very much like the eventual call to the target |
|---|
| 511 | callback function.</p> |
|---|
| 512 | |
|---|
| 513 | <p>In these methods, take care to not have other argument names that will |
|---|
| 514 | <q>steal</q> the user's callback's arguments. When sensible, prefix these |
|---|
| 515 | <q>internal</q> argument names with an underscore. For example, <code |
|---|
| 516 | class="API" base="twisted.spread.pb">RemoteReference.callRemote</code> is |
|---|
| 517 | meant to be called like this:</p> |
|---|
| 518 | |
|---|
| 519 | <pre class="python"> |
|---|
| 520 | myref.callRemote("addUser", "bob", "555-1212") |
|---|
| 521 | |
|---|
| 522 | # on the remote end, the following method is invoked: |
|---|
| 523 | def addUser(name, phone): |
|---|
| 524 | ... |
|---|
| 525 | </pre> |
|---|
| 526 | |
|---|
| 527 | <p>where <q>addUser</q> is the remote method name. The user might also |
|---|
| 528 | choose to call it with named parameters like this:</p> |
|---|
| 529 | |
|---|
| 530 | <pre class="python"> |
|---|
| 531 | myref.callRemote("addUser", name="bob", phone="555-1212") |
|---|
| 532 | </pre> |
|---|
| 533 | |
|---|
| 534 | <p>In this case, <code>callRemote</code> (and any code that uses the |
|---|
| 535 | <code class="python">**kwargs</code> syntax) must be careful to not use |
|---|
| 536 | <q>name</q>, <q>phone</q>, or any other name that might overlap with |
|---|
| 537 | a user-provided named parameter. Therefore, <code>callRemote</code> is |
|---|
| 538 | implemented with the following signature:</p> |
|---|
| 539 | |
|---|
| 540 | <pre class="python"> |
|---|
| 541 | class SomeClass(object): |
|---|
| 542 | def callRemote(self, _name, *args, **kw): |
|---|
| 543 | ... |
|---|
| 544 | </pre> |
|---|
| 545 | |
|---|
| 546 | <p>Do whatever you can to reduce user confusion. It may also be |
|---|
| 547 | appropriate to <code class="python">assert</code> that the kwargs |
|---|
| 548 | dictionary does not contain parameters with names that will eventually |
|---|
| 549 | cause problems.</p> |
|---|
| 550 | |
|---|
| 551 | |
|---|
| 552 | <h2>Special Methods</h2> |
|---|
| 553 | |
|---|
| 554 | <p>The augmented assignment protocol, defined by <code |
|---|
| 555 | class="python">__iadd__</code> and other |
|---|
| 556 | similarly named methods, can be used to allow objects to be modified in |
|---|
| 557 | place or to rebind names if an object is immutable -- both through use |
|---|
| 558 | of the same operator. This can lead to confusing code, which in turn |
|---|
| 559 | leads to buggy code. For this reason, methods of the augmented |
|---|
| 560 | assignment protocol should not be used in Twisted.</p> |
|---|
| 561 | |
|---|
| 562 | <h2>Functions</h2> |
|---|
| 563 | |
|---|
| 564 | <p>Functions should be named similiarly to methods.</p> |
|---|
| 565 | |
|---|
| 566 | <p>Functions or methods which are responding to events to |
|---|
| 567 | complete a callback or errback should be named <code>_cbMethodName</code> or |
|---|
| 568 | <code>_ebMethodName</code>, in order to distinguish them from normal |
|---|
| 569 | methods.</p> |
|---|
| 570 | |
|---|
| 571 | <h2>Attributes</h2> |
|---|
| 572 | |
|---|
| 573 | <p>Attributes should be named similarly to functions and |
|---|
| 574 | methods. Attributes should be named descriptively; attribute |
|---|
| 575 | names like <code>mode</code>, <code>type</code>, and |
|---|
| 576 | <code>buf</code> are generally discouraged. Instead, use |
|---|
| 577 | <code>displayMode</code>, <code>playerType</code>, or |
|---|
| 578 | <code>inputBuffer</code>.</p> |
|---|
| 579 | |
|---|
| 580 | <p>Do not use Python's <q>private</q> attribute syntax; prefix |
|---|
| 581 | non-public attributes with a single leading underscore. Since |
|---|
| 582 | several classes have the same name in Twisted, and they are |
|---|
| 583 | distinguished by which package they come from, Python's |
|---|
| 584 | double-underscore name mangling will not work reliably in some |
|---|
| 585 | cases. Also, name-mangled private variables are more difficult |
|---|
| 586 | to address when unit testing or persisting a class.</p> |
|---|
| 587 | |
|---|
| 588 | <p>An attribute (or function, method or class) should be |
|---|
| 589 | considered private when one or more of the following conditions |
|---|
| 590 | are true:</p> |
|---|
| 591 | |
|---|
| 592 | <ul> |
|---|
| 593 | <li>The attribute represents intermediate state which is not |
|---|
| 594 | always kept up-to-date.</li> |
|---|
| 595 | |
|---|
| 596 | <li>Referring to the contents of the attribute or otherwise |
|---|
| 597 | maintaining a reference to it may cause resources to |
|---|
| 598 | leak.</li> |
|---|
| 599 | |
|---|
| 600 | <li>Assigning to the attribute will break internal |
|---|
| 601 | assumptions.</li> |
|---|
| 602 | |
|---|
| 603 | <li>The attribute is part of a known-to-be-sub-optimal |
|---|
| 604 | interface and will certainly be removed in a future |
|---|
| 605 | release.</li> |
|---|
| 606 | </ul> |
|---|
| 607 | |
|---|
| 608 | |
|---|
| 609 | <h2>Database</h2> |
|---|
| 610 | |
|---|
| 611 | <p>Database tables will be named with plural nouns.</p> |
|---|
| 612 | |
|---|
| 613 | <p>Database columns will be named with underscores between |
|---|
| 614 | words, all lower case, since most databases do not distinguish |
|---|
| 615 | between case.</p> |
|---|
| 616 | |
|---|
| 617 | <p>Any attribute, method argument, or method name that |
|---|
| 618 | corresponds <em>directly</em> to a column in the database will |
|---|
| 619 | be named exactly the same as that column, regardless of other |
|---|
| 620 | coding conventions surrounding that circumstance.</p> |
|---|
| 621 | |
|---|
| 622 | <p>All SQL keywords should be in upper case.</p> |
|---|
| 623 | |
|---|
| 624 | <h2>C Code</h2> |
|---|
| 625 | |
|---|
| 626 | <p>Wherever possible, C code should be optional, and the |
|---|
| 627 | default python implementation should be maintained in tandem |
|---|
| 628 | with it. C code should be strict ANSI C, and |
|---|
| 629 | <strong>must</strong> build using GCC as well as Visual Studio |
|---|
| 630 | for Windows, and really shouldn't have any problems with other |
|---|
| 631 | compilers either. Don't do anything tricky.</p> |
|---|
| 632 | |
|---|
| 633 | <p>C code should only be used for efficiency, not for binding |
|---|
| 634 | to external libraries. If your particular code is not |
|---|
| 635 | frequently run, write it in Python. If you require the use of |
|---|
| 636 | an external library, develop a separate, external bindings |
|---|
| 637 | package and make your twisted code depend on it.</p> |
|---|
| 638 | |
|---|
| 639 | <h2 id="commits">Commit Messages</h2> |
|---|
| 640 | |
|---|
| 641 | <p>The commit messages are being distributed in a myriad of ways. Because |
|---|
| 642 | of that, you need to observe a few simple rules when writing a commit |
|---|
| 643 | message.</p> |
|---|
| 644 | |
|---|
| 645 | <p>The first line of the message is being used as both the subject of |
|---|
| 646 | the commit email and the announcement on #twisted. Therefore, it should |
|---|
| 647 | be short (aim for < 80 characters) and descriptive -- and must be |
|---|
| 648 | able to stand alone (it is best if it is a complete sentence). The rest |
|---|
| 649 | of the e-mail should be separated with <em>hard line breaks</em> into |
|---|
| 650 | short lines (< 70 characters). This is free-format, so you can do |
|---|
| 651 | whatever you like here.</p> |
|---|
| 652 | |
|---|
| 653 | <p>Commit messages should be about <em>what</em>, not <em>how</em>: we can |
|---|
| 654 | get how from SVN diff. Explain reasons for commits, and what they |
|---|
| 655 | affect.</p> |
|---|
| 656 | |
|---|
| 657 | <p>Each commit should be a single logical change, which is internally |
|---|
| 658 | consistent. If you can't summarize your changes in one short line, this |
|---|
| 659 | is probably a sign that they should be broken into multiple checkins.</p> |
|---|
| 660 | |
|---|
| 661 | <h2>Source Control</h2> |
|---|
| 662 | |
|---|
| 663 | <p>Twisted currently uses Subversion for source control. All |
|---|
| 664 | development <strong>should</strong> occur using branches; when a task is |
|---|
| 665 | considered complete another Twisted developer may review it and if no |
|---|
| 666 | problems are found, it may be merged into trunk. The Twisted wiki has <a |
|---|
| 667 | href="http://twistedmatrix.com/trac/wiki/TwistedDevelopment">a start</a>. |
|---|
| 668 | Branches <strong>must</strong> be used for major development. Branches |
|---|
| 669 | should be managed using <a |
|---|
| 670 | href="http://divmod.org/trac/wiki/DivmodCombinator">Combinator</a> (but |
|---|
| 671 | if you can manage them in some other way without anyone noticing, knock |
|---|
| 672 | yourself out).</p> |
|---|
| 673 | |
|---|
| 674 | <p>Certain features of Subversion should be avoided.</p> |
|---|
| 675 | |
|---|
| 676 | <ul> |
|---|
| 677 | <li> |
|---|
| 678 | |
|---|
| 679 | <p>Do not set the <code class="shell">svn:ignore</code> property on any |
|---|
| 680 | file or directory. What you wish to ignore, others may wish to examine. |
|---|
| 681 | What others may wish you ignore, <em>you</em> may wish you examine. |
|---|
| 682 | <code class="shell"> svn:ignore </code> will affect everyone who uses |
|---|
| 683 | the repository, and so it is not the right mechanism to express personal |
|---|
| 684 | preferences.</p> |
|---|
| 685 | |
|---|
| 686 | <p>If you wish to ignore certain files use the <code class="shell"> |
|---|
| 687 | global-ignores </code> feature of <code class="shell"> |
|---|
| 688 | ~/.subversion/config </code>, for example:</p> |
|---|
| 689 | |
|---|
| 690 | <pre class="shell"> |
|---|
| 691 | [miscellany] |
|---|
| 692 | global-ignores = dropin.cache *.pyc *.pyo *.o *.lo *.la #*# .*.rej *.rej .*~ |
|---|
| 693 | </pre> |
|---|
| 694 | |
|---|
| 695 | </li> |
|---|
| 696 | </ul> |
|---|
| 697 | |
|---|
| 698 | <h2>Fallback</h2> |
|---|
| 699 | |
|---|
| 700 | <p>In case of conventions not enforced in this document, the reference |
|---|
| 701 | documents to use in fallback is |
|---|
| 702 | <a href="http://www.python.org/dev/peps/pep-0008/">PEP 8</a> for Python |
|---|
| 703 | code and <a href="http://www.python.org/dev/peps/pep-0007/">PEP 7</a> for |
|---|
| 704 | C code. For example, the paragraph <strong>Whitespace in Expressions and |
|---|
| 705 | Statements</strong> in PEP 8 describes what should be done in Twisted |
|---|
| 706 | code.</p> |
|---|
| 707 | |
|---|
| 708 | <h2>Recommendations</h2> |
|---|
| 709 | |
|---|
| 710 | <p>These things aren't necessarily standardizeable (in that |
|---|
| 711 | code can't be easily checked for compliance) but are a good |
|---|
| 712 | idea to keep in mind while working on Twisted.</p> |
|---|
| 713 | |
|---|
| 714 | <p>If you're going to work on a fragment of the Twisted |
|---|
| 715 | codebase, please consider finding a way that you would <em>use</em> |
|---|
| 716 | such a fragment in daily life. Using a Twisted Web server on your |
|---|
| 717 | website encourages you to actively maintain and improve your code, |
|---|
| 718 | as the little everyday issues with using it become apparent.</p> |
|---|
| 719 | |
|---|
| 720 | <p>Twisted is a <strong>big</strong> codebase! If you're |
|---|
| 721 | refactoring something, please make sure to recursively grep for |
|---|
| 722 | the names of functions you're changing. You may be surprised to |
|---|
| 723 | learn where something is called. Especially if you are moving |
|---|
| 724 | or renaming a function, class, method, or module, make sure |
|---|
| 725 | that it won't instantly break other code.</p> |
|---|
| 726 | |
|---|
| 727 | </body> |
|---|
| 728 | </html> |
|---|