.. -*-rst-*- C = The C implementations should follow the `kernel/git coding style `_. Python ====== Python code follows `PEP8 `_ with regard to coding style and `PEP257 `_ with regard to docstring style. Multi-line docstrings should have one short summary line, followed by a blank line and a series of paragraphs. The last paragraph should be followed by a line that closes the docstring (no blank line in between). Here's an example from ``lib/bup/helpers.py``:: def unlink(f): """Delete a file at path 'f' if it currently exists. Unlike os.unlink(), does not throw an exception if the file didn't already exist. """ ... Module-level docstrings follow exactly the same guidelines but without the blank line between the summary and the details. Exception Handling ------------------ Avoid finally: blocks in favor of explict catches because a throw from a finally block will lose any pending exception. An explicit catch can chain it (see below). To behave similarly under Python 2 and 3, use add_ex_tb() to explicitly add stack traces to any exceptions that are going to be re-raised by anything other than a no-argument raise (otherwise the stack trace will be lost):: try: ... except ... as ex: add_ex_tb(ex) pending_ex = ex ... raise pending_ex When an exception is thrown from an exception handler, the pending exception should be the `"context" `_ of the new exception, which can be accomplished (portably) via ``pending_raise()``:: try: ... except ... as ex: with pending_raise(ex): clean_up() This should do roughly the same thing in Python 2 and Python 3, throwing any exception from ``clean_up()`` after adding ex as the ``__context__`` if clean_up() throws, and throwing ``ex`` otherwise. If for some reason, you need more control, you can use ``add_ex_ctx()`` directly:: try: ... except ... as ex: add_ex_tb(ex) try: ... except ... as ex2: add_ex_tb(ex2) raise add_ex_ctx(ex2, ex) raise See the end of ``lib/bup/compat.py`` for a functional example, and all of this can be removed once we drop support for Python 2.