Static code analysis tools for Python and CI
Python has some great free and open-source static code analysis tools. I recommend integrating them into you Continuous Integration (CI) pipelines so they run every time you commit and push.
The 3 linters I usually run are:
mypy
: checks type hints consistency. When I started using type hints, I was skeptical of them as they didn’t seem to belong to Python. But now that I’m used to them it’s hard to go back. Type hints not only make the code much more readable, they can also avoid a lot of bugs by using mypy.pylint
: checks for syntax errors and style problems. This one checks a ton of things, so it’s always necessary to tune it to your needs. At a minimum, you should run it to check for errors. In my professional career I’ve seen production code with syntax errors that weren’t detected until I used pylint.bandit
: checks for security issues. Security is extremely important and bandit will tell you about potential issues. It can show false positives, but they can be ignored.
In addition to these, in my CI I also always integrate the pre-commit checks. Local pre-commit checks can be bypassed, so you need
to run them in the pipeline to ensure that the code has been formatted with black
and nobody cheated!
Below you can find an example Gitlab CI template for Python projects. Note that I’m using pip-tools to manage dependencies.
image: python-3.9
stages:
- static_code_analysis
# Change pip's cache directory to be inside the project directory since we can
# only cache local items.
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
paths:
- .cache/pip
- venv/
- .mypy_cache
before_script:
- python3 -m venv venv
- . venv/bin/activate
- export PYTHONPATH="$CI_PROJECT_DIR"
- pip install --upgrade pip pip-tools wheel
- pip-sync requirements.txt requirements-dev.txt
pre-commit:
stage: static_code_analysis
script:
- pre-commit run --all-files
linters:
stage: static_code_analysis
script:
- mypy app/ --config-file=mypy.ini
- pylint app/ --rcfile=pylintrc
- bandit app/ --recursive --quiet
Leave a comment