Friday, 13 January 2017

Mypy 0.470 Released

We’ve just uploaded mypy 0.470 to PyPI. This release adds new features, bug fixes and library stub updates. You can install it as follows:

    python3 -m pip install mypy

Note: The package name is now “mypy” (no longer mypy-lang). If you have an older mypy version installed, remove it first, before installing the new package:

    python3 -m pip uninstall mypy-lang

Good news: New Package Name and Version Style

We have finally obtained ownership of the “mypy” package name on PyPI. In order to avoid conflicts with (hypothetical) users of the previous occupant of the “mypy” package name we’re changing the style of version numbers we’re using (at least until 1.0 comes along) — the new version is now 0.470. If you are using requirements.txt files, the proper incantation is now:


The old “mypy-lang” package will no longer be upgraded (the last version there is 0.4.6).

New Import Handling Options

The “silent imports” functionality, useful to avoid noisy errors about missing modules when annotating a large codebase, has been refactored and improved. There are now two separate flags (see the online docs for the full scoop):

  • --follow-imports=arg takes an argument which must be one of the following:
    • normal — the default behavior
    • silent — tries to find, parse and check imported modules (same as normal) but suppresses all errors for those modules that were not given on the command line
    • skip — roughly equivalent to the old --silent-imports flag
    • error — roughly equivalent to the old --almost-silent flag
  • --ignore-missing-imports suppresses error messages about imports that cannot be resolved at all. This was previously implied by --silent-imports unless --almost-silent was given.

Fast Parser Supported on Windows

The --fast-parser option now works also on Windows. It’s faster than the default parser and supports more Python syntax, including new syntax introduced in Python 3.6. The required package typed_ast is now installed by default as a mypy dependency (see below for more). We are planning to deprecate the current default parser in a future mypy release. (Also, the mypy project now runs tests for Windows on Appveyor.)

Improved Type Inference for lambda Expressions

A lambda expression without type context is now inferred as a Callable returning whatever type can be inferred for the expression in the body of the lambda. Previously such lambda expressions were given type Any . Note that lambda ...: None is now considered to have type Callable[..., None] which cannot be called to provide a value, only as a procedure call. The arguments are given type Any, so that e.g. the following two are now inferring the same type for a, i.e. Callable[[Any], List[Any]]:

    a = lambda x: [x]

    def a(x) -> List[Any]: return [x]

(Contributed by Elazar Gershuni)

Support for callable()

A condition using e.g. if callable(x) now causes mypy to infer a Callable type for x in the block controlled by the condition, and a non-Callable type in the block controlled by its negation. For example, this now type-checks:

    def maybecall(x: Union[int, Callable[[], int]]) -> int:
        if callable(x):
            return x()
            return x

(Contributed by Alex Frieder)

New Package Dependencies

Mypy now has automatic dependencies on typing and typed_ast. Previously typed_ast had to be manually installed using pip and typing was bundled with the mypy package.

Note that typed_ast requires Python 3.5+ on Windows. We’re dropping support for running mypy on Windows using Python 3.4 or older. (But checking still supports 2.7 and 3.2+ targets, using the --python-version flag.)

Notable Bugs Fixed

  • Callable type compatibility checking rewritten with several improvements (Naomi Seyfer)
  • Fix Callable arguments in overloaded functions
  • Fix lambda inference with simple Union contexts
  • Fix spurious warnings caused by type redeclarations (Łukasz Langa)
  • Fix handling of empty tuple type aliases
  • Fix crash on retrieving TypeVar from class (Tom Manderson)
  • Ensure required keyword-only arguments are provided (Naomi Seyfer)
  • Consider types like Tuple[t1, t2, ...] more consistently as subtypes of plain tuple (Ivan Levkivskyi)
  • Compare cached options to current per-file options when using --incremental
  • Fix NamedTuple defined in a method

New Experimental Features

There is work-in-progress support for dictionaries with literal string keys (TypedDict). Different keys can have items with different types, and mypy will figure out the right type for each key. For example, it will be possible to give a precise type for this dictionary:

    d = {'path': 'file.txt', 'size': 1254}

