Friday, 12 July 2019

Mypy 0.720 Released

We’ve just uploaded mypy 0.720 to the Python Package Index (PyPI). Mypy is a static type checker for Python. This release features a new semantic analyzer and optional warnings about unreachable code. It also includes many other new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the full documentation for this release on Read the Docs.

New Semantic Analyzer Used by Default

The new semantic analyzer was introduced in mypy 0.710 and is now the default. The old analyzer is still available under --no-new-semantic-analyzer, but it will be removed in the next mypy release. This release includes many improvements to the new semantic analyzer.

The semantic analyzer is a component of mypy that binds names to definitions. It also keeps track of what sort of thing each name defines, such as a function or a type alias. The new semantic analyzer is a major redesign and achieves several things.

The old semantic analyzer ordinarily processes files in a linear order, from the beginning to the end. This is subtly different in the mypy daemon, which sometimes processes an individual function or a module top level (code not nested within a function) as a single unit. The new semantic analyzer unifies mypy behavior by always analyzing module top-levels separately, before analyzing functions. As a bonus, this more closely reflects Python runtime behavior, since modules are usually fully initialized before any functions are called.

The old semantic analyzer processes each module in an import cycle twice, in an order determined by complicated heuristics. This can cause bogus errors when there are references to another module that hasn’t been processed yet in a dependency cycle. The new analyzer processes modules in a flexible order, and references across an import cycle work significantly more reliably.

The old semantic analyzer can’t always deal with forward references to definitions. The new semantic analyzer improves support for forward references. Example where this helps:

    from typing import NamedTuple
    
    f = lambda: A(1)  # This forward reference now works
    
    A = NamedTuple('A', [('x', int)])
    
    f()

The new semantic analyzer is stricter than the old semantic analyzer. It catches additional type errors and quality issues. Existing code that passes type checking may require small adjustments.

New Feature: Warn about Unreachable Code

If you run mypy with --warn-unreachable, mypy will warn you about unreachable statements, and expressions that may be never evaluated because of short circuiting. For example:

    from typing import Text
    
    def emphasize(text: Text) -> Text:
        if isinstance(text, int):
            text += 1  # Error: statement is unreachable
        return text.upper()

See the documentation for more information. This feature was contributed by Michael Lee.

Plugin API Changes

The new semantic analyzer may require changes to mypy plugins. We have a GitHub issue with more information for maintainers of plugins.

Notable Improvements and Bug Fixes

  • Have --package usage respect mypy_path (Aaron Batilo, PR 6926)
  • Support flexible option specification in config files. Now all the flags support invertible forms so that one can specify either strict_optional = False or no_strict_optional = True. This matches how flags work on the command line (PR 7054)
  • Fix reachability inference with isinstance(Any, Any) (Michael Lee, PR 7048)
  • Fix mypyc crash with plugins using get_customize_class_mro_hook() (PR 7075)
  • Fix slicing tuples with non-literal expressions (Ethan Smith, PR 7066)
  • Fixes to column numbers in error messages (PR 7078, PR 7081)
  • Make Need type annotation for variable error more consistent (PR 7079, PR 7113)
  • Fix error reporting context for missing generic type arguments (PR 7100)
  • Use only directories containing no __init__.py as namespace packages (Arne Welzel, PR 7108)
  • Support method plugin hooks on union types (PR 6560)
  • Fix some corner cases in --strict-equality (PR 7156, PR 7164)
  • Fix binding of self-types on unions (PR 7152)
  • Add more details for Invalid type errors (PR 7166)
  • Fix custom __init__() in dataclasses (Ryan Gonzalez, PR 7168)
  • Better support for indexing with unions of literal types (Michael Lee, PR 6558)

Other Updates

You can browse the full commit log here.

Typeshed Updates

Many small improvements were made to typeshed — too many to list. Browse the typeshed commit log here.

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • Aaron Batilo
  • Arne Welzel
  • Chad Birch
  • Daniel Hahler
  • Deepyaman Datta
  • Ethan Smith
  • Michael Lee
  • Rafi Blecher
  • Ryan Gonzalez

Additional thanks to all contributors to typeshed:

  • Benjamin Woodruff
  • Chad Dombrova
  • Cole Maclean
  • crusaderky
  • Eric Arellano
  • Florian Ludwig
  • Francis Colas
  • Gordon Ball
  • Hynek Schlawack
  • ikelos
  • Jason Gilholme
  • Jelle Zijlstra
  • Maarten ter Huurne
  • Martijn Pieters
  • Mathieu Bridon
  • Matthew Wilkes
  • Motoki Naruse
  • Rafi Blecher
  • Ran Benita
  • Rebecca Chen
  • redshiftzero
  • Rune Tynan
  • Sam Zhou
  • Savo Kovačević
  • Sebastian Rittau
  • 秋葉
— Ivan Levkivskyi, on behalf of the mypy team