Wednesday 15 December 2021

Mypy 0.920 Released

We’ve just uploaded mypy 0.920 to the Python Package Index (PyPI). Mypy is a static type checker for Python. This release includes new features and bug fixes. 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.

Making a Variable Optional in an Else Block

Now mypy allows more general conditionally defined variables with optional types. Previously mypy allowed this only if a None assignment happened first. Now this is also supported:

    def func() -> int: ...
    
    if test():
        x = func()
    else:
        x = None  # Ok, 'x' has type int | None

Implemented by Michael J. Sullivan in PR 11002.

Type Checking __slots__ Assignment

For classes that define the special __slots__ attribute, mypy will now report an error on assigning to attributes that are not found in the slots definitions (this matches runtime semantics). Example:

    class SuperClass:
        __slots__ = ("a",)
    
    class SubClass(SuperClass):
        __slots__ = ("b",)
        def __init__(self) -> None:
            self.a = 1  # OK
            self.b = 2  # OK
            self.c = 3  # Error, previously mypy allowed this.

Note that this feature does not work for dynamically computed slots. Implemented by Nikita Sobolev in PR 10864.

Partial Python 3.10 Support

We now ship binary wheels for Python 3.10 and mypy supports the new Python 3.10 union type syntax:

  • X | Y is the new syntax for Union[X, Y]
  • X | None is the new syntax for Optional[X].

Some new features, including the match statement, ParamSpec and TypeAlias are not supported yet.

Python 3.5 Is No Longer Supported

Python 3.5 reached its end of life more than a year ago. Its support was deprecated in mypy 0.910 and it is no longer supported in mypy 0.920.

Efficient String and Bytes Formatting in Mypyc

Most string and bytes formatting methods now use fast C-level logic when compiled with mypyc. This includes % formatting, the format() method, and f-strings. This was implemented by 97littleleaf11 as part of a Google Summer of Code project.

Work Towards singledispatch Support

Mypy and mypyc now have experimental support for functools.singledispatch. Here is a simple example:

    from functools import singledispatch
    
    class Expression: pass
    
    class Literal(Expression):
        def __init__(self, value: float) -> None:
            self.value = value
    
    class Add(Expression):
        def __init__(self, left: Expression, right: Expression) -> None:
            self.left = left
            self.right = right
    
    @singledispatch
    def evaluate(e: Expression) -> float:
        assert False, f"unsupported expression: {e}"
    
    @evaluate.register
    def _(e: Literal) -> float:
        return e.value
    
    @evaluate.register
    def _(e: Add) -> float:
        return evaluate(e.left) + evaluate(e.right)
    
    print(evaluate(Literal(2)))
    print(evaluate(Add(Literal(3), Literal(5))))

The signature of the initial function variant handles the generic case and describes the external signature of the singledispatch function.

This was implemented Pranav Rajpal as part of a Google Summer of Code project.

Stubgen Improvements

  • Add support for yield statements in stubgen (Sebastian Rittau, PR 10745)
  • Handle commas in namedtuple field definition in stubgen (Vanessa Ung, PR 10828)

Other Notable Fixes and Improvements

  • Allow plugin signature hooks to return FunctionLike (to support overloads) (pranavrajpal, PR 10717)
  • Narrow type with type variable when the upper bound is a subtype of current type (ethframe, PR 10658)
  • Make --cache-fine-grained imply --local-partial-types (Michael J. Sullivan, PR 10737)
  • Support new union syntax in stubs independent of target Python version and in runtime context (PR 10770, PR 10771) (Jukka Lehtosalo)
  • Support new union type syntax with isinstance() (Jukka Lehtosalo, PR 10775)
  • Better message if method is incompatible with base class (Anmol Takiar, PR 10572)
  • Allow redefinition of underscore functions (named '_') (pranavrajpal, PR 10811)
  • Properly track positional-only arguments for unannotated functions (Michael J. Sullivan, PR 10802)
  • Fixes to type checking %c string and bytes interpolation (97littleleaf11, PR 10869)
  • Use better error message for %c interpolation (97littleleaf11, PR 10875)
  • Skip overlapping overload checks in ignored files (Shantanu, PR 10922)
  • Fix ad hoc instance intersection logic (Christoph Tyralla, PR 9909)
  • Support tuple multiplication with literal integers (hatal175, PR 10361)
  • Fix recursion issue with nested instances and unions (Peilonrayz, PR 9663)
  • Fix caching behavior of PEP561-installed namespace packages (Michael J. Sullivan, PR 10937)
  • Add __dataclass_fields__ and __attrs_attrs__ to dataclasses (Timofey Kukushkin, PR 8578)
  • Fix argument checking on empty dict with double stars (Momoko Hattori, PR 9629)
  • Fix some type-guard-related crashes (Shantanu, PR 11061)
  • Reject raise Err if Err can’t be called without arguments (Nikita Sobolev, PR 11125)
  • Fix TypedDict crash with function definition (Nikita Sobolev, PR 11126)
  • Report attribute access errors for type variable bound to a union (Christoph Tyralla, PR 11140)
  • Fix crash on dataclasses.field(unpack) (Nikita Sobolev, PR 11137)
  • Fix crash related to ParamSpec in mypy daemon (Jukka Lehtosalo, PR 11567)
  • Properly type check *CustomType and CustomType function arguments (Nikita Sobolev, PR 11151)
  • Fix crash with overload and callable object decorators (Shantanu, PR 11630)
  • Fix crash involving explicit reexport, import cycle, and a wildcard (Shantanu, PR 11632)

