We've just uploaded mypy 2.2.0 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new features, performance
improvements 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.
Support for Closed TypedDicts (PEP 728)
Mypy now supports closed TypedDicts as specified in PEP 728. A closed TypedDict cannot have extra
keys beyond those explicitly defined. This allows the type checker to determine that certain
operations are safe when they otherwise wouldn't be due to the potential presence of unknown keys.
You can use the closed keyword argument with TypedDict:
HasName = TypedDict("HasName", {"name": str})
HasOnlyName = TypedDict("HasOnlyName", {"name": str}, closed=True)
Movie = TypedDict("Movie", {"name": str, "year": int})
movie: Movie = {"name": "Nimona", "year": 2023}
has_name: HasName = movie # OK: HasName is open (default)
has_only_name: HasOnlyName = movie # Error: HasOnlyName is closed and Movie has extra "year" key
Closed TypedDicts enable more precise type checking because the type checker knows exactly which
keys are present. This is particularly useful when working with TypedDict unions or when you want
to ensure that a TypedDict conforms to an exact shape.
The closed keyword also enables safe type narrowing with in checks:
Book = TypedDict('Book', {'book': str}, closed=True)
DVD = TypedDict('DVD', {'dvd': str}, closed=True)
type Inventory = Book | DVD
def print_type(inventory: Inventory) -> None:
if "book" in inventory:
# Type is narrowed to Book here - safe because DVD is closed
print(inventory["book"])
else:
# Type is narrowed to DVD here
print(inventory["dvd"])
The closed keyword is also supported in class-based syntax:
class HasOnlyName(TypedDict, closed=True):
name: str
Note that closed TypedDicts are structural types, so a closed TypedDict is assignable to an open
TypedDict with the same keys, but not vice versa.
Complete Support for Type Variable Defaults (PEP 696)
Mypy now has complete support for type variable defaults as specified in PEP 696. This allows you to
specify default values for type parameters in generic classes, functions, and type aliases.
Traditional syntax (Python 3.11 and earlier):
T = TypeVar("T", default=int) # This means that if no type is specified T = int
@dataclass
class Box(Generic[T]):
value: T | None = None
reveal_type(Box()) # type is Box[int]
reveal_type(Box(value="Hello World!")) # type is Box[str]
New syntax (Python 3.12+):
class Box[T = int]:
def __init__(self, value: T) -> None:
self.value = value
reveal_type(Box()) # type is Box[int]
reveal_type(Box(value="Hello World!")) # type is Box[str]
Type variable defaults work with all forms of generics, including classes, functions, and type aliases.
This release completes the implementation by fixing various edge cases involving recursive defaults,
dependencies between type variables, and interactions with variadic generics.
Mypy now respects explicitly annotated return types in __new__() methods. Previously, mypy would
always assume that __new__() returns an instance of the current class, ignoring explicit annotations.
With this change, if you explicitly annotate a return type that differs from the implicit type, mypy
will use the explicit annotation:
class Factory:
def __new__(cls) -> Product:
return Product()
reveal_type(Factory()) # type is Product, not Factory
Note that mypy still gives an error at the definition site if the explicit annotation is not a
subtype of the current class, since this is technically not type-safe.
For backwards compatibility, there are two exceptions:
If the return type is Any, mypy will still use the current class as the return type.
If the explicit return type comes from a superclass and is a supertype of the implicit return type,
mypy will use the implicit (more specific) type:
class A:
def __new__(cls) -> A: ...
reveal_type(A()) # type is A
class B:
def __new__(cls) -> B:
return cls()
class C(B): ...
reveal_type(C()) # type is C
This fixes several long-standing issues where explicit __new__() return types were ignored.
Support for TypeForm is no longer experimental. TypeForm (introduced in Python 3.14) allows you
to annotate parameters that accept type expressions, providing better type checking for functions
that work with types as values.
from typing import TypeForm
def make_list(tp: TypeForm[T]) -> list[T]:
...
# Correctly typed as list[int]
int_list = make_list(int)
TypeForm support was previously reverted from mypy 2.1 due to a performance regression, but this
has now been mitigated.
Contributed by Ivan Levkivskyi and Jelle Zijlstra (PRs 21262, 21591,
21459).
Experimental WASM Wheel for Python 3.14
Mypy now ships an experimental WebAssembly (WASM) wheel for Python 3.14. This allows mypy to run
in WASM environments such as Pyodide and browser-based Python implementations.
The WASM wheel is considered experimental and may have limitations compared to native builds. Please
report any issues you encounter when using mypy in WASM environments.
We’ve just uploaded mypy 2.1.0 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new features, performance
improvements 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.
librt.vecs: Fast Growable Array Type for Mypyc
The new librt.vecs module provides an efficient growable array type vec that is
optimized for mypyc use. It provides fast, packed arrays with integer and floating point
value types, which can be several times faster than list, and tens of times faster
than array.array in code compiled using mypyc. It also supports nested vec objects and
non-value-type items, such as vec[vec[str]].
librt.random: Fast Pseudo-Random Number Generation
The new librt.random module provides fast pseudo-random number generation that is
optimized for code compiled using mypyc. It can be 3x to 10x faster than the stdlib
random module in compiled code.
We’ve just uploaded mypy 2.0.0 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new features, performance
improvements and bug fixes. There are also changes to options and defaults.
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.
Enable --local-partial-types by Default
This flag affects the inference of types based on assignments in other scopes.
For now, explicitly disabling this continues to be supported, but this support will be removed
in the future as the legacy behaviour is hard to support with other current and future features
in mypy, like the daemon or the new implementation of flexible redefinitions.
Contributed by Ivan Levkivskyi, Jukka Lehtosalo, Shantanu in PR 21163.
Enable --strict-bytes by Default
Per PEP 688, mypy no longer treats bytearray and memoryview
values as assignable to the bytes type.
The --allow-redefinition flag now behaves like --allow-redefinition-new in mypy 1.20
and earlier. The new behavior is generally more flexible. For example, you can have different
types for a variable in different blocks:
# mypy: allow-redefinition
def foo(cond: bool) -> None:
if cond:
for x in ["a", "b"]:
# Type of "x" is "str" here
...
else:
for x in [1, 2]:
# Type of "x" is "int" here
...
The new behavior requires --local-partial-types, which is now enabled by default.
However, --allow-redefinition doesn't allow giving two type annotations for the same
variable. The old behavior (sometimes) allows this. Code like this now generates an error
when using --allow-redefinition:
You can still use --allow-redefinition-old to fall back to the old behavior. We have no
plans to remove the legacy behavior, but the old functionality is maintained on a best effort
basis.
Mypy now supports experimental parallel and incremental type checking. Use --num-workers N
or -nN to use N worker processes to type check in parallel. The speedup depends on the
import structure of your codebase and your environment, but for large projects we've seen
performance gains of up to 5x when using 8 worker processes.
Parallel type checking implicitly enables the new native parser. There are still some
minor semantic differences between parallel and non-parallel modes, which we will be fixing
in future mypy releases.
Contributed by Ivan Levkivskyi, with additional contributions from Emma Smith and Jukka
Lehtosalo.
Recent related changes since the last release:
Freeze garbage collection in parallel workers for 4-5% speedup (Ivan Levkivskyi, PR 21302)
Expose --num-workers and --native-parser (Ivan Levkivskyi, PR 21387)
Split type checking into interface and implementation in parallel workers (Ivan Levkivskyi, PR 21119)
Batch module groups for parallel processing (Ivan Levkivskyi, PR 21287)
Parse files in parallel when possible (Ivan Levkivskyi, PR 21175)
Use parallel parsing at all stages (Ivan Levkivskyi, PR 21266)
Fix sequential bottleneck in parallel parsing (Jukka Lehtosalo, PR 21291)
Fail fast when a user tries to generate reports with parallel workers (Ivan Levkivskyi, PR 21341)
Partially support old NumPy plugin in parallel type checking (Ivan Levkivskyi, PR 21324)
Handle reachability consistently in parallel type checking (Ivan Levkivskyi, PR 21322)
Always respect @no_type_check in parallel type checking (Ivan Levkivskyi, PR 21320)
Minor fixes in parallel checking (Ivan Levkivskyi, PR 21319)
Fix plugin logic in parallel type checking (Ivan Levkivskyi, PR 21252)
Fix Windows IPC race condition when using parallel checking (Jukka Lehtosalo, PR 21228)
Report parallel worker exit status on receive failure (Jukka Lehtosalo, PR 21224)
Drop Support for Targeting Python 3.9
Mypy no longer supports type checking code with --python-version 3.9.
Use --python-version 3.10 or newer.
Contributed by Shantanu, Marc Mueller in PR 21243.
Remove Special Casing of Legacy Bundled Stubs
Mypy used to bundle stubs for a few packages in versions 0.812 and earlier. To navigate the
transition, mypy used to report missing types for these packages even if --ignore-missing-imports
was set. Mypy now consistently respects --ignore-missing-imports for all packages.
Prevent Assignment to None for Non-Optional Class Variables with Type Comments
Mypy used to allow assignment to None for class variables when using type comments. This was a
common idiom in Python 3.5 and earlier, prior to the introduction of variable annotations.
However, this was a soundness hole and has now been removed.
librt.strings: String and Bytes Primitives for Mypyc
In mypy 1.20, we introduced librt as a standard library
for mypyc that fills in some gaps in the Python standard library and the C API.
This release adds the new module librt.strings, which contains utilities for building
string and bytes objects, and for accessing and generating binary data:
StringWriter and BytesWriter classes allow quickly building str and bytes objects from parts.
read_* and write_* functions provide fast reading and writing of binary-encoded data.
We’ve just uploaded mypy 1.20.0 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new features, performance
improvements 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.
Planned Changes to Defaults and Flags in Mypy 2.0
As a reminder, we are planning to enable --local-partial-types by default in mypy 2.0, which
will likely be the next feature release. This will often require at least minor code changes. This
option is implicitly enabled by mypy daemon, so this makes the behavior of daemon and non-daemon
modes consistent.
Note that this release improves the compatibility of --local-partial-types significantly to
make the switch easier (see below for more).
This can also be configured in a mypy configuration file (use False to disable):
We will also enable --strict-bytes by default in mypy 2.0. This usually requires at most
minor code changes to adopt. For more information, refer to the
documentation.
Finally, --allow-redefinition-new will be renamed to --allow-redefinition. If you want
to continue using the older --allow-redefinition semantics which are less flexible (e.g.
limited support for conditional redefinitions), you can switch to --allow-redefinition-old,
which is currently supported as an alias to the legacy --allow-redefinition behavior.
To use --allow-redefinition in the upcoming mypy 2.0, you can't use --no-local-partial-types.
For more information, refer to the
documentation.
Better Type Narrowing
Mypy's implementation of narrowing has been substantially reworked. Mypy will now narrow more
aggressively, more consistently, and more correctly. In particular, you are likely to notice new
narrowing behavior in equality expressions (==), containment expressions (in),
match statements, and additional expressions providing type guards.
Note that mypy (and other Python type checkers) do not model the potential for various non-local
operations to invalidate narrowing assumptions. This means mypy may conclude that some of your code
is unreachable and
avoid further checking of it. The --warn-unreachable flag is useful for highlighting these cases.
To reset narrowing, you can insert dummy reassignments, for instance var = var will reset
all narrowing of var.attr.
Future work includes better narrowing on initial assignments, more narrowing to Literal types,
and better checking of unreachable code.
Contributed by Shantanu Jain.
Rework narrowing logic for equality and identity (Shantanu, PR 20492)
Refactor equality and identity narrowing for clarity (Shantanu, PR 20595)
Treat NotImplemented as a singleton type (Shantanu, PR 20601)
Improve narrowing logic for Enum int and str subclasses (Shantanu, PR 20609)
Narrow types based on collection containment (Shantanu, PR 20602)
Refactor and improve narrowing for type(x) == t checks (Shantanu, PR 20634)
Narrow for type expr comparisons to type exprs (Shantanu, PR 20639)
Narrowing for comparisons against x.__class__ (Shantanu, PR 20642)
Better narrowing with custom equality (Shantanu, PR 20643)
Use a single pass for core narrowing logic, add comments (Shantanu, PR 20659)
Narrowing for final type objects (Shantanu, PR 20661)
Better match narrowing for unions of type objects (Shantanu, PR 20905)
Improve reachability in narrowing logic (Shantanu, PR 20660)
Better match narrowing for irrefutable mapping patterns (Shantanu, PR 20906)
Fix match statement semantic reachability (Shantanu, PR 20968)
Add some additional narrowing test cases (Shantanu, PR 20598)
Move tests to check-narrowing , improve them slightly (Shantanu, PR 20637)
Add more tests for narrowing logic (Shantanu, PR 20672)
More testing related improvements and updates (Shantanu, PR 20709)
Add --warn-unreachable to more tests (Shantanu, PR 20977)
Drop Support for Python 3.9
Mypy no longer supports running with Python 3.9, which has reached end of life.
When running mypy with Python 3.10+, it is still possible to type check code
that needs to support Python 3.9 with the --python-version 3.9 argument.
Support for this will be dropped in the first half of 2026!
Mypyc Accelerated Mypy Wheels for ARM Windows and Free Threading
For best performance, mypy can be compiled to C extension modules using mypyc. This makes
mypy 3-5x faster than when interpreted with pure Python. We now build and upload mypyc
accelerated mypy wheels for win_arm64 and cp314t-... to PyPI, making it easy for Windows
users on ARM and those using the free theading builds for Python 3.14 to realise this speedup
-- just pip install the latest mypy.
Compatibility between mypy's default behavior and the --local-partial-types flag
is now improved. This improves compatibility between mypy daemon and non-daemon modes,
since the mypy daemon requires local partial types to be enabled.
In particular, code like this now behaves consistently independent of
whether local partial types are enabled or not:
x = None
def foo() -> None:
global x
x = 1
# The inferred type of 'x' is always 'int | None'.
Also, we are planning to turn local partial types on by default in mypy 2.0 (to be
released soon), and this makes the change much less disruptive. Explicitly disabling local
partial types will continue to be supported, but the support will likely be
deprecated and removed eventually, as the legacy behavior is hard to support together with
some important changes we are working on, in addition to being incompatible with the mypy
daemon.
This feature was contributed by Ivan Levkivskyi (PR 20938).
Python 3.14 T-String Support (PEP 750)
Mypy now supports t-strings that were introduced in Python 3.14.
Add support for Python 3.14 t-strings (PEP 750) (Neil Schemenauer and Brian Schubert, PR 20850)
Add implicit module dependency if using t-string (Jukka Lehtosalo, PR 20900)
Experimental New Parser
If you install mypy using pip install mypy[native-parser] and run mypy with
--native-parser, you can experiment with a new Python parser. It is based on
the Ruff parser, and it's more efficient than the default parser. It will also enable
access to all Python syntax independent of which Python version you use to run mypy.
The new parser is still not feature-complete and has known issues.
Related changes:
Add work-in-progress implementation of a new Python parser (Jukka Lehtosalo, PR 20856)
Skip redundant analysis pass when using the native parser (Ivan Levkivskyi, PR 21015)
Add t-string support to native parser (Ivan Levkivskyi, PR 21007)
Add ast-serialize as an optional dependency (Ivan Levkivskyi, PR 21028)
Use native-parser instead of native-parse for optional dependency (Jukka Lehtosalo, PR 21115)
Performance Improvements
Mypy now uses a binary cache format (fixed-format cache) by default to speed up incremental
checking. You can still use --no-fixed-format-cache to use the legacy JSON cache format,
but we will remove the JSON cache format in a future release. Mypy includes a tool to convert
individual fixed-format cache files (.ff) to the JSON format to make it possible to inspect
cache contents:
python -m mypy.exportjson <path> ...
If the SQLite cache is enabled, you will first need to convert the SQLite cache into
individual files using the misc/convert-cache.py
tool available in the mypy GitHub repository. You can also disable the SQLite
cache using --no-sqlite-cache.
The SQLite cache (--sqlite-cache) is now enabled by default. It improves mypy
performance significantly in certain environments where slow file system operations
used to be a bottleneck.
List of all performance improvements (for mypyc improvements there is a separate section below):
Flip fixed-format cache to on by default (Ivan Levkivskyi, PR 20758)
Enable --sqlite-cache by default (Shantanu, PR 21041)
Save work on emitting ignored diagnostics (Shantanu, PR 20621)
Skip logging and stats collection calls if they are no-ops (Jukka Lehtosalo, PR 20839)
Speed up large incremental builds by optimizing internal state construction (Jukka Lehtosalo, PR 20838)
Speed up suppressed dependencies options processing (Jukka Lehtosalo, PR 20806)
Avoid path operations that need syscalls (Jukka Lehtosalo, PR 20802)
Use faster algorithm for topological sort (Jukka Lehtosalo, PR 20790)
Replace old topological sort (Jukka Lehtosalo, PR 20805)
Fix quadratic performance in dependency graph loading for incremental builds (Jukka Lehtosalo, PR 20786)
Avoid unnecessary work when checking deferred functions (Ivan Levkivskyi, PR 20860)
Improve --allow-redefinition-new performance for code with loops (Ivan Levkivskyi, PR 20862)
Avoid setattr/getattr with fixed format cache (Ivan Levkivskyi, PR 20826)
Improvements to Allowing Redefinitions
Mypy now allows significantly more flexible variable redefinitions when using --allow-redefinition-new.
In particular, function parameters can now be redefined with a different type:
# mypy: allow-redefinition-new, local-partial-types
def process(items: list[str]) -> None:
# Reassign parameter to a completely different type.
# Without --allow-redefinition-new, this is a type error
# because list[list[str]] is not compatible with
# list[str].
items = [item.split() for item in items]
...
In mypy 2.0, we will update --allow-redefinition to mean --allow-redefinition-new.
This release adds --allow-redefinition-old as an alias of --allow-redefinition, which
can be used to continue using the old redefinition behavior in mypy 2.0 and later.
List of changes:
Add --allow-redefinition-old as an alias of --allow-redefinition (Ivan Levkivskyi, PR 20764)
Allow redefinitions for function arguments (Ivan Levkivskyi, PR 20853)
Fix regression on redefinition in deferred loop (Ivan Levkivskyi, PR 20879)
Fix loop convergence with redefinitions (Ivan Levkivskyi, PR 20865)
Make sure new redefinition semantics only apply to inferred variables (Ivan Levkivskyi, PR 20909)
Fix union edge case in function argument redefinition (Ivan Levkivskyi, PR 20908)
Show an error when old and new redefinition are enabled in a file (Ivan Levkivskyi, PR 20920)
--allow-redefinition-new is no longer experimental (Jukka Lehtosalo, PR 21110)
Fix type inference for nested union types (Ivan Levkivskyi, PR 20912)
Fix type inference regression for multiple variables in loops (Ivan Levkivskyi, PR 20892)
Improve type inference for empty collections in conditional contexts (Ivan Levkivskyi, PR 20851)
Incremental Checking Improvements
This release includes multiple fixes to incremental type checking:
Invalidate cache when --enable-incomplete-feature changes (kaushal trivedi, PR 20849)
Add back support for warn_unused_configs (Ivan Levkivskyi, PR 20801)
Recover from corrupted fixed-format cache meta file (Jukka Lehtosalo, PR 20780)
Distinguish not found versus skipped modules (Ivan Levkivskyi, PR 20812)
Fix undetected submodule deletion on warm run (Ivan Levkivskyi, PR 20784)
Fix staleness on changed follow-imports options (Ivan Levkivskyi, PR 20773)
Verify indirect dependencies reachable on incremental run (Ivan Levkivskyi, PR 20735)
Fix indirect dependencies for protocols (Ivan Levkivskyi, PR 20752)
Show error locations in other modules on warm runs (Ivan Levkivskyi, PR 20635)
Don't read errors from cache on silent import (Sjoerd Job Postmus, PR 20509)
More robust fix for re-export of __all__ (Ivan Levkivskyi, PR 20487)
Fix crashes caused by type variable defaults in-place modifications (Stanislav Terliakov, PR 20139)
Fix crash when calling len() with no arguments (Jukka Lehtosalo, PR 20774)
Fix crash when checking async for inside nested comprehensions (A5rocks, PR 20540)
Fix ParamSpec related crash (Stanislav Terliakov, PR 20119)
Mypyc: Faster Imports on macOS
Imports in native (compiled) modules that target other native modules that are compiled
together are now significantly faster on macOS, especially on the first run after a compiled
package has been installed. This also speeds up the first mypy run after installation/update
on macOS.
This was contributed by Jukka Lehtosalo (PR 21101).
librt: Mypyc Standard Library
Mypyc now has a dedicated standard library, librt, to provide basic features that are optimized
for compiled code. They are faster than corresponding Python stdlib functionality. There is no
plan to replace the Python stdlib, though. We'll only include a carefully selected set of features
that help with common performance bottlenecks in compiled code.
Currently, we provide librt.base64 that has optimized SIMD (Single Instruction, Multiple
Data) base64 encoding and decoding functions. In future mypyc releases we are planning to
add efficient data structures, string/bytes utilities, and more.
Use python3 -m pip install librt to make librt available to compiled modules. Compiled
modules don't require librt unless they explicitly import librt. If you install mypy, you
will also get a compatible version of librt as a dependency. We will keep librt backward
compatible, so you should always be able to update to a newer version of the library.
Enable SIMD for librt.base64 on x86-64 (Jukka Lehtosalo, PR 20244)
Add primitive for librt.base64.b64decode (Jukka Lehtosalo, PR 20272)
Add urlsafe_b64encode and urlsafe_b64decode to librt.base64 (Jukka Lehtosalo, PR 20274)
Make librt.base64 non-experimental (Ivan Levkivskyi, PR 20783)
Support pyodide for Python 3.12 (Michael R. Crusoe, PR 20342)
Support pyodide via the NEON intrinsics (Michael R. Crusoe, PR 20316)
Fix librt compilation on platforms with OpenMP (Ivan Levkivskyi, PR 20583)
Fix cross-compiling librt by enabling x86_64 optimizations with pragmas (James Le Cuirot, PR 20815)
Use existing SIMD CPU dispatch by customizing build flags (Michael R. Crusoe, PR 20253)
Document librt and librt.base64 (Jukka Lehtosalo, PR 21114)
Mypyc: Acyclic Classes
Mypyc now supports defining acyclic native classes that don't participate in the tracing
garbage collection:
from mypy_extensions import mypyc_attr
@mypyc_attr(acyclic=True)
class Item:
def __init__(self, key: str, value: str) -> None:
self.key = key
self.value = value
Allocating and freeing instances of acyclic classes is faster than regular native class
instances, and they use less memory, but if they participate in reference cycles, there
may be memory leaks.
This was contributed by Jukka Lehtosalo (PR 20795).
Additional Mypyc Fixes and Improvements
Fix range loop variable off-by-one after loop exit (Vaggelis Danias, PR 21098)
Removed Flags --force-uppercase-builtins and --force-union-syntax
The --force-uppercase-builtins flag was deprecated and has been a no-op since mypy 1.17.0.
Since mypy has dropped support for Python 3.9, the --force-union-syntax flag is no longer
necessary.
Contributed by Marc Mueller (PR 20410)
and (PR 20405).
Stubgen Improvements
Fix mis-parsing of double colon ("::") (Jeremy Nimmer, PR 20285)
Stubtest Improvements
Attempt to resolve decorators from their type (Shantanu, PR 20867)
Fix crash on instances with redefined __class__ (sobolevn, PR 20926)
Improve checking of positional-only parameters in dunder methods (Brian Schubert, PR 19593)
Check Final variables with literal values against runtime (Vikash Kumar, PR 20858)
Fix duplicate errors with invalid line numbers (Joren Hammudoglu, PR 20417)
We’ve just uploaded mypy 1.19.0 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new features, performance
improvements 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.
Python 3.9 Support Ending Soon
This is the last mypy feature release that supports Python 3.9, which reached end of life in October 2025.
Performance Improvements
Switch to a more dynamic SCC processing logic (Ivan Levkivskyi, PR 20053)
Mypy uses a cache by default to speed up incremental runs by reusing partial results
from earlier runs. Mypy 1.18 added a new binary fixed-format cache representation as
an experimental feature. The feature is no longer experimental, and we are planning
to enable it by default in a future mypy release (possibly 1.20), since it's faster
and uses less space than the original, JSON-based cache format. Use
--fixed-format-cache to enable the fixed-format cache.
Mypy now has an extra dependency on the librt PyPI package, as it's needed for
cache serialization and deserialization.
Mypy ships with a tool to convert fixed-format cache files to the old JSON format.
Example of how to use this:
This way existing use cases that parse JSON cache files can be supported when using
the new format, though an extra conversion step is needed.
This release includes these improvements:
Force-discard cache if cache format changed (Ivan Levkivskyi, PR 20152)
Add tool to convert binary cache files to JSON (Jukka Lehtosalo, PR 20071)
Use more efficient serialization format for long integers in cache files (Jukka Lehtosalo, PR 20151)
More robust packing of floats in fixed-format cache (Ivan Levkivskyi, PR 20150)
Use self-descriptive cache with type tags (Ivan Levkivskyi, PR 20137)
Use fixed format for cache metas (Ivan Levkivskyi, PR 20088)
Make metas more compact; fix indirect suppression (Ivan Levkivskyi, PR 20075)
Use dedicated tags for most common cached instances (Ivan Levkivskyi, PR 19762)
PEP 747: Annotating Type Forms
Mypy now recognizes TypeForm[T] as a type and implements
PEP 747. The feature is still experimental,
and it's disabled by default. Use --enable-incomplete-feature=TypeForm to
enable type forms. A type form object captures the type information provided by a
runtime type expression. Example:
from typing_extensions import TypeForm
def trycastT -> T | None: ...
def example(o: object) -> None:
# 'int | str' below is an expression that represents a type.
# Unlike type[T], TypeForm[T] can be used with all kinds of types,
# including union types.
x = trycast(int | str, o)
if x is not None:
# Type of 'x' is 'int | str' here
...
This feature was contributed by David Foster (PR 19596).
Fixes to Crashes
Do not push partial types to the binder (Stanislav Terliakov, PR 20202)
Fix crash on recursive tuple with Hashable (Ivan Levkivskyi, PR 20232)
Fix crash related to decorated functions (Stanislav Terliakov, PR 20203)
Do not abort constructing TypeAlias if only type parameters hold us back (Stanislav Terliakov, PR 20162)
Use the fallback for ModuleSpec early if it can never be resolved (Stanislav Terliakov, PR 20167)
Do not store deferred NamedTuple fields as redefinitions (Stanislav Terliakov, PR 20147)
Fix an infinite recursion bug (Stanislav Terliakov, PR 20127)
Fix IsADirectoryError for namespace packages when using --linecoverage-report (wyattscarpenter, PR 20109)
Fix an internal error when creating cobertura output for namespace package (wyattscarpenter, PR 20112)
Allow type parameters reusing the name missing from current module (Stanislav Terliakov, PR 20081)
Prevent TypeGuardedType leak from narrowing declared type as part of type variable bound (Stanislav Terliakov, PR 20046)
Fix crash on invalid unpack in base class (Ivan Levkivskyi, PR 19962)
Traverse ParamSpec prefix where we should (Ivan Levkivskyi, PR 19800)
Fix daemon crash related to imports (Ivan Levkivskyi, PR 20271)
Mypyc: Support for __getattr__, __setattr__, and __delattr__
Mypyc now has partial support for __getattr__, __setattr__ and
__delattr__ methods in native classes.
Note that native attributes are not stored using __dict__. Setting attributes
directly while bypassing __setattr__ is possible by using
super().__setattr__(...) or object.__setattr__(...), but not via __dict__.
Example:
class Demo:
_data: dict[str, str]
def __init__(self) -> None:
# Initialize data dict without calling our __setattr__
super().__setattr__("_data", {})
def __setattr__(self, name: str, value: str) -> None:
print(f"Setting {name} = {value!r}")
if name == "_data":
raise AttributeError("'_data' cannot be set")
self._data[name] = value
def __getattr__(self, name: str) -> str:
print(f"Getting {name}")
try:
return self._data[name]
except KeyError:
raise AttributeError(name)
d = Demo()
d.x = "hello"
d.y = "world"
print(d.x)
print(d.y)