MyPy Review

November 2, 2017

I recently added type annotations to two of my projects git-browse and git-reviewers using mypy and found it to be relatively enjoyable. Adding types to python definitely helps to make code self-documenting and effectively increases the number of tests in your code. There are a few large issues though for anyone trying to add type annotations:

  1. In order to use python’s type annotation syntax (rather than type comments), your code must be Python 3 only. (Yes, you should use python 3 whether or not you’re adding type annotations)

  2. You must have library stubs of your imports so that MyPy can infer types. So far, there are very few library stubs available and even some extremely popular packages like Flask aren’t covered. This limits type checking to packages with few if any external dependencies.

Adding in type annotations, I also ran into a few issues:

  1. The docs are quite good but given python typing’s obscurity, it’s still hard to find answers for more esoteric features.

  2. The syntax for default values, e.g. (from the mypy docs):

def greeting(name: str, prefix: str = 'Mr.') -> str:
return 'Hello, {} {}'.format(name, prefix)

puts the default value after the type annotation. For a person who hasn’t worked with the type syntax before, at first glance it looks like a string value is being assigned to str within a dictionary.

  1. MyPy requires newly instantiated empty iterables (lists, sets, dictionaries) to include annotations so it can type check elements. However, the native python syntax has no support for it which requires adding type comments, resulting in:
data = [] # type: List[int]
  1. The comment syntax has a bug where its types require imports which set off linters like Flake8 as an unused import. From the above example, this ends up requiring odd code to pass both the flake8 linter and mypy:
from types import List  # NOQA
data = []  # type: List[int]

MyPy is still under heavy development with significant hands-on support from Guido van Rossum himself. Overall though, adding in types was still a relatively easy and useful exercise and helped prompt some refactorings.

PS - Turns out that python-markdown2 has a bug when rendering code fences inside of lists.