Wednesday, 22 December 2021

Mypy 0.930 Released

We’ve just uploaded mypy 0.930 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.

New Feature: Explicit Type Aliases (PEP 613)

You can now explicitly mark an assignment as a type alias, by using typing.TypeAlias:

    # On Python 3.9 and earlier, use "from typing_extensions ..."
    from typing import TypeAlias

    A: TypeAlias = int | str

For more context, see the docs or PEP 613.

This was contributed by Shantanu in PR 11305.

New Feature: NotRequired in TypedDicts

You can now define individual TypedDict items as non-required by using typing_extensions.NotRequired. Previously this could only be configured at TypedDict level (by using total=). Example:

    from typing import TypedDict
    from typing_extensions import NotRequired

    class D(TypedDict):
        x: str
        y: NotRequired[int]

    a: D = {"x": "value"}  # OK
    b: D = {"x": "value", y: 0}  # OK
    c: D = {}  # Error: "x" is required

You can also use typing_extensions.Required to mark an item as required in a non-total TypedDict.

For more information, see the draft PEP 655.

This was contributed by David Foster in PR 10370.

New Feature: ParamSpec (Experimental)

Mypy now partially support ParamSpec, which was introduced in Python 3.10. This makes it possible to define type variables that range over the parameter specification of a callable type. In particular, it allows giving precise types for some decorators that change the return type of the decorated function.

Here’s an example copied (and slightly modified) from PEP 612:

    from typing import Awaitable, Callable, ParamSpec, TypeVar

    P = ParamSpec("P")
    R = TypeVar("R")

    def add_logging(f: Callable[P, R]) -> Callable[P, Awaitable[R]]:
        async def inner(*args: P.args, **kwargs: P.kwargs) -> R:
            await log_to_database()
            return f(*args, **kwargs)
        return inner

    @add_logging
    def takes_int_str(x: int, y: str) -> int:
        return x + 7

    await takes_int_str(1, "A")  # Accepted
    await takes_int_str("B", 2)  # Rejected

See Python documentation and PEP 612 for additional details. Note that typing.Concatenate and some other use cases are still not supported.

Support for semantic analysis of ParamSpec was contributed by Shantanu. Jukka Lehtosalo implemented type checking of ParamSpec types. Additional fixes were contributed by Nikita Sobolev.

Miscellaneous New Features

  • Define a GitHub Action that makes it easier to run mypy in GitHub CI workflows (Elvis Pranskevichus, PR 11320)
  • Allow mypy to run self check on PyPy 3.8 beta (Ethan Smith, PR 11350)
  • Check that enum values are unique (Nikita Sobolev, PR 11267)
  • Make enum classess with values implicitly final (Nikita Sobolev, PR 11247)
  • Make enum members implicitly final (Nikita Sobolev, PR 10852)
  • Allow NamedTuple to be used as a type that accepts all named tuples, as an experimental extension (Nikita Sobolev, PR 11162)
  • Allow booleans to be narrowed to literal types (Ethan Leba, PR 10389)
  • Add slots=True support for @dataclass (Nikita Sobolev, PR 11483)
  • Add slots=True support for @attr.s (Nikita Sobolev, PR 11489)
  • Support the typing_extensions.OrderedDict alias (Nikita Sobolev, PR 11533)

Usability and Documentation Improvements

  • Add better NamedTuple error messages (Nikita Sobolev, PR 11127)
  • Show all overloads in error message (Akuli, PR 9177)
  • Fix error message for dataclasses.field with positional argument (Hiroshi Ogawa, PR 11180)
  • Fix error message for f-string and str-bytes-safe (Nikita Sobolev, PR 11139)
  • Add documentation for type: ignore (Tushar Sadhwani, PR 11358)
  • Support --exclude more than once on command line (Nipunn Koorapati, PR 11329)
  • Use list[int] instead of List[int] in documentation (PR 11377, PR 11450) (Nick Crews)
  • Remove builtins. from error messages (97littleleaf11, PR 11522)
  • Document explicit type aliases (Nikita Sobolev, PR 11800)
  • Improve documentation of annotating generator functions (Alex Waygood, PR 11623)
  • Improve error message for nested TypedDict (97littleleaf11, PR 11658)
  • Exit gracefully on KeyboardInterrupt (Marc Mueller, PR 10725)

