Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
Mypy
https://mypy.readthedocs.io/en/stable/
Admin
Official documentation for the Mypy type checker.
Tokens:
205,042
Snippets:
1,739
Trust Score:
9.6
Update:
1 week ago
Context
Chat
Benchmark
83.61
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Install mypy with pip Source: https://mypy.readthedocs.io/en/stable/changelog.html Install or upgrade mypy to the latest version, such as 2.4.0, from PyPI. ```bash python3 -m pip install -U mypy ``` -------------------------------- ### Install mypy 1.18.1 with pip Source: https://mypy.readthedocs.io/en/stable/changelog.html Install or upgrade mypy to the latest version, such as 1.18.1, from PyPI. ```bash python3 -m pip install -U mypy ``` -------------------------------- ### Install mypy with pip Source: https://mypy.readthedocs.io/en/stable/getting_started.html Install mypy using pip. Requires Python 3.10 or later. ```bash $ python3 -m pip install mypy ``` -------------------------------- ### Example pyproject.toml for mypy configuration Source: https://mypy.readthedocs.io/en/stable/config_file.html Example pyproject.toml configuration for mypy. Place at repo root or append to existing pyproject.toml, then run mypy. Shows global options (python_version, warn_return_any, warn_unused_configs, exclude) and per-module overrides using [[tool.mypy.overrides]]. ```toml # mypy global options: [tool.mypy] python_version = "3.10" warn_return_any = true warn_unused_configs = true exclude = [ '^file1\.py$', # TOML literal string (single-quotes, no escaping necessary) "^file2\.py$", # TOML basic string (double-quotes, backslash and other characters need escaping) ] # mypy per-module options: [[tool.mypy.overrides]] module = "mycode.foo.*" disallow_untyped_defs = true [[tool.mypy.overrides]] module = "mycode.bar" warn_return_any = false [[tool.mypy.overrides]] module = [ "somelibrary", "some_other_library" ] ignore_missing_imports = true ``` -------------------------------- ### Install mypy with mypyc dependencies Source: https://mypy.readthedocs.io/en/stable/changelog.html Install mypy along with mypyc dependencies. Use this instead of plain mypy when you need mypyc package dependencies. ```bash python3 -m pip install -U 'mypy[mypyc]' ``` -------------------------------- ### Install mypy with faster-cache extra Source: https://mypy.readthedocs.io/en/stable/changelog.html Install mypy with the faster-cache extra to enable the optional orjson-based cache for improved performance. ```bash python3 -m pip install -U mypy[faster-cache] ``` -------------------------------- ### Install development mypy build from source Source: https://mypy.readthedocs.io/en/stable/common_issues.html Clones the mypy repository and installs the latest development version locally with pip. Use this to test unreleased mypy features or fixes. ```bash git clone https://github.com/python/mypy.git cd mypy python3 -m pip install --upgrade . ``` -------------------------------- ### Install typing-extensions for NoReturn Source: https://mypy.readthedocs.io/en/stable/more_types.html Installs typing_extensions using pip for Python 3. Required to use NoReturn in earlier Python versions. ```bash python3 -m pip install --upgrade typing-extensions ``` -------------------------------- ### Example source module for stubgen Source: https://mypy.readthedocs.io/en/stable/stubgen.html Example source module used to illustrate stub generation. It imports a dynamic attribute, defines a module-level constant, a class with an instance attribute and an __init__ method, and a function returning a Window instance. ```python from other_module import dynamic BORDER_WIDTH = 15 class Window: parent = dynamic() def __init__(self, width, height): self.width = width self.height = height def create_empty() -> Window: return Window(0, 0) ``` -------------------------------- ### mypy error: Library stubs not installed for "yaml" Source: https://mypy.readthedocs.io/en/stable/running_mypy.html Example error output shown when mypy cannot find stubs for a third-party library and knows stubs exist. The output includes a hint to install the specific stub package and a note about using --install-types. ```text main.py:1: error: Library stubs not installed for "yaml" main.py:1: note: Hint: "python3 -m pip install types-PyYAML" main.py:1: note: (or run "mypy --install-types" to install all missing stub packages) ``` -------------------------------- ### PEP 696 type parameter defaults example Source: https://mypy.readthedocs.io/en/stable/changelog.html Example adapted from PEP 696 demonstrating type parameter defaults with TypeVar from typing_extensions. Requires importing TypeVar, ParamSpec, or TypeVarTuple from typing_extensions until Python 3.13. ```python from typing import Generic from typing_extensions import TypeVar class Bot: ... BotT = TypeVar("BotT", bound=Bot, default=Bot) class Context(Generic[BotT]): bot: BotT class MyBot(Bot): ... # type is Bot (the default) reveal_type(Context().bot) # type is MyBot reveal_type(Context[MyBot]().bot) ``` -------------------------------- ### Install missing stubs with mypy --install-types Source: https://mypy.readthedocs.io/en/stable/running_mypy.html Command to install all known missing stub packages. It runs mypy twice, shows a confirmation prompt by default, and can make controlling stub versions harder. ```bash mypy --install-types ``` -------------------------------- ### Example of --deprecated-calls-exclude: ignoring deprecated warnings Source: https://mypy.readthedocs.io/en/stable/command_line.html Shows how to use --deprecated-calls-exclude to suppress deprecated warnings for a specific class prefix. The example includes a mypy command line and a file foo.py defining a deprecated method. ```python # mypy --enable-error-code deprecated # --deprecated-calls-exclude=foo.A import foo foo.A().func() # OK, the deprecated warning is ignored ``` ```python # file foo.py from typing_extensions import deprecated class A: @deprecated("Use A.func2 instead") def func(self): pass ``` -------------------------------- ### Start mypy daemon with --use-fine-grained-cache Source: https://mypy.readthedocs.io/en/stable/additional_features.html Starts the mypy daemon with the --use-fine-grained-cache option so it can use the extra fine-grained cache information generated by --cache-fine-grained. This speeds up the first dmypy check run after starting or restarting the daemon. ```bash $ dmypy start -- --use-fine-grained-cache <options...> ``` -------------------------------- ### Recursive protocol example (TreeLike) Source: https://mypy.readthedocs.io/en/stable/protocols.html Shows a recursive protocol for tree-like structures. The protocol references itself via properties, and SimpleTree satisfies it. ```python from __future__ import annotations from typing import Protocol class TreeLike(Protocol): value: int @property def left(self) -> TreeLike | None: ... @property def right(self) -> TreeLike | None: ... class SimpleTree: def __init__(self, value: int) -> None: self.value = value self.left: SimpleTree | None = None self.right: SimpleTree | None = None root: TreeLike = SimpleTree(0) # OK ``` -------------------------------- ### Example output for --follow-imports=error Source: https://mypy.readthedocs.io/en/stable/running_mypy.html Shows the error messages mypy emits when using --follow-imports=error, flagging the import of a module not passed on the command line. ```text main.py:1: note: Import of "mycode.bar" ignored main.py:1: note: (Using --follow-imports=error, module not passed on command line) ``` -------------------------------- ### Unannotated new_user function Source: https://mypy.readthedocs.io/en/stable/kinds_of_types.html Unannotated function that creates an instance of the class passed as an argument. This is the starting point for the annotation examples. ```python def new_user(user_class): user = user_class() # (Here we could write the user object to a database) return user ``` -------------------------------- ### Example mypy.ini with global and per-module options Source: https://mypy.readthedocs.io/en/stable/config_file.html Place this file at the root of your repository and run mypy to apply the configuration. The [mypy] section sets global options: warn_return_any reports an error when a function returns a value inferred as Any, and warn_unused_configs reports unused config options to catch typos. Per-module sections override global defaults: disallow_untyped_defs applies only to mycode.foo.*, warn_return_any is disabled for mycode.bar, and ignore_missing_imports suppresses import errors for somelibrary. ```ini # Global options: [mypy] warn_return_any = True warn_unused_configs = True # Per-module options: [mypy-mycode.foo.*] disallow_untyped_defs = True [mypy-mycode.bar] warn_return_any = False [mypy-somelibrary] ignore_missing_imports = True ``` -------------------------------- ### import-untyped: Library stubs not installed Source: https://mypy.readthedocs.io/en/stable/error_code_list.html Mypy raises this error when an imported module has source code but lacks type annotations (PEP 561). The example shows two cases: a missing stub package and a module installed without a py.typed marker. ```python # Error: Library stubs not installed for "bs4" [import-untyped] import bs4 # Error: Skipping analyzing "no_py_typed": module is installed, but missing library stubs or py.typed marker [import-untyped] import no_py_typed ``` -------------------------------- ### Run stubtest on a library and view errors Source: https://mypy.readthedocs.io/en/stable/stubtest.html Shows a complete stubtest workflow: install mypy, create a runtime module and its stub, run stubtest, and see the reported inconsistencies. The output demonstrates two errors: a default value mismatch for foo and a type mismatch for x. ```bash $ python3 -m pip install mypy $ cat library.py x = "hello, stubtest" def foo(x=None): print(x) $ cat library.pyi x: int def foo(x: int) -> None: ... $ python3 -m mypy.stubtest library error: library.foo is inconsistent, runtime argument "x" has a default value but stub argument does not Stub: at line 3 def (x: builtins.int) Runtime: in file ~/library.py:3 def (x=None) error: library.x variable differs from runtime type Literal['hello, stubtest'] Stub: at line 1 builtins.int Runtime: 'hello, stubtest' ``` -------------------------------- ### Python module with conditional import Source: https://mypy.readthedocs.io/en/stable/stubtest.html Example module `ex` that conditionally defines `second` only when `optional_expensive_dep` is installed. Used to illustrate stubtest errors when the dependency is missing. ```python try: import optional_expensive_dep except ImportError: optional_expensive_dep = None first = 1 if optional_expensive_dep: second = 2 ``` -------------------------------- ### Per-module mypy configuration options Source: https://mypy.readthedocs.io/en/stable/type_inference_and_annotations.html Example of per-module configuration options in the mypy configuration file. Shows how to ignore all errors in a package, disable specific error codes and allow untyped defs in another, and ignore missing imports in a third. ```ini # Don't report errors in the 'package_to_fix_later' package [mypy-package_to_fix_later.*] ignore_errors = True # Disable specific error codes in the 'tests' package # Also don't require type annotations [mypy-tests.*] disable_error_code = var-annotated, has-type allow_untyped_defs = True # Silence import errors from the 'library_missing_types' package [mypy-library_missing_types.*] ignore_missing_imports = True ``` -------------------------------- ### Allowlist entry for ex.second Source: https://mypy.readthedocs.io/en/stable/stubtest.html Allowlist file `allowlist.txt` with an entry for `ex.second` to suppress the stubtest error. Running stubtest with `--allowlist=allowlist.txt` produces no errors. ```text # Allowlist entries in `allowlist.txt` file: # Does not exist if `optional_expensive_dep` is not installed: ex.second ``` -------------------------------- ### Example of --implicit-optional: function with None default Source: https://mypy.readthedocs.io/en/stable/command_line.html Shows a function with a parameter defaulting to None. With --implicit-optional, mypy treats x as int | None. This flag is disabled by default starting in mypy 0.980. ```python def foo(x: int = None) -> None: print(x) ``` -------------------------------- ### Mypy missing import error output Source: https://mypy.readthedocs.io/en/stable/running_mypy.html Example error output from mypy when it cannot follow imports. Shows three common missing-import errors: missing library stubs or py.typed marker, library stubs not installed, and module not found. ```text main.py:1: error: Skipping analyzing 'django': module is installed, but missing library stubs or py.typed marker main.py:2: error: Library stubs not installed for "requests" main.py:3: error: Cannot find implementation or library stub for module named "this_module_does_not_exist" ``` -------------------------------- ### Type alias example that typechecks Source: https://mypy.readthedocs.io/en/stable/more_types.html Type aliases make `int` and `UserId` synonymous, so this example typechecks successfully. ```python UserId = int def name_by_id(user_id: UserId) -> str: ... name_by_id(3) # ints and UserId are synonymous ``` -------------------------------- ### Overload with None and TypeVar example Source: https://mypy.readthedocs.io/en/stable/changelog.html Example of an overload where mypy no longer considers None and a type variable to overlap, avoiding a previous error. ```python @overload def f(x: None) -> None: .. @overload def f(x: T) -> Foo[T]: ... ... ``` -------------------------------- ### Improved callable type inference example Source: https://mypy.readthedocs.io/en/stable/changelog.html Example showing improved type inference for callable types, where mypy now correctly infers type variables inside arguments. ```python def f(c: Callable[[T, S], None]) -> Callable[[str, T, S], None]: ... def g(*x: int) -> None: ... reveal_type(f(g)) # Callable[[str, int, int], None] ``` -------------------------------- ### Define a class with type annotations and subclassing Source: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html Shows how to annotate instance variables, methods, and use user-defined classes as types. Includes a subclass with an audit log and demonstrates that functions accepting a base class also accept subclasses. ```python from typing import ClassVar class BankAccount: # The "__init__" method doesn't return anything, so it gets return # type "None" just like any other method that doesn't return anything def __init__(self, account_name: str, initial_balance: int = 0) -> None: # mypy will infer the correct types for these instance variables # based on the types of the parameters. self.account_name = account_name self.balance = initial_balance # For instance methods, omit type for "self" def deposit(self, amount: int) -> None: self.balance += amount def withdraw(self, amount: int) -> None: self.balance -= amount # User-defined classes are valid as types in annotations account: BankAccount = BankAccount("Alice", 400) def transfer(src: BankAccount, dst: BankAccount, amount: int) -> None: src.withdraw(amount) dst.deposit(amount) # Functions that accept BankAccount also accept any subclass of BankAccount! class AuditedBankAccount(BankAccount): # You can optionally declare instance variables in the class body audit_log: list[str] def __init__(self, account_name: str, initial_balance: int = 0) -> None: super().__init__(account_name, initial_balance) self.audit_log: list[str] = [] def deposit(self, amount: int) -> None: self.audit_log.append(f"Deposited {amount}") self.balance += amount def withdraw(self, amount: int) -> None: self.audit_log.append(f"Withdrew {amount}") self.balance -= amount audited = AuditedBankAccount("Bob", 300) transfer(audited, account, 100) # type checks! # You can use the ClassVar annotation to declare a class variable class Car: seats: ClassVar[int] = 4 passengers: ClassVar[list[str]] # If you want dynamic attributes on your class, have it # override "__setattr__" or "__getattr__" class A: # This will allow assignment to any A.x, if x is the same type as "value" # (use "value: Any" to allow arbitrary types) def __setattr__(self, name: str, value: int) -> None: ... # This will allow access to any A.x, if x is compatible with the return type def __getattr__(self, name: str) -> int: ... a = A() a.foo = 42 # Works a.bar = 'Ex-parrot' # Fails type checking ``` -------------------------------- ### Generic new_user with TypeVar (Python 3.11 and earlier) Source: https://mypy.readthedocs.io/en/stable/kinds_of_types.html Legacy syntax for Python 3.11 and earlier using TypeVar with an upper bound. Equivalent to the Python 3.12 version. ```python U = TypeVar('U', bound=User) def new_user(user_class: type[U]) -> U: # Same implementation as before ``` -------------------------------- ### Type parameter ordering with Generic and multiple bases Source: https://mypy.readthedocs.io/en/stable/generics.html Illustrates how type parameter order is determined in legacy syntax. If Generic[...] is present, order follows Generic[...]; otherwise parameters are collected in lexicographic order (first appearance). Shows that Generic can be omitted when other bases include type variables. ```python from typing import Generic, TypeVar, Any T = TypeVar('T') S = TypeVar('S') U = TypeVar('U') class One(Generic[T]): ... class Another(Generic[T]): ... class First(One[T], Another[S]): ... class Second(One[T], Another[S], Generic[S, U, T]): ... x: First[int, str] # Here T is bound to int, S is bound to str y: Second[int, str, Any] # Here T is Any, S is int, and U is str ``` -------------------------------- ### Define an abstract base class with abstract method and property Source: https://mypy.readthedocs.io/en/stable/class_basics.html Shows how to define an ABC using abc.ABCMeta and @abc.abstractmethod, including an abstract property. Instantiating the abstract class raises an error, while instantiating a concrete subclass is allowed. ```python from abc import ABCMeta, abstractmethod class Animal(metaclass=ABCMeta): @abstractmethod def eat(self, food: str) -> None: pass @property @abstractmethod def can_walk(self) -> bool: pass class Cat(Animal): def eat(self, food: str) -> None: ... # Body omitted @property def can_walk(self) -> bool: return True x = Animal() # Error: 'Animal' is abstract due to 'eat' and 'can_walk' y = Cat() # OK ``` -------------------------------- ### Generated stub file from stubgen Source: https://mypy.readthedocs.io/en/stable/stubgen.html Generated stub file (`.pyi`) produced by stubgen from the example source module. It uses `Any` for unannotated attributes and `...` for default values and function bodies, and adds `-> None` to `__init__`. ```python from typing import Any BORDER_WIDTH: int = ... class Window: parent: Any = ... width: Any = ... height: Any = ... def __init__(self, width, height) -> None: ... def create_empty() -> Window: ... ``` -------------------------------- ### Create a mypy plugin with get_type_analyze_hook Source: https://mypy.readthedocs.io/en/stable/extending_mypy.html Defines a mypy plugin entry point that returns a subclass of mypy.plugin.Plugin. The entry point receives the full mypy version string and can ignore it if the plugin works with all versions. The get_type_analyze_hook method can return a callback for analyzing unbound types with the given full name. ```python from mypy.plugin import Plugin class CustomPlugin(Plugin): def get_type_analyze_hook(self, fullname: str): # see explanation below ... def plugin(version: str): # ignore version argument if the plugin works with all mypy versions. return CustomPlugin ``` -------------------------------- ### Trigger unreachable with --warn-unreachable Source: https://mypy.readthedocs.io/en/stable/error_code_list2.html Use this example to see how mypy reports unreachable code when using --warn-unreachable. The example shows two errors: 'Right operand of "or" is never evaluated' and 'Statement is unreachable'. The mypy configuration comment '# mypy: warn-unreachable' enables the check. ```python # mypy: warn-unreachable def example(x: int) -> None: # Error: Right operand of "or" is never evaluated [unreachable] assert isinstance(x, int) or x == 'unused' return # Error: Statement is unreachable [unreachable] print('unreachable') ``` -------------------------------- ### Example: Unsupported operand types error Source: https://mypy.readthedocs.io/en/stable/index.html A minimal example showing how mypy reports a type error at runtime. The code reads a number as a string and attempts to add an integer, producing the error: Unsupported operand types for + ("str" and "int"). Use this to see how mypy flags type mismatches without running the program. ```python number = input("What is your favourite number?") print("It is", number + 1) # error: Unsupported operand types for + ("str" and "int") ``` -------------------------------- ### Define a simple protocol with `Protocol` Source: https://mypy.readthedocs.io/en/stable/protocols.html Defines a simple protocol `SupportsClose` with a `close` method and shows that `Resource` and file objects are compatible without inheriting from the protocol. Use this to enforce structural subtyping with mypy. ```python from collections.abc import Iterable from typing import Protocol class SupportsClose(Protocol): # Empty method body (explicit '...') def close(self) -> None: ... class Resource: # No SupportsClose base class! def close(self) -> None: self.resource.release() # ... other methods ... def close_all(items: Iterable[SupportsClose]) -> None: for item in items: item.close() close_all([Resource(), open('some/file')]) # OK ``` -------------------------------- ### Instantiating an implicitly abstract class is an error Source: https://mypy.readthedocs.io/en/stable/class_basics.html Shows that attempting to create an instance of an implicitly abstract class is rejected by mypy. ```python d = Derived() # Error: 'Derived' is abstract ``` -------------------------------- ### Ineffective type ignore comment placement Source: https://mypy.readthedocs.io/en/stable/common_issues.html Shows a `# type: ignore` comment that will not take effect because it is not at the start of the comments on the line. ```python import frobnicate #example other comment # type: ignore frobnicate.start() ``` -------------------------------- ### New --allow-redefinition behavior Source: https://mypy.readthedocs.io/en/stable/changelog.html Example showing the new --allow-redefinition behavior, which allows different types for a variable in different blocks. Requires --local-partial-types, now enabled by default. ```python # 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 ... ``` -------------------------------- ### Typical dictionary with fixed schema Source: https://mypy.readthedocs.io/en/stable/typed_dict.html A typical dictionary with string keys and a fixed schema. This is the motivating example for using TypedDict. ```python movie = {'name': 'Blade Runner', 'year': 1982} ```