Add Static Analysis to Python Code

Posted by Harald Nezbeda on Sun 22 September 2019

To make sure all developers of a team or any code contributor to an open source project follows the same code style and guidelines for code quality, project maintainers should consider adding static code analysis. This will help keep the code clean, readable, maintainable and will also reduce the time required to take new developers on board as the code base is using common practices that are well known for the specific technology.

It is best practice to add this to your code base right from the start, although it wouldn't be wrong adding it latter (depending on the size of your code base, you may spend some time here to fix the issues that where detected).

Python has a specific set of so called Python Enhancement Proposals (or short PEPs) that focus on code style, with PEP8 being the most specific and well known of them, but also the one you should focus on first.

Pycodestyle

This is the fastest and simplest way to add checks for PEP8. All you need to do is install pycodestyle

pip install pycodestyle

Afterwards, run it against the code (supposing the code is in the src directory):

pycodestyle ./src

You can also add custom configuration for the static checks, which allows you to extend the rules or to disable them. In order to do this, you need to add a setup.cfg file in the root of your project:

[pycodestyle]
max-line-length = 120

The example above is a common configuration that allows you to change the max line length from the default of 80 to 120, as screens are larger these days (compared to when PEP8 was written).

You can find out more in the module documentation: http://pycodestyle.pycqa.org/en/latest/intro.html#configuration

Pylama

Similar to flake, this is a wrapper over multiple tools for code analysis. With Pylama you get the following modules:

  • pycodestyle
  • pydocstyle
  • PyFlakes
  • Mccabe
  • Pylint
  • Radon
  • eradicate
  • Mypy

To run it, simply use pylama in the console:

pylama ./src

Pylama can also use the configurations provided in the setup.cfg for each module. This way, the custom configuration for pycodestyle defined above can be used without any change. This is ideal if you already use some of the modules that Pylama is wrapping, because your modifications will be minimal (mostly the CI configurations will be affected).

Automate Static Analysis checks using Travis CI

After all configurations are set, you want to make sure that the Static Analysis is done automatically and each developer gets notified in case one or more rules don’t apply to their new code. This can be done inside a continuous integration (CI) task. For Travis CI this can be achieved by defining stages and creating a new stage for the static check:

stages:
- lint
- test

jobs:
  include:
  - stage: lint
    python: 3.7
    install: pip install pylama
    script: pylama ./updatable ./test

The test stage is the default stage of Travis CI and will be executed only if the lint stage will pass successfully. If an error occurs, the maintainers of the repository will get notified.

Here is a commit with a full implementation: https://github.com/nezhar/updatable/commit/e951c7967c4fb4b2d549aa97d912d41beb8945ea

This practice is similar for other CI systems such as Gitlab CI, Bitbucket CI, Cirlce CI and many more. The only thing that will differ is the syntax for the configuration file.