Improve docs.
[xnet] / doc / coding_rules.rst
1 Style guide
2 ===========
3
4 This document describes the main coding rules in use in the plat/al codebase.
5
6 Python
7 ------
8
9 Plat/al mostly follows the :pep:8 rules and `Django's coding style`_.
10
11 .. _Django's coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
12
13 Mostly:
14
15   - Lines are limited to 120 characters
16   - Indent with 4 spaces
17
18 Annotations
19 """""""""""
20
21 - Use ``TODO`` and ``FIXME`` annotations with the name of the assignee::
22
23     # TODO(x2006barrois): make the spam more explicit
24     # FIXME(x2008gelineau): this may fry the eggs
25
26 - Use ``XXX`` for things we can't improve, such as limitations in Python::
27
28     # XXX: OrderedDict does not exist before Python 2.7
29
30
31 Imports
32 """""""
33
34 **Do not use** ``import *``.
35
36 When importing from the same package, use relative imports.
37 Otherwise, use absolute imports:
38
39 .. code-block:: python
40
41     # xnet/foo/bar.py
42
43     # Absolute import of xnet.blih
44     from xnet import blih
45
46     # Relative import of xnet.foo.baz
47     from . import baz
48
49
50 Imports should be ordered from most general to most local:
51
52 #. Standard lib imports
53 #. Django imports
54 #. Third party lib imports
55 #. Plat/al imports
56 #. Current app imports
57
58
59 Exceptions
60 """"""""""
61
62 Exceptions are quite powerful, but should be used properly.
63
64 Each module defining custom exceptions should define a base class for its
65 exceptions; other exceptions from the module must then inherit from that base
66 exception. This makes it much easier to catch module-specific exceptions:
67
68
69 .. code-block:: python
70
71     # blah/foo.py
72
73     class FooError(Exception):
74         """Base class for exceptions from blah.foo."""
75
76     class SpecificException(FooError):
77         """A specific exception."""
78
79     def some_fun():
80         """Demo function for exception catching."""
81         try:
82             do_something()
83         except SpecificException as e:
84             handle_specific_exception(e)
85
86     # module bar.py
87
88     def other_fun():
89         try:
90             do_something()
91         except foo.FooError as e:
92             handle_generic_foo_exception(e)
93
94
95 Only catch the errors that you expect. Let the other errors propagate. Do not catch an exception then raise another one, as this hides the true cause of the error.
96
97 Avoid generic excepts, or worse, naked excepts:
98
99 - ``except Exception:`` will catch import or syntax exceptions
100 - ``except:`` and ``except BaseException:`` will catch all exceptions, including ``KeyboardInterrupt``, thus preventing ``^C``.