How to use mypy on Python 2.7 project

Posted on Fri, 29 Jul 2016 in Python

If you work on a big Python project, type hinting can help you to find many design and function usage problems. Of course, you have to use external tools for static analysis, such as mypy. This is a great tool, but supports Python 3 mainly. Support for 2.7 branch isn't so straightforward. There are a couple of tricks that allows you to use it for 2.7.

Type comments vs stub files

First of all you should decide how to add type hints into your code. There are two options for Python 2.7: type comments or stub files. Personally I prefer type comments because it's easy to use and maintain.

A disadvantage of this approach is a necessity to import typing module. It looks quite strange. I only add comments, but mypy manages me to add an import statement into the code. Hopefully when we migrate to Python 3, we will change type comment to "in code" types, and that imports will become necessary.

Using stub files isn't an option for me. It's OK to use them for third party code. But it's really hard to manage ourselves to maintain them properly for our codebase.

How I use MyPy

MyPy runs under Python 3.5. It means that we have to do several things before MyPy will check 2.7 code.

  • Install python 3.5 somewhere in your system. Personally I prefer pyenv to do it. Make virtualenv and run pip install mypy-lang inside that environment.
  • go back to you python 2 project environment and install there back port of typing library: pip install typing

Check the installation. Activate mypy virtualenv and run mypy --py2 inside the project root folder.

Integrate with PyCharm

I know that PyCharm already has a good type hinting system. But it works not only with PEP syntax, but with JetBrains own syntax. And it's not possible to use a PyCharm type checking in CI. Thats's why I integrate mypy checks into this IDE.

  • Go Preferences -> Tools -> File Watchers. Add a new Watcher. Call it MyPy.
  • In Watcher Settings check Python file in File type field. Program should point to mypy executable inside virtualenv. Use this as Arguments: --py2 -s --check-untyped-defs $FilePath$. Press OK.