TypedDict is still very tentative and there’s no official documentation yet. You need to import TypedDict from mypy_extensions; use pip install -U mypy_extensions to install it. (Contributed by David Foster)

Descriptors are now supported. We're still not quite sure how well they work in practice. (Contributed by Calen Pennington)

Other Changes in This Release

  • Turn --hide-error-context on by default to generate more concise output from mypy. Add --show-error-context to re-enable the old behavior.
  • Arguments starting with __ (two underscores) are now positional-only. (Naomi Seyfer)
  • Add an API for calling mypy directly from another python application. (Jacques de Hooge)
  • Add ignore_errors config option to selectively ignore all non-fatal errors in some files.
  • Add Python 3 cheat sheet. (Ethan Smith)
  • Speed up the mypy test suite. (Łukasz Langa)
  • Miscellaneous other bug fixes.
  • Many updates to the library stubs in typeshed.


Thanks to all mypy contributors who contributed to this release:

  • Aleksander Vognild Burkow
  • Alex Frieder
  • Bertrand Bonnefoy-Claudet
  • Calen Pennington
  • Chris Oelmueller
  • David Euresti
  • David Foster
  • Elazar Gershuni
  • Ethan (ethanhs)
  • Ivan Levkivskyi
  • Jacques de Hooge
  • Jakub Stasiak
  • Jelle Zijlstra
  • Josiah Boning
  • Juanvulcano
  • Łukasz Langa
  • Naomi Seyfer
  • Roy Williams
  • Tetsuya Morimoto
  • Tom Manderson
  • TrueBrain

Additional thanks to these contributors to typeshed:

  • Alex Frieder
  • Alex Jurkiewicz
  • Anders Kaseorg
  • Bertrand Bonnefoy-Claudet
  • Cadel Watson
  • Calen Pennington
  • Daisuke Miyakawa
  • Danny Weinberg
  • David Euresti
  • Eric Moyer
  • George King
  • gotyaoi
  • Henri Dwyer
  • Hugo (hugovk)
  • Jason Fried
  • Jelle Zijlstra
  • Jon Dufresne
  • Joseph H Garvin
  • Josiah Boning
  • Kosaka Masayuki
  • lionel-github
  • Luiz Menezesf
  • Łukasz Langa
  • Madeleine Thompson
  • Mateusz Kurek
  • Matthias Kramm
  • Michael Lee
  • Mohab Usama
  • Naomi Seyfer
  • Nicolas Duchastel de Montrouge
  • Onno Kortmann
  • Peter Amstutz
  • Philip House
  • Reverb Chu
  • Richard Eames
  • Roy Williams
  • Ryan C. Thompson
  • rymdhund
  • Simon Ekstrand
  • Thomas Aynaud
  • Thomas Cellerier
  • Tom Manderson
  • TrueBrain
  • Wesley Bowman
  • z33ky

— Jukka (on behalf of the rest of the mypy team: Guido, David and Greg)

Monday, 21 November 2016

Mypy 0.4.6 Released

We’ve just uploaded mypy 0.4.6 to PyPI. This release adds many new features, bug fixes and library stub updates. As always, you can install it as follows, being careful to install mypy-lang, not mypy:

    python3 -m pip install --upgrade mypy-lang

Generic Type Aliases

You can now define type aliases that are themselves generic types. For example, consider this definition of Vector:

    from typing import TypeVar, List

    T = TypeVar('T')

    Vector = Tuple[T, T, T]

Now Vector[float], for example, is equivalent to Tuple[float, float, float]. Generic type aliases can make your type annotations shorter and easier to read. The following example defines two equivalent functions. The first one uses a generic type alias to simplify the signature:

    def negate1(vecs: List[Vector[float]]) -> List[Vector[float]]:
        return [(-x, -y, -z) for x, y, z in vecs]

    def negate2(vecs: List[Tuple[float, float, float]]
               ) -> List[Tuple[float, float, float]]:
        return [(-x, -y, -z) for x, y, z in vecs]

