Commit | Line | Data |
---|---|---|
a61373d3 RB |
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``. |