We’ve just uploaded mypy 0.981 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 Python 3.6 and 2 DroppedSupport for Python 2 has been completely removed in this release.
Support for Python 3.6 has also been dropped, since Python 3.6 has reached its end of life. It is still possible to target Python 3.6 using --python-version in future mypy versions, but no bugs will be fixed that affect only Python 3.6 (unless they are regressions). Also note that typeshed just recently dropped Python 3.6 support, so standard library features only available in Python 3.6 will not be supported.
The implementation was jointly contributed by Shantanu, Nikita Sobolev and Ivan Levkivskyi.
Generate Error on Unbound TypeVar Return TypeCode like this will now generate an error, since the value of T cannot be inferred in calls:
from typing import TypeVar T = TypeVar("T") # Error: A function returning TypeVar should receive at least one # argument containing the same Typevar def f() -> T: ...
Having an unbound type variable in a nested position (e.g. list[T]) is still accepted in a return type, since it has valid use cases. This was contributed by Aurélien Jaquier (PR 13166).
Methods with Empty Bodies in Protocols Are AbstractAny method with an empty body in a protocol is now correctly treated as implicitly abstract and must be implemented even if a class explicitly inherits the protocol:
from typing import Protocol class P(Protocol): # "..." is the literal ellipsis and indicates an empty body def meth(self) -> int: ... class Cls(P): pass # Error: Cannot instantiate abstract class "Cls" with abstract # attribute "method" Cls()
This was contributed by Thomas MK (PR 12118).
Implicit Optional Types Will Be Disabled by DefaultA future mypy feature release (possibly the next one after 0.98x) will disable implicit optional types such as these by default, and they will have to be explicitly enabled:
def foo(s: str = None) -> int: ... No error currently foo(None) # Ok
In the future mypy will only accept the example with an explicit optional type (e.g. str | None) for the s argument, when using the default options:
# s: Optional[str] also works def foo(s: str | None = None) -> int: ... foo(None) # No change to callers
To prepare for the change, you can set the relevant configuration option explicitly. Either disable implicit optional types by using --no-implicit-optional, or no_implicit_optional = True in your mypy configuration file, or enable them via --implicit-optional or no_implicit_optional = False. We don’t recommend relying on implicit optional types, since they are a non-standard feature, but we have no plans to stop supporting them.
We hope to provide a migration tool that will automatically switch implicit optional types to explicit ones in function signatures.
Precise Types for **kwds Using TypedDictMypy now supports precise type annotations for kwds parameters. You can use this feature as following:
from typing import TypedDict from typing_extensions import Unpack class Style(TypedDict, total=False): margin: int sticky: bool def add_button(label: str, **kwds: Unpack[Style]) -> None: ... def add_check_box(active: bool, **kwds: Unpack[Style]) -> None: ... add_button("Cancel", margin=0, sticky=False) # This works tight: Style = {"margin": 0} add_button("OK", **tight) # This works as well
You can alternatively use Required[...] and NotRequired[...] TypedDict annotations to control whether a keyword argument is required or not. Note that arbitrary extra keywords are not allowed for such functions (this is consistent with how mypy currently handles TypedDicts). Although this feature is complete, Unpack[...] is still considered experimental, so you will need to use --enable-incomplete-features to enable it.
This feature was contributed by Ivan Levkivskyi (PR 13471).
Experimental Support for General Recursive TypesUntil recently mypy only supported recursively defined classes (e.g. trees), but not arbitrary recursive types. In this version we add (experimental) support for arbitrary recursively defined types, including type aliases, TypedDicts, NamedTuples, and so on. This example uses a recursively defined type alias:
from typing import TypeVar, Sequence T = TypeVar("T") # String literal escaping needed to avoid NameError at runtime Nested = Sequence[T | "Nested[T]"] def flatten(seq: Nested[T]) -> list[T]: result = [] for item in seq: if isinstance(item, list): result.extend(flatten(item)) else: result.append(item) return result flatten([1, [2, 3]]) # This works, inferred type is list[int]
This feature can be enabled using --enable-recursive-aliases. If mypy doesn’t work as expected with some recursive types, you can try adding more explicit annotations, and/or using covariant collections (e.g. Sequence instead of list). Please file an issue on the issue tracker if you think you have found a bug.
List of relevant PRs:
Mypy now supports defining generic TypedDicts, NamedTuples, and user defined tuple types. You can use either the class or call syntax for this:
from typing import Generic, TypeVar from typing_extensions import TypedDict # From "typing" on Python 3.11 T = TypeVar("T") class Param(TypedDict, Generic[T]): name: str value: T Opt = TypedDict("Opt", {"value": T, "is_set": bool}) def apply(param: Param[T]) -> T: ... x = apply({"name": "test", "value": 42}) # Inferred type is "int"Note:
While you can freely use this feature in stub files, if you want to use it in source files, you will need to either use Python 3.11 (which is not officially supported by mypy yet), import
TypedDict/
NamedTuplefrom
typing_extensions, or use an
if TYPE_CHECKING: ...block.
List of relevant PRs:
Mypy now has better support for instance attributes with Callable[...] types. Previously, mypy couldn’t reliably distinguish between callable instance attributes and method aliases. Now there are consistent rules. If a variable is defined using and assignment and/or annotation in a class body and has a callable type, it is an instance attribute if both these conditions are true:
Conversely, such an assignment/annotation defines a method in these cases:
Example:
from typing import ClassVar, Callable class Test: runner: Callable[[], None] # An instance variable def hook(self) -> None: ... self.runner = lambda: print("pass") legacy_hook = hook # A method other_hook: ClassVar[Callable[[Test], None]] # Also a method Test.other_hook = lambda self: None t = Test() t.legacy_hook() t.runner() t.other_hook()
This feature was contribute by Ivan Levkivskyi (PR 13400).
Per-Module Error Code ConfigurationYou can now disable and/or enable individual error codes per module and per directory using config files and/or inline # mypy: comments. Example:
# mypy.ini [mypy] strict = True [mypy-tests.*] allow_untyped_defs = True allow_untyped_calls = True disable_error_code = var-annotated
# source.py x = [] # Error: Need type annotation for "x"
# tests/foo.py x = [] # OK
# tests/bar.py # mypy: enable-error-code="var-annotated" x = [] # Error: Need type annotation for "x"
Note that these per-directory settings act as incremental overrides. The precedence is the following:
You can, for example, enable an error code globally, disable it for all tests in the config file, and then re-enable it in a particular file by using an inline comment.
This feature was contributed by Ivan Levkivskyi (PR 13502).
Experimental Support for Interactive Inspection of ExpressionsMypy now has an experimental support for various static inspections using the mypy daemon dmypy inspect command. These inspections are currently included:
Note that you can run this only after the file has been type-checked by the daemon, for example by using dmypy check or dmypy run. Basic usage is like this:
dmypy inspect [--show type|attrs|definition] \
path/to/file.py:line:column[:end_line:end_column]
Please read the docs for more details. This feature was contributed by Ivan Levkivskyi (PR 13209).
Mypyc ImprovementsMypyc compiles Python modules to C extensions and is bundled with mypy. It uses standard Python type hints to generate fast code (documentation).
Stubgen is a tool for automatically generating draft stubs for libraries.
Stubtest is a tool for testing that stubs conform to the implementations.
Typeshed is now modular and distributed as separate PyPI packages for everything except the standard library stubs. Please see git log for full list of typeshed changes.
AcknowledgementsThanks to all mypy contributors who contributed to this release:
We’d also like to thank our employer, Dropbox, for funding the mypy core team.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4