Check out the documentation for more details.

This was contributed by Ivan Levkivskyi and he also implemented the related changes to typing.

Detecting Missing Return Statements

Mypy now can generate an error if a function is missing a return statement, unless the return type is None or Any. Use the --warn-no-return command line option to enable this, or the warn_no_return config file setting. When the option is set, mypy warns about this function, since it doesn’t return anything if the condition is false:

    def f(n: int) -> int:
        if n > 3:
            return n + 1  # Missing return statement

Mypy currently doesn’t warn about empty function bodies or bodies that only have an ellipsis (), since these are sometimes used for abstract methods and aren’t necessarily a problem. The option can generate false positives if you rely on the implicit None return value when execution falls off the end of a function.

This was contributed by Reid Barton.

Improved Type Checking of Import Cycles

Previous versions of mypy were prone to giving errors like ‘Cannot determine type of “foo”’ if your program had import cycles. Another common problem was that innocent-looking changes inside import cycles would cause mypy to emit a new set of unrelated errors.

This release has two changes that should resolve most of these issues. They are a bit technical, and it’s not important to understand how they work in order to enjoy the benefits. Anyway, the two following subsections have a summary for those who are interested in the nitty-gritty internal details. Feel free to skip them. For even more details, have a look at these PRs: #2264 and #2167

Deferred Checking within Import Cycles

Previously mypy type-checked each module only once, a single module at a time. This could be a problem with import cycles. For example, module a could depend on inferred types in b, and b could depend on types of a. No linear ordering of modules would produce clean output, unless the program had type annotations for all the problematic variables — this was only a problem for things whose types weren’t immediately obvious to mypy. Mypy now type-checks an import cycle in two passes. If there is a reference to a variable in another module that mypy hasn’t yet processed, mypy defers the type-checking of the surrounding function, and finally runs another type-checking pass for only deferred functions.

Programs without cycles aren’t affected, since mypy has type-checked single modules in two passes for some time. We’ve now generalized it to multiple modules in a cycle.

Stable Processing Order within Import Cycles

The erratic mypy behavior mentioned earlier was caused by changes in the order of processing modules within a cycle. Mypy goes through each module in a cycle in a linear order, and some errors are only triggered for certain orderings. In previous versions of mypy a small change in a program could trigger big changes in the module processing order. Mypy now better approximates the runtime module initialization order, which is usually pretty stable.

For example, if module a has a statement like from b import f, module b likely will be initialized before module a at runtime, and so mypy will type-check b before a. On the other hand, if an import statement is within an if TYPE_CHECKING: block, mypy will not use this heuristic, since typing.TYPE_CHECKING is false at runtime and the import statement won’t affect runtime behavior.

Self Types (Experimental)

[This feature is experimental — the implementation still has significant limitations or bugs, and the feature may change in future mypy versions in incompatible ways.]

Sometimes you have a method that returns a value with exactly the same type as self. Previously there was no way to do this. Now you can annotate the self argument with a type variable to express this. Here’s an example taken from the documentation:

    from typing import TypeVar

    T = TypeVar('T', bound='Shape')

    class Shape:
        def set_scale(self: T, scale: float) -> T:
            self.scale = scale
            return self

    class Circle(Shape):
        def set_radius(self, r: float) -> 'Circle':
            self.radius = r
            return self

    class Square(Shape):
        def set_width(self, w: float) -> 'Square':
            self.width = w
            return self

    circle = Circle().set_scale(0.5).set_radius(2.7)  # type: Circle
    square = Square().set_scale(0.5).set_width(3.2)  # type: Square

By declaring self as a type variable, the set_scale can return a Circle when called on a Circle object and a Square when called on a Square, while only having a single method definition in the Shape base class.

For a class method, you can also now use Type[T] in a similar way as the annotation for the cls argument.

This feature was contributed by Elazar Gershuni.

Type Applications

Mypy now supports a type application syntax for user-defined generic classes. For example, consider a generic Stack class:

    from typing import TypeVar, Generic

    T = TypeVar('T')

    class Stack(Generic[T]):

