I just uploaded version 0.4 of mypy-lang to PyPI! This release focuses on performance improvements, usability improvements and bug fixes. Again, there are too many changes to describe them all. I'll focus here on the most important ones.
I'm also happy to welcome a new mypy core developer, Reid Barton. Reid is supported by Dropbox, like the rest of the core team.
As before, mypy is experimental and still has known bugs and limitations, though things are quickly getting better. Library stubs for many commonly used modules are still missing, but now there is the option --silent-imports (which was supported by 0.3.1, but poorly documented) that can work around this issue by ignoring missing stubs, at the cost of some type checking precision.
These are some of the most exciting new things:
- Experimental incremental type checking mode (enabled via --incremental or -i) speeds up type checking large programs significantly by reusing cached results from previous type checking runs. If you’ve only made small changes, type checking can now be much faster. We plan to enable this by default once we’ve given it a little more time to mature. (By Guido)
- David Fisher implemented a new experimental parser that uses a tweaked version of the standard library ast module to parse programs. This gives a nice performance boost and can be enabled via --fast-parser. (You must first pip install typed-ast for this to work. Note that it doesn't support Python 3.2.)
- Mypy now supports type variable bounds, i.e. TypeVar(…, bound=…), as specified by PEP 484. (By Reid Barton)
- Many crashes and bugs fixed (and a few added :-).
- A ton of typeshed updates.
Command Line Changes
There are several new command line options:
- --fast-parser enables the new, faster parser (see above). This is still experimental but worth a try!
- --disallow-untyped-defs generates errors for functions without type annotations. Consider using this if you tend to forget to annotate some functions.
- --disallow-untyped-calls causes mypy to complain about calls to untyped functions. This is a boon for static typing purists, together with --disallow-untyped-defs :-)
- --line-count-report DIRECTORY generates a report of annotated line counts.
- --almost-silent behaves like --silent-imports, but it also reports every module that was silently ignored. This is useful for troubleshooting if mypy doesn’t seem to find all the code you are expecting.
Some old options or arguments are now a little more useful:
- When given a directory as a positional argument, mypy now always looks into the directory and any subpackages of the directory and includes every .py or .pyi file that it finds there. It also does the right thing if the target directory is a package. (The old behavior was surprising and better not discussed any further.)
- Documented the --silent-imports / -s command-line option for silently ignoring missing modules.
- Support multiple -m options.
- --implicit-any was renamed to --check-untyped-defs. It causes mypy to do rudimentary type checking even in unannotated functions. Be default, mypy mostly ignores unannotated functions. It’s still better to annotate functions, but this can provide some light type checking for almost free.
A few options were removed or deprecated:
- --silent is deprecated (use -s or --silent-imports, which do the same thing)
- --use-python-path is disabled because it’s rarely the right thing to do and has resulted in much confusion. --silent-imports often gives better results.
Python 2 Support
There were only a few changes to Python 2 language support — it’s now pretty mature:
- A function annotation like # type: (...) -> rtype (that’s a literal ...) specifies only the return type of a function without having to enumerate all the argument types (they default to Any).
- Parse lambda (x): y correctly.
(Support for PEP 484 long argument list annotations for Python 2 will be included in the next release.)
Type Checking Improvements
- Support bare Callable types (#670)
- The first argument of a class method now has a real type (it used to be Any)
- Fix various issues around generics, type variables and type inference
- Fix error messages when the type of *args or **kwds is wrong
- Compute type of inherited constructor correctly (#1246)
- Add typing.DefaultDict
- Support calling dict() with positional arguments and keyword arguments or **kwds (#1391)
- Some improvements to handling of import cycles, forward references and decorators
- Some improvements to conditional imports and definitions (still more to do)
- Improve type inference of  if ... else [something]
- Suppress (most) errors from semantic analysis for unannotated functions (#1334)
- We’ve now got a nice CONTRIBUTING.md file (thanks, Greg Price!)
- Fixed many bugs in report generation, e.g. correct support for multiple files (also by Greg)
- Improved algorithm for finding data files (e.g. typeshed) when installed on various platforms
- “Regular” errors are written to stdout; errors about command line or files to stderr
- Added a .bat file for running mypy on Windows
- Various speedups (also by Greg -- even the test suite was made much faster!)
- Improved processing of internal errors
Here's a list of everybody who contributed to the mypy repository since the last release. Thanks to everybody who helped! Apologies if I've missed anybody.
- Alex Brandt
- Ben Darnell
- Brett Cannon
- Chris (allthedata)
- Dmitriy Olshevskiy
- Ivan Levkivskyi
- Keith Philpott
- Kevin Modzelewski
- Max Wittek
- Michał Zochniak
- Paul Kienzle
- Reid Barton
- Ryan Gonzalez
- Samuel Colvin
- Vytautas Astrauskas
Also thanks to everybody who contributed to typeshed:
- Alessio Bogon
- Anirudha Bose
- Ben Darnell
- David Soria Parra
- Drew Haven
- Filip Hron
- Hong Minhee
- Isaac Goldberg
- Ivan Levkivskyi
- Jakub Stasiak
- James Tatum
- Julien Hebert
- Katherine Lai
- Linjie Ding
- Lorenzo Bolla
- Martin Geisler
- Matthias Kramm
- Max Wittek
- Maxim Kurnikov
- Michael Lee
- Michael R. Crusoe
- Reid Barton
- Sidharth Kapur
- Valérian Rousset
- Yasushi Saito
- Yusuke Miyazaki
Additional thanks to Guido and the rest of the core team for helping with this blog post.
- Jukka (on behalf of the mypy team)