albertyw/albertyw.com

View on GitHub
app/notes/20171103-0656.md

Summary

Maintainability
Test Coverage
MyPy Review

mypy-review

1509692197

I recently added type annotations to two of my projects [git-browse](https://github.com/albertyw/git-browse)
and [git-reviewers](https://github.com/albertyw/git-reviewers) using
[mypy](https://github.com/python/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 regardless of whether
    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](http://mypy.readthedocs.io/en/stable/index.html) 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):

    ```python
    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.

3.  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:

    ```python
    data = [] # type: List[int]
    ```

4.  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:

    ```python
    from types import List  # NOQA
    data = []  # type: List[int]
    ```

MyPy is still under heavy development with significant hands-on support from
[Guido van Rossum](https://github.com/gvanrossum) 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](https://github.com/trentm/python-markdown2/issues/276).