When constructing a Stack instance, you can use the type application syntax Stack[<type>] to specify the type arguments. This constructs a Stack[int] instance using a type application:

    stack = Stack[int]()

Previously you had to use a type annotation, which is more verbose:

    stack = Stack()  # type: Stack[int]

This is now practical since the latest typing implementation caches the result of Stack[int], so it will be quick enough even for a frequently called function. This was actually supported in early mypy releases, but it has been unsupported for a while, primarily due to performance concerns.

You still have to use the type annotation syntax for standard-library classes such as list and Queue since these classes don’t support the indexing operator.

This was contributed by Ivan Levkivskyi. He also implemented the related changes to typing.

New NamedTuple Syntax (Python 3.6)

You can use a new syntax for named tuples with Python 3.6b1 or newer:

    from typing import NamedTuple

    class Point(NamedTuple):
        x: int
        y: int

    p = Point(x=1, y=2)

Run mypy with --fast-parser --python-version 3.6 to use this. You’ll need to install a recent version of typed_ast (pip3 install --upgrade typed_ast).

This was contributed by Ivan Levkivskyi.

Config File Changes

The filename patterns in the mypy configuration file were changed to module name patterns. You’ll have to update your config files if you use this feature.

Here’s an example mypy.ini file that rejects functions without a type annotation in the frobnicate package but allows them elsewhere:

    disallow_untyped_defs = True

You can configure additional module search path entries in the mypy configuration file through the mypy_path configuration file option. This can be useful with local stub files stored in a separate directory, for example. Previously you had to use the MYPYPATH environment variable. mypy_path was contributed by Filip Figiel.

New Command Line Options

  • Add --cobertura-xml-report for outputting Cobertura XML reports with type checking coverage information (Roy Williams).
  • Add support for using a custom typeshed directory (--custom-typeshed-dir).
  • Add --junit-xml=PATH option for generating JUnit XML files with type checking results.
  • Add --find-occurrences that finds all references to a class member using static type information (experimental).
  • Stubgen now supports --fast-parser (Ivan Levkivskyi).

Other Changes in This Release

  • Improvements to --strict-optional (please go ahead and try it — it now works pretty well).
  • Allow subclassing Tuple[...] outside stubs again (Ivan Levkivskyi).
  • Show column number for reveal_type() expressions.
  • Various updates to the bundled typing module.
  • Support conditional import in functions/classes (Mark Laws).
  • Support matrix multiplication operator @ (Elazar Gershuni).
  • Several miscellaneous bug fixes.
  • Several documentation improvements.
  • Lots of updates to the library stubs in typeshed.


Thanks to all mypy contributors who contributed to this release:

  • Alex Jurkiewicz
  • Byungwoo Jeon
  • Calen Pennington
  • Chris Lamb
  • David Foster
  • Elazar Gershuni
  • Filip Figiel
  • Herbert Ho
  • Ivan Levkivskyi
  • Kevin Yap
  • Mark Laws
  • Reid Barton
  • Roy Williams
  • Ryan Gonzalez
  • Ulric Aleksandrov

Additional thanks to these contributors to typeshed:

  • Alvaro Caceres
  • Calen Pennington
  • David Percy
  • Dima Gerasimov
  • Eklavya Sharma
  • Evan Hubinger
  • Gerhard Hagerer
  • Hong Minhee
  • Jakub Stasiak
  • Jon Dufresne
  • Jordan Pittier
  • Joshua Smock
  • Kai Lautaportti
  • Matthias Kramm
  • Onno Kortmann
  • Reiner Gerecke
  • Ruud van Asseldonk
  • Ryan C. Thompson
  • Sebastian Meßmer
  • TrueBrain
  • Xavier Mehrenberger
  • Yegor Roganov
  • Joseph H Garvin
  • nobuggy
  • paavoap

— Jukka (on behalf of the rest of the mypy team: Guido, David and Greg)

Friday, 7 October 2016

Mypy 0.4.5 Released