Mypyc Features, Fixes, and Performace Improvements

  • Fix class-based named tuples (Jukka Lehtosalo, PR 10746)
  • Add a special case for len() of a string value (97littleleaf11, PR 10710)
  • Reject instance attribute access through class object (Jukka Lehtosalo, PR 10798)
  • Speed up the construction of list objects (97littleleaf11, PR 10807)
  • Add bytes primitive type (97littleleaf11, PR 10881)
  • Add bytearray support (97littleleaf11, PR 10891)
  • Optimize construction via list() and dict() (Richard Si, PR 10918)
  • Speed up bytes join() method (jhance, PR 10929)
  • Speed up len(bytes) (97littleleaf11, PR 10936)
  • Speed up bytes indexing and slicing (PR 10966, PR 10950) (97littleleaf11)
  • Speed up bytes.decode() and str.encode() (PR 10974, PR 10951) (97littleleaf11)
  • Speed up bytes equality checks (jhance, PR 10928)

Documentation Improvements

  • Add docs about exhaustive literal and enum checks (Nikita Sobolev, PR 10860)
  • Add ‘or’ regular expression example to --exclude documentation (Niklas Gustafsson, PR 10903)
  • Document per-module follow_imports more explicitly (Shantanu, PR 10845)
  • Add docs for the TypeGuard type (Nikita Sobolev, PR 10758)
  • Update type narrowing section in common issues (Nikita Sobolev, PR 11014)
  • Document how --no-implicit-reexport handles from X import Y as Z (Max Marrone, PR 11083)
  • Document strict config file option (Anders Kaseorg, PR 11132)
  • Add better type narrowing documentation (Nikita Sobolev, PR 11088)
  • Add documentation about := and type guards (Nikita Sobolev, PR 11161)

Typeshed Updates

Typeshed is now modular and distributed as separate PyPI packages for everything except the standard library. Please see git log for full list of typeshed changes.

Acknowledgements

Thanks to all mypy contributors who contributed to this release:

  • 97littleleaf11
  • Abdul Rehaman
  • Anders Kaseorg
  • Anmol Takiar
  • Anton Agestam
  • Chad Dombrova
  • Christoph Tyralla
  • Daniel Hahler
  • Dong-hee Na
  • Elisha Hollander
  • Ethan Smith
  • ethframe
  • geo7
  • hatal175
  • Hugues
  • Ilya Konstantinov
  • Jared Hance
  • Kevin Wojniak
  • KotlinIsland
  • Louis Sautier
  • Max Marrone
  • Mehdi ABAAKOUK
  • Michael J. Sullivan
  • Michael R. Crusoe
  • Momoko Hattori
  • Nikita Sobolev
  • Niklas Gustafsson
  • Nipunn Koorapati
  • Peilonrayz
  • pranavrajpal
  • Richard Si
  • ryan-gunderson
  • Sebastian Rittau
  • sed-i
  • Shantanu
  • Taneli Hukkinen
  • Tim Gallant
  • Timofey Kukushkin
  • Vanessa Ung
  • Zac Hatfield-Dodds

We’d also like to thank our employer, Dropbox, for funding the mypy core team.