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)
We’ve just uploaded mypy 1.18.1 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.
Mypy Performance Improvements
Mypy 1.18.1 includes numerous performance improvements, resulting in about 40% speedup
compared to 1.17 when type checking mypy itself. In extreme cases, the improvement
can be 10x or higher. The list below is an overview of the various mypy optimizations.
Many mypyc improvements (discussed in a separate section below) also improve performance.
Type caching optimizations have a small risk of causing regressions. When
reporting issues with unexpected inferred types, please also check if
--disable-expression-cache will work around the issue, as it turns off some of
these optimizations.
Return early where possible in subtype check (Stanislav Terliakov, PR 19400)
Deduplicate some types before joining (Stanislav Terliakov, PR 19409)
Speed up type checking by caching argument inference context (Jukka Lehtosalo, PR 19323)
Optimize binding method self argument type and deprecation checks (Ivan Levkivskyi, PR 19556)
Keep trivial instance types/aliases during expansion (Ivan Levkivskyi, PR 19543)
Fixed‑Format Cache (Experimental)
Mypy now supports a new cache format used for faster incremental builds. It makes
incremental builds up to twice as fast. The feature is experimental and
currently only supported when using a compiled version of mypy. Use --fixed-format-cache
to enable the new format, or fixed_format_cache = True in a configuration file.
We plan to enable this by default in a future mypy release, and we'll eventually
deprecate and remove support for the original JSON-based format.
Unlike the JSON-based cache format, the new binary format is currently
not easy to parse and inspect by mypy users. We are planning to provide a tool to
convert fixed-format cache files to JSON, but details of the output JSON may be
different from the current JSON format. If you rely on being able to inspect
mypy cache files, we recommend creating a GitHub issue and explaining your use
case, so that we can more likely provide support for it. (Using
MypyFile.read(binary_data) to inspect cache data may be sufficient to support
some use cases.)
Mypy 1.16.0 introduced --allow-redefinition-new, which allows redefining variables
with different types, and inferring union types for variables from multiple assignments.
The feature is now documented in the --help output, but the feature is still experimental.
We are planning to enable this by default in mypy 2.0, and we will also deprecate the
older --allow-redefinition flag. Since the new behavior differs significantly from
the older flag, we encourage users of --allow-redefinition to experiment with
--allow-redefinition-new and create a GitHub issue if the new functionality doesn't
support some important use cases.
This feature was contributed by Jukka Lehtosalo.
Inferred Type for Bare ClassVar
A ClassVar without an explicit type annotation now causes the type of the variable
to be inferred from the initializer:
from typing import ClassVar
class Item:
# Type of 'next_id' is now 'int' (it was 'Any')
next_id: ClassVar = 1
...
This feature was contributed by Ivan Levkivskyi (PR 19573).
Disjoint Base Classes (@disjoint_base, PEP 800)
Mypy now understands disjoint bases (PEP 800): it recognizes the @disjoint_base
decorator, and rejects class definitions that combine mutually incompatible base classes,
and takes advantage of the fact that such classes cannot exist in reachability and
narrowing logic.
This class definition will now generate an error:
# Error: Class "Bad" has incompatible disjoint bases
class Bad(str, Exception):
...
This feature was contributed by Jelle Zijlstra (PR 19678).
Miscellaneous New Mypy Features
Add --strict-equality-for-none to flag non-overlapping comparisons involving None (Christoph Tyralla, PR 19718)
Don’t show import‑related errors after a module‑level assert such as assert sys.platform == "linux" that is always false (Stanislav Terliakov, PR 19347)
Improvements to Match Statements
Add temporary named expressions for match subjects (Stanislav Terliakov, PR 18446)
Fix unwrapping of assignment expressions in match subject (Marc Mueller, PR 19742)
Omit errors for class patterns against object (Marc Mueller, PR 19709)
Remove unnecessary error for certain match class patterns (Marc Mueller, PR 19708)
Use union type for captured vars in or pattern (Marc Mueller, PR 19710)
Prevent final reassignment inside match case (Omer Hadari, PR 19496)
Fixes to Crashes
Fix crash with variadic tuple arguments to a generic type (Randolf Scholz, PR 19705)
Fix crash when enable_error_code in pyproject.toml has wrong type (wyattscarpenter, PR 19494)
Prevent crash for dataclass with PEP 695 TypeVarTuple on Python 3.13+ (Stanislav Terliakov, PR 19565)
Fix crash on settable property alias (Ivan Levkivskyi, PR 19615)
Experimental Free-threading Support for Mypyc
All mypyc tests now pass on free-threading Python 3.14 release candidate builds. The performance
of various micro-benchmarks scale well across multiple threads.
Free-threading support is still experimental. Note that native attribute access
(get and set), list item access and certain other operations are still
unsafe when there are race conditions. This will likely change in the future.
You can follow the
area-free-threading label
in the mypyc issues tracker to follow progress.
Related PRs:
Enable free‑threading when compiling multiple modules (Jukka Lehtosalo, PR 19541)
Fix list.pop on free‑threaded builds (Jukka Lehtosalo, PR 19522)
Make type objects immortal under free‑threading (Jukka Lehtosalo, PR 19538)
Mypyc: Support __new__
Mypyc now has rudimentary support for user-defined __new__ methods.
This feature was contributed by Piotr Sawicki (PR 19739).
Mypyc: Faster Generators and Async Functions
Generators and calls of async functions are now faster, sometimes by 2x or more.
Related PRs:
Speed up for loops over native generators (Jukka Lehtosalo, PR 19415)
Speed up native‑to‑native calls using await (Jukka Lehtosalo, PR 19398)