We’ve just uploaded mypy 0.4.5 to PyPI. This release adds many new features, bug fixes and library stub updates. As always, you can install it as follows, being careful to install mypy-lang, not mypy:

    python3 -m pip install -U mypy-lang

Gitter Chat Room

We’re embarking on a customer support paradigm shift: we now have a chat room at Please join us for an interactive conversation. Of course, we also still encourage filing issues in our tracker!

Configuration Files

You can now put common mypy options in a configuration file, so you won’t have to remember to pass all those pesky flags each time you run mypy. Many options can also be specified per file using filename matching patterns. For example, you might put this in mypy.ini at the root of your repo:

    python_version = 2.7
    fast_parser = True
    disallow_untyped_defs = True

This sets --python-version 2.7 (a.k.a. --py2 ) and --fast-parser for all mypy runs in this tree, and selectively turns on the --disallow-untyped-defs flag for all files under the foo/ subdirectory. This prints an error for function definitions without type annotations in that subdirectory only.

On a related topic, if you have a file containing a list of files and directories to check, you can now invoke mypy on that list using mypy @filenames — this reads a list of filenames from the file filenames .

PEP 526 Variable Annotations

If you like to live in the future, you may have noticed that Python 3.6b1 was recently released with syntactic support for variable annotations specified by PEP 526. But syntactic support alone wouldn’t be very useful, so we’ve got experimental type checking support for this feature in mypy! Thanks a bundle to Ivan Levkivskyi for the implementation. Example:

    def sum(a: List[float]) -> List[float]:
        total = 0.0
        cumulative: List[float] = []  # Check it out!
        for x in a:
            total += x
        return cumulative

Note: you need --fast-parser to use this (it’s easy to enable in mypy.ini , see above) and you need to install typed-ast version 0.6.1 (python3 -m pip install -U typed-ast ).

New and Changed Flags

  • Renamed --suppress-error-context to --hide-error-context .
  • Fixed some nasty bugs in --incremental mode that could cause irreproducible errors.
  • Multiple -c arguments are now joined using newlines into a single multiline command.
  • New flag --show-column-numbers causes error messages to include column numbers in addition to line numbers. Note that column numbers are zero-based: the start of the line is column 0. (Ben Duffield)
  • New flag --disallow-subclassing-any reports errors when a base class has type Any .
  • New flag --strict-optional-whitelist controls strict none checking for individual files using filename matching patterns. (In mypy.ini, use show_none_errors in pattern sections, in combination with a global strict_optional flag.)
  • New flag --scripts-are-modules gives command line arguments that appear to be scripts (i.e. files whose name does not end in .py) a module name derived from the script name rather than the fixed name __main__. (This is more useful although less strictly correct.)

