Whatever you want to know about typing, try to find it in the mypy documentation,
not by googling. Typing has been evolving and continues to evolve, and anything you
don’t find by checking the current docs is quite likely out of date.
What mypy catches for me:
Sloppy thinking - if the correct type declaration for something exceeds the
line length limit in your flake8 settings, you have written a truly terrible API.
Sloppy error checking - did you declare something as Optional and then forget
to have a None code path? You did, didn’t you…
Actual type mistakes (duh)
False alarms or stuff I don’t quite know how to type hint correctly… Judicious use of
# type: ignore is nothing to be ashamed of, IMHO. Especially if the problem is localized
to a screenful of code that can be checked by inspection.
So, I finally added pre-commit to my little library repo – it’s so much easier than I thought it would be.
Why use pre-commit?
Python has a ton of tools for improving code readability and quality, including
black, isort, flake8, mypy and so on. Pre-commit is a tool that aggregates
all tools you want to run before committing a file into one command.
This talk from PyOhio explains it well, and adds adding pre-commit as your linter in your tox
environment as well (but this article will just cover setting up pre-commit).
Initial steps
Install it
pip install pre-commit
Create a default config file. From the top directory of your project, run:
Congratulations! You’ve just used pre-commit to remove trailing whitespace from all you files and a couple other checks. (You can delete any of the “standard” rules you don’t like from the initial .yaml file.)
Install additional tools
Go to the
pre-commit hooks list
and enter the hook you want in the search box. Let’s choose isort.
Copy the repo link from the pre-commit website. Sometimes, as for isort, it is the tool’s official repo. Other times, it’s a special
pre-commit mirror repo.
Paste the link from the pre-commit hooks website into your command line to get the entry for your pre-commit-config.yaml:
The top part of the output will be the entry for the yaml file:
[INFO] Initializing environment for https://github.com/PyCQA/isort.
===============================================================================
Using config:
===============================================================================
This is my own little trick: copy the ouput for the tool
into your yaml file, but replace the git-hash with a fake version number (“v0”). Your file will look something like this:
Run pre-commit autoupdate and it will replace the “v0” with the human-readable current version of the tool. (Or you could pin a preferred version of your choice here as well.)
You can add additional arguments or install-dependencies to each tool in this yaml file as well. I had my arguments already set up in setup.cfg and pyproject.toml and I left them there for now. Mypy was a smidge tricky - you do have to add the install dependencies for any stub files you need.
Add one tool at a time, running pre-commit run --all-files each time to verify that the tool is configured correctly. If a tool is slow, you can just run a single tool, such as with pre-commit run isort --all-files
Configure your project and development environment
Delete the installation of all the file-checking tools from your setup or requirements files in your project. Replace all the separate tool installs
with installing pre-commit, let pre-commit take it from there. Test everything one last time. I had a Makefile to run my tools - I changed
that to a single command to call pre-commit as well.
When everything is happy, run pre-commit install to make it a git hook that runs every time you commit a file in this repo. (Don’t forget to
check in .pre-commit-config.yaml as well.)
If you run multiple coordinated builds in tox, see the video above for
instructions for that.