We use two types of software packages: ones needed for the software to work, and ones that make it easier to build the
software. All these are listed in a file named pyproject.toml
.
If you need to add a new dependency that's important for the software to work, add it to the dependencies
list
in pyproject.toml
. If the dependency is just to help make the software, add it to the dev
list in
the optional-dependencies
section.
We use a tool called pip-tools
to keep all our dependencies organized. To install it on your computer, type this
command:
pip install pip-tools
You can find a bunch of helpful commands in the Makefile
, including ones that help manage our dependencies. Here's a
brief overview of them:
lock
- locks versions of all dependencies listed inpyproject.toml
. Thanks to the--upgrade
option, it doesn't overwrite already locked dependencies, it just creates new ones.sync
- installs missing dependencies and removes redundant ones.sync-dev
- do the same assync
, but also takes into account dev dependencies.
We use Black to automatically format code according
to PEP8. For imports ordering we use isort. Both
tools are configured in pyproject.toml
to be compatible with each other.
To run them both at the same time and in the correct order, you can use the fmt
command from the Makefile
.
To disable formatting for a specific line of code, append # fmt: skip
for Black or # isort: skip
for isort.
These comments tell the formatters to skip the respective lines. If you want to combine them both into one line,
separate them with a semicolon: # fmt: skip; isort: skip
.
Important: Always remember to exclude folders/files that do not require formatting. Run the formatter in verbose mode to see what it formats.
Flake8 is used as the main liner. Its configuration is stored in pyproject.toml
using the Flake8-pyproject plugin that allows you to do this. Of course,
we use additional plugins to make this tool even more powerful. Here's a brief overview of them:
- flake8-builtins - ensures that variables do not overwrite builtins.
- pep8-naming - ensures that PEP8 naming conventions aren't violated.
- flake8-bugbear - prevents possible bugs and problems.
You can find other plugins here, and if you find them useful, try integrating them into the project.
We also use MyPy for static types analysis
and Bandit for static security analysis. Their configurations you too
can find in pyproject.toml
.
To run all of them at the same time and in the correct order, you can use the lint
command from the Makefile
.
For them, you can also disable checks of specific lines using special comments: use # noqa
for
Flake8, # type: ignore
for MyPy,
and # nosec
for Bandit. Add these at the end of the line you want the tool
to ignore.
Important: Always remember to exclude folders/files that do not require linting. Run the linter in verbose mode to see what it lints.
We use pre-commit to set up our git hooks. Right now, we only use pre-commit
hook for
checking our code’s style before someone commits it. This makes our code reviews easier because we don’t have to worry
about style issues.
To set up git hooks locally, you just need to run this command:
pre-commit install
If for some reason you need to remove all git hooks from the .git/hooks
directory, run this command:
pre-commit uninstall
Important: Don't forget to set it up locally as it is a prerequisite. Just do it once and forget about it.
Pre-commit framework helps us easily manage and maintain git hooks. It works with many programming languages, but we mainly use it for Python, which is what it was initially created for.
Our configuration is in the .pre-commit-config.yaml
file. We are currently
using local hooks, but the real power
of pre-commit is being able to use tools without having to install them on your computer. To
understand more about this, take a look at
this guide. Also, check out the full list of
available third-party repos with hooks here.
After updating the configuration you can check if it's valid with this command:
pre-commit validate-config
To update third-party repos with hooks to the latest versions, run this command:
pre-commit autoupdate
And to update a specific one:
pre-commit autoupdate --repo <repo>
You don't need to do a silly commit just to check if the pre-commi
' hook works. Instead, you can test all hooks with:
pre-commit run --all_files
Or test a specific hook by specifying its id:
pre-commit run <hook_id> --all_files