Optimizations

This release includes some optimizations that make mypy a bit faster (in addition to mypyc performance improvements discussed below):

  • Enable --fast-exit by default to speed up mypy (Jukka Lehtosalo, PR 11541)
  • Only read the stdlib versions dictionary once per run (Jukka Lehtosalo, PR 11542)
  • Optimize commonly used function (Jukka Lehtosalo, PR 11543)
  • Minor optimization/cleanup (Jukka Lehtosalo, PR 11544)
  • Reduce the number of executed local imports (Jukka Lehtosalo, PR 11545)

Mypyc Fixes and Improvements

  • Add missing type coercions (Jared Hance, PR 11176)
  • Support --allow-redefinition (Jared Hance, PR 11175)
  • Constant fold integer operations and string concatenation (Jukka Lehtosalo, PR 11194)
  • Use optimized implementation for builtins.sum (Sara Sinback and 97littleleaf11, PR 10268)
  • Move mypyc to console_scripts to fix running on Windows 10 (谭九鼎, PR 11494)
  • Make min(x, y) faster(Chetan Khanna and 97littleleaf11, PR 10265)
  • Make max(x, y) faster (97littleleaf11, PR 11530)
  • Speed up reference counting operations by inlining them in commonly executed blocks (Jukka Lehtosalo, PR 11540)
  • Add support for attrs classes (Chad Dombrova, PR 11328)
  • Port mypyc to Python 3.11 (Victor Stinner, PR 11652)
  • Reduce the amount of debug information included in compiled extension modules (Nehal J Wani, PR 11526)

