Developer's guide ################# :Author: Ben Finney <ben+python@benfinney.id.au> :Updated: 2016-10-21 VCS repository ============== The official Version Control System (VCS) for this code base is the Git repository at `the âpython-daemonâ Pagure project`_. You can submit your proposed changes as merge requests: * Use your Pagure account and use the âpull requestâ feature. * Subscribe to `the âpython-daemon-develâ discussion forum`_ and direct us to a branch in your published fork. .. _the âpython-daemonâ Pagure project: https://pagure.io/python-daemon/ .. _the âpython-daemon-develâ discussion forum: https://lists.alioth.debian.org/mailman/listinfo/python-daemon-devel Project layout ============== :: ./ Top level of source tree doc/ Project documentation bin/ Executable programs daemon/ Main âdaemonâ library test/ Unit tests Code style ========== Python ------ All Python code should conform to the guidelines in :PEP:`8` and :PEP:`257`. In particular: Indentation +++++++++++ * Indent each level using 4 space characters (``U+0020 SPACE``). * Indent continuation lines two levels (8 spaces). This will help distinguish them from adjacent code blocks indented one level. Do not attempt to align continuation lines with characters on the previous line. * Do not insert TAB (``U+0008 CHARACTER TABULATION``) characters into source code. This allows the code to render the same in different programs, and improves the ability to cut-and-paste the code. Example:: flim = flambake( foo=eeny.meeny.miney.moe.Catcher(), bar="eggs", baz="spam") found_anomolous_wibble = False for wibble in flim: if wibble in [ zork for zork in zorkulate(wibble)]: found_anomolous_wibble = True break wibble_accumulator.append(wibble) zinkify(wibble_accumulator) Naming ++++++ * Name modules in lower case, ``multiplewordslikethis``. * Name classes in title case, ``MultipleWordsLikeThis``. * Name functions, instances, and other variables in lower case, ``multiplewordslikethis`` or ``multiple_words_like_this``. * Do not choose ``camelCaseNames``, which are inconsistently capitalised. Documenting code ++++++++++++++++ * Every module, class, and function has a Python doc string explaining its purpose and API. *Exception*: Functions whose purpose and API are mandated by Python itself (dunder-named methods) do not need a doc string. * Every doc string conforms to :PEP:`257`. Additionally: * The text of the doc string is marked up with reStructuredText. * The first line is a one-line synopsis of the object. This summary line appears on the same line as the opening triple-quote, separated by a single space. * Further lines, if needed, are separated from the first by one blank line. * The synopsis is separated by one space from the opening triple-quote; this causes it to appear four columns past the beginning of the line. All subsequent lines are indented at least four columns also. * The synopsis is followed by a reStructuredText field list. The field names are: âparam fooâ for each parameter (where âfooâ is the parameter name), and âreturnâ for the return value. The field values describe the purpose of each. * The closing triple-quote appears on a separate line. Example:: def frobnicate(spam, algorithm="dv"): """ Perform frobnication on the `spam` travortionate. :param spam: A travortionate (as a sequence of strings). :param algorithm: The name of the algorithm to use for frobnicating the travortionate. :return: The frobnicated travortionate, if it is non-empty; otherwise ``None``. The frobnication is done by the Dietzel-Venkman algorithm, and optimises for the case where `spam` is freebled and agglutinative. """ spagnify(spam) # ⦠Import statements +++++++++++++++++ * All ``import`` statements appear at the top of the module. * Each ``import`` statement imports a single module, or (using ``from``) multiple names from a single module. Example:: import sys import os from spam import (foo, bar, baz) Additional style guidelines +++++++++++++++++++++++++++ * All text files (including program code) are encoded in UTF-8. * A page break (``U+000C FORM FEED``) whitespace character is used within a text file to break up semantically separate areas of the module. * Editor hints for Emacs and Vim appear in a comment block at the file's end. For Python source code:: # Local variables: # coding: utf-8 # mode: python # End: # vim: fileencoding=utf-8 filetype=python : For reStructuredText documents:: # Local variables: # coding: utf-8 # mode: text # mode: rst # End: # vim: fileencoding=utf-8 filetype=rst : Unit tests ========== All code should aim for 100% coverage by unit tests. New code, or changes to existing code, will only be considered for inclusion in the development tree when accompanied by corresponding additions or changes to the unit tests. Test-driven development ----------------------- Where possible, practice test-driven development to implement program code. * During a development session, maintain a separate window or terminal with the unit test suite for the project running continuously, or automatically every few seconds. * Any time a test is failing, the only valid change is to make all tests pass. * Develop new interface features (changes to the program unit's behaviour) only when all current tests pass. * Refactor as needed, but only when all tests pass. * Refactoring is any change to the code which does not alter its interface or expected behaviour, such as performance optimisations, readability improvements, modularisation improvements etc. * Develop new or changed program behaviour by: * *First* write a single, specific test case for that new behaviour, then watch the test fail in the absence of the desired behaviour. * Implement the minimum necessary change to satisfy the failing test. Continue until all tests pass again, then stop making functional changes. * Once all tests (including the new test) pass, consider refactoring the code and the tests immediately, then ensure all the tests pass again after any changes. * Iterate for each incremental change in interface or behaviour. Test-driven development is not absolutely necessary, but is the simplest, most direct way to generate the kind of program changes accompanied by unit tests that are necessary for inclusion in the project. .. Local variables: coding: utf-8 mode: rst time-stamp-format: "%:y-%02m-%02d" time-stamp-start: "^:Updated:[ ]+" time-stamp-end: "$" time-stamp-line-limit: 20 End: vim: fileencoding=utf-8 filetype=rst :