Deprecations and Removals

  • We no longer support using Python 3.2 to run mypy. (You can still type check Python 3.2 programs by specifying --python-version 3.2 .)
  • There used to be an undocumented feature named “weak mode”, triggered by comments of the form # mypy: weak . We now have better way to configure the strictness of checking per file, using pattern sections in mypy.ini (see above) so we have removed this feature to simplify mypy’s internals somewhat.
  • There was an undocumented package mypy.codec that was meant to support the Python 3 function annotation syntax in Python 2 using a codec hack (# coding: mypy ). We stopped using this a long time ago in favor of type comments, and we’ve finally removed the code.

Miscellaneous Other Changes in This Release

  • typing.TYPE_CHECKING : a constant that is false at runtime but true while type checking. This is the PEP 484 spelling. Previously you had to use if MYPY instead of if TYPE_CHECKING. Requires version of the typing package.
  • Support for bytes formatting (e.g. b'foo%d' % 42) in Python 3.5 and up, per PEP 461. (Buck Baskin)
  • Several improvements to namedtuple and NamedTuple , e.g. _replace() and _fields are now supported. (Elazar Gershuni)
  • Mypy is now less aggressive about shortening types in error messages. E.g. previously a union with four or more values would often be replaced with union type (4 items), and similar for tuples. This now doesn’t happen unless the text would be over 400 characters.
  • Modest performance improvements.
  • Several miscellaneous bug fixes.
  • Lots of updates to the library stubs in typeshed.

Stub Generator

  • Improvements to the generated stubs. (Valérian Rousset)
  • Add --recursive and --ignore-errors flags. (Raphael Gaschignard)


We’d like to thank Michael Lee whose internship ended during this release cycle. He made --incremental worthy of trust and also contributed many other fixes (including documentation). Thanks Michael!

Thanks to all mypy contributors who contributed to this release:

  • Ben Duffield
  • Buck Baskin
  • David Foster
  • Elazar Gershuni
  • Ivan Levkivskyi
  • John Hagen
  • Raphael Gaschignard
  • Valérian Rousset

Additional thanks to these contributors to typeshed:

  • Alvaro Caceres
  • claws
  • Danny Weinberg
  • David Euresti
  • dlinnemeyer
  • Drew Haven
  • Elazar Gershuni
  • Evgeniy Vasilev
  • Gustavo J. A. M. Carneiro
  • Ivan Levkivskyi
  • John Hagen
  • Manuel Krebber
  • Matthias Kramm
  • Ollie Wild
  • rchen152
  • Rich Li
  • Robin Alazard
  • Roy Williams
  • Samuel Colvin
  • Sebastian Meßmer
  • Stephen Thorne
  • Tim Abbott
  • Valérian Rousset
  • Yasushi Saito

— Jukka (on behalf of the rest of the mypy team: Guido, David and Greg)

Thursday, 25 August 2016

Mypy 0.4.4 Released

I just uploaded version 0.4.4 of mypy-lang to PyPI! This release adds several new features, bug fixes and library stub updates.

Run this to upgrade to the new release using pip:

    python3 -m pip install -U mypy-lang

Experimental async and await Support

Mypy can now type check code using async and await (PEP 492). Here is an example from the documentation (this requires --fast-parser):

    import asyncio

    async def format_string(tag: str, count: int) -> str:
        return 'T-minus {} ({})'.format(count, tag)

    async def countdown_1(tag: str, count: int) -> str:
        while count > 0:
            my_str = await format_string(tag, count)  # has type 'str'
            await asyncio.sleep(0.1)
            count -= 1
        return "Blastoff!"

    loop = asyncio.get_event_loop()
    loop.run_until_complete(countdown_1("Millennium Falcon", 5))


You can use NewType (see documentation) to define a special lightweight variant of an existing type. Mypy considers it to be a separate type, but there’s only minimal runtime overhead, as it doesn’t define a new class. We can create a new type called UserId, instances of which are actually int objects at runtime, but which is treated like a subclass of int by mypy:

    from typing import NewType

    UserId = NewType('UserId', int)

    def name_by_id(user_id: UserId) -> str:

    name_by_id(42)          # Type check error -- UserId expected
    name_by_id(UserId(42))  # OK
    print(UserId(42))       # 42 (the runtime representation is just int)

Additional Changes

Here is list of other notable changes in this release:

  • Support checks for sys.version_info and sys.platform, which are especially useful for stubs (see documentation)
  • Add the --platform command line option to explicitly set the target platform, instead of defaulting to the current platform
  • Support *expr within list, tuple and set expressions, and **expr within dict expressions (requires --fast-parser)
  • Incremental type checking is now more robust (--incremental)
  • Strict optional checking is also more robust (--strict-optional)
  • Many bugs fixed (especially crashes)
  • Lots of typeshed improvements
  • Documentation updates
  • Warn about unused type ignores on imports with --warn-unused-ignores
  • Add --suppress-error-context flag to suppress notes about class/function (this cleaner output mode may become the default in the future)
  • Less output by default on internal error (use --tb to show traceback)
  • Removed the need for -f /--dirty-stubs during mypy development
  • Started transitioning to using pytest for the mypy test suite (PR #1944)


Thanks to all mypy contributors who contributed to this release:
  • Daniel F Moisset
  • Fabian Heredia Montiel
  • Roy Williams
  • Ryan Gonzalez
  • Shrey Desai
  • Valérian Rousset
Additional thanks to typeshed contributors:
  • Alvaro Caceres
  • Antoine Catton
  • Daniel Horn
  • Daniël van Eeden
  • David Euresti
  • Elazar Gershuni
  • Emanuel Barry
  • Fu Yong Quah
  • Jakub Stasiak
  • Matthias Kramm
  • Max Wittek
  • Michael R. Crusoe
  • Nicholas Bishop
  • Tom Manderson
  • Tomasz Elendt
  • Tyler O'Meara
  • Wojciech Kaczmarek
  • Alvaro Caceres
  • jchien14
  • jdelic
  • John K Lai
  • kosaka
  • peterdotran
  • speezepearson
  • Tony Grue
  • wreed4

- Jukka (on behalf of the rest of the mypy team: Guido, David, Greg and Michael Lee)

Thursday, 14 July 2016

Mypy 0.4.3 Released

I just uploaded version 0.4.3 of mypy-lang to PyPI! This release adds several new features (some of which are still experimental), bug fixes and library stub updates.

Run this to upgrade to the new release using pip:

    python3 -m pip install -U mypy-lang

Strict Checking of Optional Types

Mypy now supports strict checking of optional types (enable it through --strict-optional). The option makes mypy check that you don’t try to perform unsupported operations on None values, and that you don’t use None values when a non-Optional value is expected.

This feature is still experimental and has known issues. Our intention is to turn this on by default in a future mypy release, once it works well enough.

Here is an example buggy program that mypy will reject only if you use --strict-optional:

    from typing import Optional, List

    def read_data_file(path: Optional[str]) -> List[str]:
        with open(path) as f:  # Error

Mypy will rightly complain about the program, since open() does not accept a None argument — and path may be None. Luckily, it’s easy to fix the program:

    from typing import Optional, List

    DEFAULT_PATH = '...'

    def read_data_file(path: Optional[str]) -> List[str]:
        if not path:
            path = DEFAULT_PATH
        with open(path) as f:  # OK!

Mypy recognizes that if the not path condition isn’t true and the if statement body is not executed, path won’t be None. It also knows that after the assignment statement that I added path can’t be None, so now the open(path) call is always safe, no matter which execution path is taken.

The example shows that mypy can do pretty clever reasoning about code. Mypy also knows about other kinds of None checks — go ahead and give it a try.

Multi-line Comment Function Annotation Syntax

You can now use an alternative per-argument comment annotation syntax for code that needs to be Python 2 compatible. Previously, functions with a long argument list resulted in overly long type comments and it was tricky to see which argument type corresponds to which argument.

Note: This only works when using --fast-parser. This isn’t supported on Windows yet. (We intend to use --fast-parser by default in a future release, but only once it works on Windows.)

Here is an example (from PEP 484):

    def send_email(address,     # type: Union[str, List[str]]
                   sender,      # type: str
                   cc,          # type: Optional[List[str]]
                   bcc,         # type: Optional[List[str]]
                   body=None    # type: List[str]
        # type: (...) -> bool
        """Send an email message.  Return True iff successful."""

Additional Changes

Here are the remaining notable changes in this release:

  • Improve how mypy deals with module cycles. When adding a new module to a cycle, mypy is less likely to generate unrelated-looking errors from other modules in the cycle.
  • Mypy more aggressively infers types for variables initialized with literals, instead of requiring a dummy annotation. Previously you sometimes had to write code like x = 0 # type: int which was a little silly.
  • Infer types from multiple isinstance checks or’ed together, such as isinstance(x, int) or isinstance(x, str). The inferred type is a union type.
  • Add option --warn-unused-ignores that gives a warning if you use # type: ignore on a line that actually doesn’t generate an error and thus may be redundant.
  • Add option --warn-redundant-casts that gives a warning if you have a cast that is superfluous and can be removed without generating an error.
  • Fixes and improvements to incremental type checking. Add option --cache-dir for specifying a custom custom incremental cache directory. Note that incremental type checking is still experimental.
  • Fixes to Type[C].
  • Other bug fixes.
  • Typeshed stub updates.
  • Python 3.2 is no longer officially supported for running mypy. (This does not affect type checking Python 3.2 programs.)


Thanks to all mypy contributors who contributed to this release:

  • Carol Willing
  • Eric Price
  • Herbert Ho
  • Max Wittek
  • Michael Lee
  • Russ Allbery

Additional thanks to typeshed contributors:

  • Alvaro Caceres
  • Amandine Lee
  • Amit Saha
  • Brett Cannon
  • Dakkaron
  • Drew Haven
  • Eklavya Sharma
  • Elazar
  • Fu Yong Quah
  • Herbert Ho
  • Håken Lid
  • Matthias Kramm
  • Michael Lee
  • Mickaël S
  • Oren Leaffer
  • Phil Jones
  • Philip House
  • Russ Allbery
  • Skip Montanaro
  • Valérian Rousset
  • garetht
  • tewe
  • Thomas Cellerier

- Jukka (on behalf of the rest of the mypy team: Guido, David, Greg and Reid)

Thursday, 9 June 2016

Mypy 0.4.2 Released

I just uploaded version 0.4.2 of mypy-lang to PyPI! This is a minor release that focuses on bug fixes.

The biggest change is the addition of Type[C]. You can now accurately describe the type of an argument whose type is itself a type or class. Given a class C, a function argument annotated with Type[C] can be a class object that's either C or a subclass of C. You can call C's class methods on that argument, and instantiate it using the constructor signature(s) supported by C. Combined with a type variable with C as an upper bound you can do even more powerful things. The Type operator must be imported from the typing module. It will be available starting Python 3.5.2. See the description in PEP 484.

Note: To use typing.Type[C], you need Python 3.5.2 (to be released shortly) or you can pip install the latest version of typing.

These are the other notable changes in this release:

  • Add reveal_type(expr) for displaying the static type of an expression.
  • Better IntEnum support.
  • Get the latest version of typing from python/typing repo (for Python 3.4 and earlier that don't include typing in stdlib).
  • When both* and foo/* exist, prefer the latter.
  • Suppress error about untyped defs in typeshed stubs.
  • Fix use of property in a NamedTuple class.
  • Fix how the fast parser interprets string literals in Python 2.
  • Other bug fixes.
  • Typeshed stub updates.
  • Documentation updates, such as a type annotation cheat sheet.
  • Stop testing running mypy with Python 3.2. We’ll likely drop support for running mypy itself with 3.2 pretty soon, though you'll still be able to type check Python 3.2 code.


Thanks to all mypy contributors who contributed to this release:

  • Akshit Khurana
  • Andrew Sprenchynat
  • Babak
  • Jakub Stasiak
  • Jeffrey McLarty
  • Josh Soref
  • Justus Adam
  • Margaret Sy
  • Max Wittek
  • Peter McCormick
  • Ryan Gonzalez
  • Tarashish Mishra
  • Thiago
  • Tim Abbott
  • Thomas Ballinger
  • Valérian Rousset

Additional thanks to typeshed contributors:

  • beckjake
  • Dakkaron
  • David Euresti
  • David Shea
  • detlefla
  • Eklavya Sharma
  • Erin Haswell
  • Florian Bruhin
  • Jakub Stasiak
  • James Tatum
  • jukebox
  • Max Payton
  • Michael R. Crusoe
  • Oren Leaffer
  • Ran Benita
  • Thomas Grainger
  • Tim Abbott
  • Tim Simpson
  • Vadim Chugunov
  • Valérian Rousset
- Jukka (on behalf of the rest of the mypy team: Guido, David, Greg and Reid)

Tuesday, 31 May 2016

Slides for Mypy Talk At PyCon

The mypy team gave a talk about mypy at PyCon 2016 on Sunday, the day before the main conference. The slides are available here:

Thanks to all who were able to attend!

The talk wasn't recorded (which is particularly unfortunate since David Fisher gave an awesome live demo).

- Jukka