Code Style Guidelines
Black
We use the black coding style, a flavour of PEP-8 for Python.
We use a pre-commit-hook to apply this style before committing, so you don’t have to bother about formatting. Just code how you feel comfortable and let the tool do the work for you (see Pre-commit Hooks).
If you want to apply the formatting without committing, use our developer tool tools/black.sh:
./tools/black.sh
DjLint
We use djlint to format our Django HTML templates.
We use a pre-commit-hook to apply this style before committing, so you don’t have to bother about formatting. Just code how you feel comfortable and let the tool do the work for you (see Pre-commit Hooks).
If you want to apply the formatting without committing, use our developer tool tools/djlint.sh:
./tools/djlint.sh
Prettier
We use prettier to format our static JS and CSS files.
We use a pre-commit-hook to apply this style before committing, so you don’t have to bother about formatting. Just code how you feel comfortable and let the tool do the work for you (see Pre-commit Hooks).
If you want to apply the formatting without committing, use our developer tool tools/prettier.sh:
./tools/prettier.sh
Linting
In addition to black, we use pylint to check the code for semantic correctness. Run pylint with our developer tool tools/pylint.sh:
./tools/pylint.sh
When you think a warning is a false positive, add a comment (see Messages control):
def some_function(
something: SomeModel, # pylint: disable=unused-argument
*args,
**kwargs) -> None:
# pylint: disable=too-many-branches
Note
Please use the string identifiers (unused-argument
) instead of the alphanumeric code (W0613
) when disabling warnings.
Hint
If you want to run both tools at once, use our developer tool tools/code_style.sh:
./tools/code_style.sh
Docstrings
Please add docstrings in the sphinx format (see Writing docstrings):
"""
[Summary]
:param [ParamName]: [ParamDescription], defaults to [DefaultParamVal]
...
:return: [ReturnDescription]
:raises [ErrorType]: [ErrorDescription]
...
"""
Hint
In the model documentation, the parameters are not required, because they are automatically derived from the model field type.
Whenever you want to document module/class attributes which are not parameters (i.e. because they are not passed to the
__init__()
-function or contain static values), use inline comments:
#: Description of attribute
attribute = "value of this attribute"
See the configuration files settings
and conf
or constants
for examples.
my[py]
We use my[py] to check type annotations of our python code.
We use a pre-commit-hook to apply this check before committing, so TypeErrors will be prevented. Just code how you feel comfortable and let the tool do the work for you (see Pre-commit Hooks).
If you want to apply the formatting without committing, use our developer tool tools/mypy.sh:
./tools/mypy.sh
Note
If you’re unsure about a type, temporarily add reveal_type(variable)
to the code and run ./tools/mypy.sh
, the tool will then tell you what type it would guess.
Any imports that are only needed during type checking should be wrapped into a if TYPE_CHECKING:
block. For that the variable TYPE_CHECKING
should be imported from typing
.
The line from __future__ import annotations
must be the first line (after the module docstring) of any new python file.
(This activates PEP 563 for any python version where it is not already active by default, so we need to keep this until all python versions we support implement it. At the time of writing the first python version where this is not just optional is still mentioned as TBD)
If a third party library is incorrectly typed or missing type hints, and this results in errors you cannot fix, then you can add # type: ignore[<error-class>]
(where the <error-class>
is the identifier of the error you’re experiencing, e.g. attr-defined
) in the end of the line where the error is thrown.
Shellcheck
All developer tools in the tools directory have to comply to the standards of shellcheck (see ShellCheck wiki). Shellcheck is run both in the CI-pipeline of CircleCI (see shellcheck/check) and as pre-commit hook (see Pre-commit Hooks) and can be run locally with:
shellcheck -x tools/*
False positives can be ignored with the syntax:
# shellcheck disable=SC2059