Style

formate is used for code formatting. It can be run manually via pre-commit:

pre-commit run formate -a

or, to run the complete autoformatting suite:

pre-commit run -a

The general formatting rules are based on PEP 8, but with some differences:

Indentation

Tabs are used instead of spaces.

Function signatures

Function signatures should be laid out like this:

def long_function_name(
        var_one: str,
        var_two: int,
        var_three: List[str],
        var_four: Dict[str, Any],
        ) -> Iterable[Tuple[str, int]]:
    ...

with each argument on its own line, and the function name and return annotatons on separate lines. Ensure to include the trailing comma after the last argument’s annotation. If the signature is short enough it may be placed on one line:

def function_name(var_one: str, var_two: int) -> bool:
    ...

Functions should always be type annotated. *args and **kwargs need not be annotated, but other use of * (e.g. **children) should be annotated. Annotations may be omitted in tests, but are strongly encouraged.

Type Annotations

String annotations should be avoided. Exceptions include TypeVars and where the object is imported using with TYPE_CHECKING: to resolve a circular dependency. PEP 563 (from __future__ import annotations) must not be used.

Type hints should be valid with the earliest supported Python version for the project, typically Python 3.6. This includes the use of typing.Dict[…] etc. rather than dict[…], and importing certain objects from typing-extensions.

Long if Statements

Long if statements should be formatted with if ( on one line, the conditions on the following lines and the ): on the final line. The operator should be at the start of the lines, not at the end.

Where possible such long statements should be avoided, for example by splitting it into multiple if statements or calculating the value in advance.

Long Sequences

Long sequences should be written with each element on its own line and a trailing comma after the last element:

# Bad
my_list = [
        1, 2, 3,
        4, 5, 6
        ]
# Good
my_list = [
        1,
        2,
        3,
        4,
        5,
        6,
        ]

Maximum Line Length

Limit all lines to a maximum of 110 characters. This also applies to docstrings, expect for long URLs in explicit hyperlink targets. Converting long, implicit targets to explicit targets improves the readability of the docstring. This also applies to reStructuredText files in the documentation.

If the summary line of a docstring must exceed 110 characters the line must be wrapped and the docstring marked with # noqa: D400 immediately after the closing quotes.

Blank Lines

Blank lines must be used:

  • After a file’s top-level comments.

  • Before a comment indicating a group of imports.

  • After a group of imports.

  • Immediately after a docstring.

  • Immediately after a class, function or method signature if there is no docstring.

Blank lines must not be used:

  • Between a class, function or method signature and its docstring.

Module Level Dunder Names

Module level “dunders” (i.e. names with two leading and two trailing underscores) such as __all__, __author__, __version__, etc. should be placed after the module docstring and any imports.

They should be in the following order:

  • __author__

  • __copyright__

  • __license__

  • __version__

  • __email__

  • <a blank line>

  • __all__

__all__ should always be included, even for modules with no public API. Only include the names of public objects. If the module has no public API write __all__ = (). TypeVars may be included if it is necessary to document them, otherwise they should be omitted.

The flake8-dunder-all pre-commit hook can be used to automatically generate __all__, although its output should be checked by hand as it can sometimes produce odd results.

String Quotes

Strings should use double quotes where possible, except for single characters and empty strings which should use single quotes. Single quotes may be used where a double quote occurs within the string.

Triple double quotes (""") must be used for docstrings.

Docstrings

The first line of the docstring must start a new line:

# Bad:
"""Return a foobang
"""
# Good:
"""
Return a foobang
"""

This rule is enforced even for short one-liner docstrings, although those should be rare.

Each docstring must document the function’s parameters. For classes, the class docstring should document the arguments of __init__ or __new__ as appropriate.

__init__ should not have a docstring. __new__ may have a docstring in certain crcumstances, expecially for namedtuples.

Naming Style

Function and method names should be written in lower_case_with_underscores.

Class names should use CamelCase. When using acronyms, capitalize all the letters of the acronym. HTTPServerError is better than HttpServerError.

Private classes, functions and instance variables should be prefixed with a single underscore.