Improve docs.
[xnet] / doc / coding_rules.rst
diff --git a/doc/coding_rules.rst b/doc/coding_rules.rst
new file mode 100644 (file)
index 0000000..aeebb90
--- /dev/null
@@ -0,0 +1,100 @@
+Style guide
+===========
+
+This document describes the main coding rules in use in the plat/al codebase.
+
+Python
+------
+
+Plat/al mostly follows the :pep:8 rules and `Django's coding style`_.
+
+.. _Django's coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
+
+Mostly:
+
+  - Lines are limited to 120 characters
+  - Indent with 4 spaces
+
+Annotations
+"""""""""""
+
+- Use ``TODO`` and ``FIXME`` annotations with the name of the assignee::
+
+    # TODO(x2006barrois): make the spam more explicit
+    # FIXME(x2008gelineau): this may fry the eggs
+
+- Use ``XXX`` for things we can't improve, such as limitations in Python::
+
+    # XXX: OrderedDict does not exist before Python 2.7
+
+
+Imports
+"""""""
+
+**Do not use** ``import *``.
+
+When importing from the same package, use relative imports.
+Otherwise, use absolute imports:
+
+.. code-block:: python
+
+    # xnet/foo/bar.py
+
+    # Absolute import of xnet.blih
+    from xnet import blih
+
+    # Relative import of xnet.foo.baz
+    from . import baz
+
+
+Imports should be ordered from most general to most local:
+
+#. Standard lib imports
+#. Django imports
+#. Third party lib imports
+#. Plat/al imports
+#. Current app imports
+
+
+Exceptions
+""""""""""
+
+Exceptions are quite powerful, but should be used properly.
+
+Each module defining custom exceptions should define a base class for its
+exceptions; other exceptions from the module must then inherit from that base
+exception. This makes it much easier to catch module-specific exceptions:
+
+
+.. code-block:: python
+
+    # blah/foo.py
+
+    class FooError(Exception):
+        """Base class for exceptions from blah.foo."""
+
+    class SpecificException(FooError):
+        """A specific exception."""
+
+    def some_fun():
+        """Demo function for exception catching."""
+        try:
+            do_something()
+        except SpecificException as e:
+            handle_specific_exception(e)
+
+    # module bar.py
+
+    def other_fun():
+        try:
+            do_something()
+        except foo.FooError as e:
+            handle_generic_foo_exception(e)
+
+
+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.
+
+Avoid generic excepts, or worse, naked excepts:
+
+- ``except Exception:`` will catch import or syntax exceptions
+- ``except:`` and ``except BaseException:`` will catch all exceptions, including ``KeyboardInterrupt``, thus preventing ``^C``.