Other Notable Fixes and Improvements

  • Fix semantic analysis of assignment expressions (Shantanu, PR 11153)
  • Fixes mypy crash on protocol with contravariant variable (Nikita Sobolev, PR 11135)
  • Warn about unused ignores when not all specified error codes are used (Hiroshi Ogawa, PR 11178)
  • Improve type narrowing for walrus operator in conditional statements (Shantanu, PR 11202)
  • Fix literal type compatibility checking special case (Nikita Sobolev, PR 11236)
  • Rename API method builtin_type to named_type (97littleleaf11, PR 11224)
  • Fix narrowing information not propagated in assignment and boolean expressions (Ran Benita, PR 11207)
  • Fix narrowing of a nested union of TypedDicts (Ran Benita, PR 11204)
  • Fix case mismatching modules during namespace package search (Nipunn Koorapati, PR 11261)
  • Disallow invalid identifiers from getting implicit bazel __init__.py (Nipunn Koorapati, PR 11268)
  • Don’t type check lambdas nested in unchecked functions (Nikita Sobolev, PR 11213)
  • Update None.__bool__ to return Literal[False] (Nikita Sobolev, PR 11290)
  • Relax type checking of % formatting when the right operand is an iterable (97littleleaf11, PR 11319)
  • Fix crash with namespace packages when generating html reports (Nikita Sobolev, PR 11338)
  • Allow slice syntax in Annotated types (Zac Hatfield-Dodds, PR 11345)
  • Show warning if self / cls argument is missing (Nikita Sobolev, PR 11317)
  • Improve subtype checking of TypeGuard types (Nikita Sobolev, PR 11314)
  • Fix type narrowing for overlaping runtime types (Nikita Sobolev, PR 11273)
  • Do not use TypeGuard context for lambda (Nikita Sobolev, PR 11417)
  • Check reachability in module bodies (Nikita Sobolev, PR 11361)
  • Check that __new__ in a metaclass returns a subtype of type (Nikita Sobolev, PR 11420)
  • Improve support of contextlib.asynccontextmanager (Barnaby Shearer, PR 11352)
  • Discard deprecated builtin_type (97littleleaf11, PR 11343)
  • Don't look in user site packages when using a virtual env (Dimitri Merejkowsky, PR 11444)
  • Update stubgen to preserve string literals in annotations (Imad Eddine Rezgui, PR 11292)
  • Fix issue with exporting names in the presence of __getattr__ (Shantanu, PR 11411)
  • Reject duplicate bases when defining TypedDict (97littleleaf11, PR 11485)
  • Fix type inference for index expression with a bounded TypeVar (Ilya Labun, PR 11434)
  • Fix get_dynamic_class_hook in some scenarios (Jade Lin, PR 10904)
  • Check print >> properly (Nikita Sobolev, PR 11576)
  • Correctly handle cls in protocol classmethod (Ilia Novoselov, PR 11119)
  • Use current Python version, rather than hardcoding 3.6, in stubgen (Shantanu, PR 10907)
  • Don't use ModuleType.__getattr__ if we know module symbols (Jukka Lehtosalo, PR 11597)
  • Fix strict equality when using the latest typeshed (Jukka Lehtosalo, PR 11599)
  • Make sure ClassVar does not contain type variables (Nikita Sobolev, PR 11585)
  • Allow overriding attributes with methods (Nikita Sobolev, PR 11561)
  • Don’t generate an error for PEP 593 Annotated with a string literal second argument (Seth Yastrov, PR 10777)
  • Install types to the correct environment (Konstantin Weddige, PR 11457)
  • Support decorators in additional contexts (Nikita Sobolev, PR 11150)
  • Fix crash involving unreachable binary operations (Shantanu, PR 11680)
  • Fix None assignments with mypy daemon cache (Christian Bundy, PR 11574)
  • Handle OSError when accessing the mtime of a mypy cache file (Zac Hatfield-Dodds, PR 11718)
  • Special case some special Enum properties to be non-final (Nikita Sobolev, PR 11713)
  • Fix crash involving undefined cyclic import * (Shantanu, PR 11681)
  • Remove incorrect assumption about file system case sensitivity (Shantanu, PR 11708)
  • Fix compatibility of bool and Literal[True, False] (Nikita Sobolev, PR 11709)
  • Allow subclassing enums with annotations and no values (Nikita Sobolev, PR 11579)

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
  • Akuli
  • Alex Waygood
  • Barnaby Shearer
  • Chad Dombrova
  • Chetan Khanna
  • Christian Bundy
  • Daniel Mendelsohn
  • David Foster
  • DetachHead
  • Dimitri Merejkowsky
  • Elisha Hollander
  • Elvis Pranskevichus
  • Ethan Leba
  • Ethan Smith
  • Hiroshi Ogawa
  • Ilia Novoselov
  • Ilya Labun
  • Imad Eddine Rezgui
  • Infinil
  • Jared Hance
  • Ken Jin
  • Konstantin Weddige
  • KotlinIsland
  • Louis Sautier
  • luzpaz
  • Marc Mueller
  • Nehal J Wani
  • Neil Girdhar
  • Nick Crews
  • Nikita Sobolev
  • Nipunn Koorapati
  • Noé Rubinstein
  • parthaxntn
  • Peter Law
  • pranavrajpal
  • Ran Benita
  • Sara Sinback
  • Sebastian Rittau
  • Seth Yastrov
  • Shantanu
  • Taneli Hukkinen
  • Tushar Sadhwani
  • Victor Stinner
  • William Woodruff
  • Zac Hatfield-Dodds
  • 林玮 (Jade Lin)
  • 谭九鼎

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

Tuesday, 21 December 2021

Mypy 0.921 Released

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

Bug Fixes Included in This Release

  • Fix regression in PathLike (Shantanu, PR 11785)
  • Allow calling a function with name _ (Jukka Lehtosalo, PR 11810)
  • Fix signature in curses and corresponding dmypy bug (Shantanu, PR 11785)

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

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.