## File: README.md

Mypy: Static Typing for Python
=======================================

[](https://pypi.org/project/mypy/)
[](https://pypistats.org/packages/mypy)
[](https://github.com/python/mypy/actions)
[](https://mypy.readthedocs.io/en/latest/?badge=latest)
[](https://gitter.im/python/typing?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://mypy-lang.org/)
[](https://github.com/psf/black)
[](https://github.com/astral-sh/ruff)

Got a question?
---------------

We are always happy to answer questions! Here are some good places to ask them:

- for general questions about Python typing, try [typing discussions](https://github.com/python/typing/discussions)
- for anything you're curious about, try [gitter chat](https://gitter.im/python/typing)

If you're just getting started,
[the documentation](https://mypy.readthedocs.io/en/stable/index.html)
and [type hints cheat sheet](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html)
can also help answer questions.

If you think you've found a bug:

- check our [common issues page](https://mypy.readthedocs.io/en/stable/common_issues.html)
- search our [issue tracker](https://github.com/python/mypy/issues) to see if
  it's already been reported

To report a bug or request an enhancement:

- report at [our issue tracker](https://github.com/python/mypy/issues)
- if the issue is with a specific library or function, consider reporting it at
  [typeshed tracker](https://github.com/python/typeshed/issues) or the issue
  tracker for that library

To discuss a new type system feature:

- discuss at [discuss.python.org](https://discuss.python.org/c/typing/32)
- there is also some historical discussion at the [typing-sig mailing list](https://mail.python.org/archives/list/typing-sig@python.org/) and the [python/typing repo](https://github.com/python/typing/issues)

What is mypy?
-------------

Mypy is a static type checker for Python.

Type checkers help ensure that you're using variables and functions in your code
correctly. With mypy, add type hints ([PEP 484](https://www.python.org/dev/peps/pep-0484/))
to your Python programs, and mypy will warn you when you use those types
incorrectly.

Python is a dynamic language, so usually you'll only see errors in your code
when you attempt to run it. Mypy is a *static* checker, so it finds bugs
in your programs without even running them!

Here is a small example to whet your appetite:

```python
number = input("What is your favourite number?")
print("It is", number + 1)  # error: Unsupported operand types for + ("str" and "int")
```

Adding type hints for mypy does not interfere with the way your program would
otherwise run. Think of type hints as similar to comments! You can always use
the Python interpreter to run your code, even if mypy reports errors.

Mypy is designed with gradual typing in mind. This means you can add type
hints to your code base slowly and that you can always fall back to dynamic
typing when static typing is not convenient.

Mypy has a powerful and easy-to-use type system, supporting features such as
type inference, generics, callable types, tuple types, union types,
structural subtyping and more. Using mypy will make your programs easier to
understand, debug, and maintain.

See [the documentation](https://mypy.readthedocs.io/en/stable/index.html) for
more examples and information.

In particular, see:

- [type hints cheat sheet](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html)
- [getting started](https://mypy.readthedocs.io/en/stable/getting_started.html)
- [list of error codes](https://mypy.readthedocs.io/en/stable/error_code_list.html)

Quick start
-----------

Mypy can be installed using pip:

```bash
python3 -m pip install -U mypy
```

If you want to run the latest version of the code, you can install from the
repo directly:

```bash
python3 -m pip install -U git+https://github.com/python/mypy.git
```

Now you can type-check the [statically typed parts] of a program like this:

```bash
mypy PROGRAM
```

You can always use the Python interpreter to run your statically typed
programs, even if mypy reports type errors:

```bash
python3 PROGRAM
```

If you are working with large code bases, you can run mypy in
[daemon mode], that will give much faster (often sub-second) incremental updates:

```bash
dmypy run -- PROGRAM
```

You can also try mypy in an [online playground](https://mypy-play.net/) (developed by
Yusuke Miyazaki).

[statically typed parts]: https://mypy.readthedocs.io/en/latest/getting_started.html#function-signatures-and-dynamic-vs-static-typing
[daemon mode]: https://mypy.readthedocs.io/en/stable/mypy_daemon.html

Integrations
------------

Mypy can be integrated into popular IDEs:

- VS Code: provides [basic integration](https://code.visualstudio.com/docs/python/linting#_mypy) with mypy.
- Vim:
  - Using [Syntastic](https://github.com/vim-syntastic/syntastic): in `~/.vimrc` add
    `let g:syntastic_python_checkers=['mypy']`
  - Using [ALE](https://github.com/dense-analysis/ale): should be enabled by default when `mypy` is installed,
    or can be explicitly enabled by adding `let b:ale_linters = ['mypy']` in `~/vim/ftplugin/python.vim`
- Emacs: using [Flycheck](https://github.com/flycheck/)
- Sublime Text: [SublimeLinter-contrib-mypy](https://github.com/fredcallaway/SublimeLinter-contrib-mypy)
- PyCharm: [mypy plugin](https://github.com/dropbox/mypy-PyCharm-plugin)
- IDLE: [idlemypyextension](https://github.com/CoolCat467/idlemypyextension)
- pre-commit: use [pre-commit mirrors-mypy](https://github.com/pre-commit/mirrors-mypy), although
  note by default this will limit mypy's ability to analyse your third party dependencies.

Web site and documentation
--------------------------

Additional information is available at the web site:

  <https://www.mypy-lang.org/>

Jump straight to the documentation:

  <https://mypy.readthedocs.io/>

Follow along our changelog at:

  <https://mypy-lang.blogspot.com/>

Contributing
------------

Help in testing, development, documentation and other tasks is
highly appreciated and useful to the project. There are tasks for
contributors of all experience levels.

To get started with developing mypy, see [CONTRIBUTING.md](CONTRIBUTING.md).

Mypyc and compiled version of mypy
----------------------------------

[Mypyc](https://github.com/mypyc/mypyc) uses Python type hints to compile Python
modules to faster C extensions. Mypy is itself compiled using mypyc: this makes
mypy approximately 4 times faster than if interpreted!

To install an interpreted mypy instead, use:

```bash
python3 -m pip install --no-binary mypy -U mypy
```

To use a compiled version of a development
version of mypy, directly install a binary from
<https://github.com/mypyc/mypy_mypyc-wheels/releases/latest>.

To contribute to the mypyc project, check out the issue tracker at <https://github.com/mypyc/mypyc>

---

## File: docs/source/additional_features.rst

Additional features
-------------------

This section discusses various features that did not fit in naturally in one
of the previous sections.

.. _dataclasses_support:

Dataclasses
***********

The :py:mod:`dataclasses` module allows defining and customizing simple
boilerplate-free classes. They can be defined using the
:py:func:`@dataclasses.dataclass ` decorator:

.. code-block:: python

    from dataclasses import dataclass, field

    @dataclass
    class Application:
        name: str
        plugins: list[str] = field(default_factory=list)

    test = Application("Testing...")  # OK
    bad = Application("Testing...", "with plugin")  # Error: list[str] expected

Mypy will detect special methods (such as :py:meth:`__lt__ <object.__lt__>`) depending on the flags used to
define dataclasses. For example:

.. code-block:: python

    from dataclasses import dataclass

    @dataclass(order=True)
    class OrderedPoint:
        x: int
        y: int

    @dataclass(order=False)
    class UnorderedPoint:
        x: int
        y: int

    OrderedPoint(1, 2) < OrderedPoint(3, 4)  # OK
    UnorderedPoint(1, 2) < UnorderedPoint(3, 4)  # Error: Unsupported operand types

Dataclasses can be generic and can be used in any other way a normal
class can be used (Python 3.12 syntax):

.. code-block:: python

    from dataclasses import dataclass

    @dataclass
    class BoxedData[T]:
        data: T
        label: str

    def unbox[T](bd: BoxedData[T]) -> T:
        ...

    val = unbox(BoxedData(42, ""))  # OK, inferred type is int

For more information see :doc:`official docs `
and :pep:`557`.

Caveats/Known Issues
====================

Some functions in the :py:mod:`dataclasses` module, such as :py:func:`~dataclasses.asdict`,
have imprecise (too permissive) types. This will be fixed in future releases.

Mypy does not yet recognize aliases of :py:func:`dataclasses.dataclass <dataclasses.dataclass>`, and will
probably never recognize dynamically computed decorators. The following example
does **not** work:

.. code-block:: python

    from dataclasses import dataclass

    dataclass_alias = dataclass
    def dataclass_wrapper(cls):
      return dataclass(cls)

    @dataclass_alias
    class AliasDecorated:
      """
      Mypy doesn't recognize this as a dataclass because it is decorated by an
      alias of `dataclass` rather than by `dataclass` itself.
      """
      attribute: int

    AliasDecorated(attribute=1) # error: Unexpected keyword argument


To have Mypy recognize a wrapper of :py:func:`dataclasses.dataclass <dataclasses.dataclass>`
as a dataclass decorator, consider using the :py:func:`~typing.dataclass_transform`
decorator (example uses Python 3.12 syntax):

.. code-block:: python

    from dataclasses import dataclass, Field
    from typing import dataclass_transform

    @dataclass_transform(field_specifiers=(Field,))
    def my_dataclass[T](cls: type[T]) -> type[T]:
        ...
        return dataclass(cls)


Data Class Transforms
*********************

Mypy supports the :py:func:`~typing.dataclass_transform` decorator as described in
`PEP 681 <https://www.python.org/dev/peps/pep-0681/#the-dataclass-transform-decorator>`_.

.. note::

    Pragmatically, mypy will assume such classes have the internal attribute :code:`__dataclass_fields__`
    (even though they might lack it in runtime) and will assume functions such as :py:func:`dataclasses.is_dataclass`
    and :py:func:`dataclasses.fields` treat them as if they were dataclasses
    (even though they may fail at runtime).

.. _attrs_package:

The attrs package
*****************

:doc:`attrs <attrs:index>` is a package that lets you define
classes without writing boilerplate code. Mypy can detect uses of the
package and will generate the necessary method definitions for decorated
classes using the type annotations it finds.
Type annotations can be added as follows:

.. code-block:: python

    import attrs

    @attrs.define
    class A:
        one: int
        two: int = 7
        three: int = attrs.field(8)

If you're using ``auto_attribs=False`` you must use ``attrs.field``:

.. code-block:: python

    import attrs

    @attrs.define
    class A:
        one: int = attrs.field()          # Variable annotation (Python 3.6+)
        two = attrs.field()  # type: int  # Type comment
        three = attrs.field(type=int)     # type= argument

Typeshed has a couple of "white lie" annotations to make type checking
easier. :py:func:`attrs.field` and :py:class:`attrs.Factory` actually return objects, but the
annotation says these return the types that they expect to be assigned to.
That enables this to work:

.. code-block:: python

    import attrs

    @attrs.define
    class A:
        one: int = attrs.field(8)
        two: dict[str, str] = attrs.Factory(dict)
        bad: str = attrs.field(16)   # Error: can't assign int to str

Caveats/Known Issues
====================

* The detection of attr classes and attributes works by function name only.
  This means that if you have your own helper functions that, for example,
  ``return attrs.field()`` mypy will not see them.

* All boolean arguments that mypy cares about must be literal ``True`` or ``False``.
  e.g the following will not work:

  .. code-block:: python

      import attrs
      YES = True
      @attrs.define(init=YES)
      class A:
          ...

* Currently, ``converter`` only supports named functions.  If mypy finds something else it
  will complain about not understanding the argument and the type annotation in
  :py:meth:`__init__ <object.__init__>` will be replaced by ``Any``.

* :ref:`Validator decorators <attrs:examples-validators>`
  and `default decorators <https://www.attrs.org/en/stable/examples.html#defaults>`_
  are not type-checked against the attribute they are setting/validating.

* Method definitions added by mypy currently overwrite any existing method
  definitions.

.. _remote-cache:

Using a remote cache to speed up mypy runs
******************************************

Mypy performs type checking *incrementally*, reusing results from
previous runs to speed up successive runs. If you are type checking a
large codebase, mypy can still be sometimes slower than desirable. For
example, if you create a new branch based on a much more recent commit
than the target of the previous mypy run, mypy may have to
process almost every file, as a large fraction of source files may
have changed. This can also happen after you've rebased a local
branch.

Mypy supports using a *remote cache* to improve performance in cases
such as the above.  In a large codebase, remote caching can sometimes
speed up mypy runs by a factor of 10, or more.

Mypy doesn't include all components needed to set
this up -- generally you will have to perform some simple integration
with your Continuous Integration (CI) or build system to configure
mypy to use a remote cache. This discussion assumes you have a CI
system set up for the mypy build you want to speed up, and that you
are using a central git repository. Generalizing to different
environments should not be difficult.

Here are the main components needed:

* A shared repository for storing mypy cache files for all landed commits.

* CI build that uploads mypy incremental cache files to the shared repository for
  each commit for which the CI build runs.

* A wrapper script around mypy that developers use to run mypy with remote
  caching enabled.

Below we discuss each of these components in some detail.

Shared repository for cache files
=================================

You need a repository that allows you to upload mypy cache files from
your CI build and make the cache files available for download based on
a commit id.  A simple approach would be to produce an archive of the
``.mypy_cache`` directory (which contains the mypy cache data) as a
downloadable *build artifact* from your CI build (depending on the
capabilities of your CI system).  Alternatively, you could upload the
data to a web server or to S3, for example.

Continuous Integration build
============================

The CI build would run a regular mypy build and create an archive containing
the ``.mypy_cache`` directory produced by the build. Finally, it will produce
the cache as a build artifact or upload it to a repository where it is
accessible by the mypy wrapper script.

Your CI script might work like this:

* Run mypy normally. This will generate cache data under the
  ``.mypy_cache`` directory.

* Create a tarball from the ``.mypy_cache`` directory.

* Determine the current git master branch commit id (say, using
  ``git rev-parse HEAD``).

* Upload the tarball to the shared repository with a name derived from the
  commit id.

Mypy wrapper script
===================

The wrapper script is used by developers to run mypy locally during
development instead of invoking mypy directly.  The wrapper first
populates the local ``.mypy_cache`` directory from the shared
repository and then runs a normal incremental build.

The wrapper script needs some logic to determine the most recent
central repository commit (by convention, the ``origin/master`` branch
for git) the local development branch is based on. In a typical git
setup you can do it like this:

.. code::

    git merge-base HEAD origin/master

The next step is to download the cache data (contents of the
``.mypy_cache`` directory) from the shared repository based on the
commit id of the merge base produced by the git command above. The
script will decompress the data so that mypy will start with a fresh
``.mypy_cache``. Finally, the script runs mypy normally. And that's all!

Caching with mypy daemon
========================

You can also use remote caching with the :ref:`mypy daemon <mypy_daemon>`.
The remote cache will significantly speed up the first ``dmypy check``
run after starting or restarting the daemon.

The mypy daemon requires extra fine-grained dependency data in
the cache files which aren't included by default. To use caching with
the mypy daemon, use the :option:`--cache-fine-grained <mypy --cache-fine-grained>` option in your CI
build::

    $ mypy --cache-fine-grained <args...>

This flag adds extra information for the daemon to the cache. In
order to use this extra information, you will also need to use the
``--use-fine-grained-cache`` option with ``dmypy start`` or
``dmypy restart``. Example::

    $ dmypy start -- --use-fine-grained-cache <options...>

Now your first ``dmypy check`` run should be much faster, as it can use
cache information to avoid processing the whole program.

Refinements
===========

There are several optional refinements that may improve things further,
at least if your codebase is hundreds of thousands of lines or more:

* If the wrapper script determines that the merge base hasn't changed
  from a previous run, there's no need to download the cache data and
  it's better to instead reuse the existing local cache data.

* If you use the mypy daemon, you may want to restart the daemon each time
  after the merge base or local branch has changed to avoid processing a
  potentially large number of changes in an incremental build, as this can
  be much slower than downloading cache data and restarting the daemon.

* If the current local branch is based on a very recent master commit,
  the remote cache data may not yet be available for that commit, as
  there will necessarily be some latency to build the cache files. It
  may be a good idea to look for cache data for, say, the 5 latest
  master commits and use the most recent data that is available.

* If the remote cache is not accessible for some reason (say, from a public
  network), the script can still fall back to a normal incremental build.

* You can have multiple local cache directories for different local branches
  using the :option:`--cache-dir <mypy --cache-dir>` option. If the user switches to an existing
  branch where downloaded cache data is already available, you can continue
  to use the existing cache data instead of redownloading the data.

* You can set up your CI build to use a remote cache to speed up the
  CI build. This would be particularly useful if each CI build starts
  from a fresh state without access to cache files from previous
  builds. It's still recommended to run a full, non-incremental
  mypy build to create the cache data, as repeatedly updating cache
  data incrementally could result in drift over a long time period (due
  to a mypy caching issue, perhaps).

.. _extended_callable:

Extended Callable types
***********************

.. note::

   This feature is deprecated.  You can use
   :ref:`callback protocols <callback_protocols>` as a replacement.

As an experimental mypy extension, you can specify :py:class:`~collections.abc.Callable` types
that support keyword arguments, optional arguments, and more.  When
you specify the arguments of a :py:class:`~collections.abc.Callable`, you can choose to supply just
the type of a nameless positional argument, or an "argument specifier"
representing a more complicated form of argument.  This allows one to
more closely emulate the full range of possibilities given by the
``def`` statement in Python.

As an example, here's a complicated function definition and the
corresponding :py:class:`~collections.abc.Callable`:

.. code-block:: python

   from collections.abc import Callable
   from mypy_extensions import (Arg, DefaultArg, NamedArg,
                                DefaultNamedArg, VarArg, KwArg)

   def func(__a: int,  # This convention is for nameless arguments
            b: int,
            c: int = 0,
            *args: int,
            d: int,
            e: int = 0,
            **kwargs: int) -> int:
       ...

   F = Callable[[int,  # Or Arg(int)
                 Arg(int, 'b'),
                 DefaultArg(int, 'c'),
                 VarArg(int),
                 NamedArg(int, 'd'),
                 DefaultNamedArg(int, 'e'),
                 KwArg(int)],
                int]

   f: F = func

Argument specifiers are special function calls that can specify the
following aspects of an argument:

- its type (the only thing that the basic format supports)

- its name (if it has one)

- whether it may be omitted

- whether it may or must be passed using a keyword

- whether it is a ``*args`` argument (representing the remaining
  positional arguments)

- whether it is a ``**kwargs`` argument (representing the remaining
  keyword arguments)

The following functions are available in ``mypy_extensions`` for this
purpose:

.. code-block:: python

   def Arg(type=Any, name=None):
       # A normal, mandatory, positional argument.
       # If the name is specified it may be passed as a keyword.

   def DefaultArg(type=Any, name=None):
       # An optional positional argument (i.e. with a default value).
       # If the name is specified it may be passed as a keyword.

   def NamedArg(type=Any, name=None):
       # A mandatory keyword-only argument.

   def DefaultNamedArg(type=Any, name=None):
       # An optional keyword-only argument (i.e. with a default value).

   def VarArg(type=Any):
       # A *args-style variadic positional argument.
       # A single VarArg() specifier represents all remaining
       # positional arguments.

   def KwArg(type=Any):
       # A **kwargs-style variadic keyword argument.
       # A single KwArg() specifier represents all remaining
       # keyword arguments.

In all cases, the ``type`` argument defaults to ``Any``, and if the
``name`` argument is omitted the argument has no name (the name is
required for ``NamedArg`` and ``DefaultNamedArg``).  A basic
:py:class:`~collections.abc.Callable` such as

.. code-block:: python

   MyFunc = Callable[[int, str, int], float]

is equivalent to the following:

.. code-block:: python

   MyFunc = Callable[[Arg(int), Arg(str), Arg(int)], float]

A :py:class:`~collections.abc.Callable` with unspecified argument types, such as

.. code-block:: python

   MyOtherFunc = Callable[..., int]

is (roughly) equivalent to

.. code-block:: python

   MyOtherFunc = Callable[[VarArg(), KwArg()], int]

.. note::

   Each of the functions above currently just returns its ``type``
   argument at runtime, so the information contained in the argument
   specifiers is not available at runtime.  This limitation is
   necessary for backwards compatibility with the existing
   ``typing.py`` module as present in the Python 3.5+ standard library
   and distributed via PyPI.

---

## File: docs/source/builtin_types.rst

Built-in types
==============

This chapter introduces some commonly used built-in types. We will
cover many other kinds of types later.

Simple types
............

Here are examples of some common built-in types:

====================== ===============================
Type                   Description
====================== ===============================
``int``                integer
``float``              floating point number
``bool``               boolean value (subclass of ``int``)
``str``                text, sequence of unicode codepoints
``bytes``              8-bit string, sequence of byte values
``object``             an arbitrary object (``object`` is the common base class)
====================== ===============================

All built-in classes can be used as types.

Any type
........

If you can't find a good type for some value, you can always fall back
to ``Any``:

====================== ===============================
Type                   Description
====================== ===============================
``Any``                dynamically typed value with an arbitrary type
====================== ===============================

The type ``Any`` is defined in the :py:mod:`typing` module.
See :ref:`dynamic-typing` for more details.

Generic types
.............

Built-in collection type objects support indexing:

====================== ===============================
Type                   Description
====================== ===============================
``list[str]``          list of ``str`` objects
``tuple[int, int]``    tuple of two ``int`` objects (``tuple[()]`` is the empty tuple)
``tuple[int, ...]``    tuple of an arbitrary number of ``int`` objects
``dict[str, int]``     dictionary from ``str`` keys to ``int`` values
``Iterable[int]``      iterable object containing ints
``Sequence[bool]``     sequence of booleans (read-only)
``Mapping[str, int]``  mapping from ``str`` keys to ``int`` values (read-only)
``type[C]``            type object of ``C`` (``C`` is a class/type variable/union of types)
====================== ===============================

The type ``dict`` is a *generic* class, signified by type arguments within
``[...]``. For example, ``dict[int, str]`` is a dictionary from integers to
strings and ``dict[Any, Any]`` is a dictionary of dynamically typed
(arbitrary) values and keys. ``list`` is another generic class.

``Iterable``, ``Sequence``, and ``Mapping`` are generic types that correspond to
Python protocols. For example, a ``str`` object or a ``list[str]`` object is
valid when ``Iterable[str]`` or ``Sequence[str]`` is expected.
You can import them from :py:mod:`collections.abc` instead of importing from
:py:mod:`typing`.

See :ref:`generic-builtins` for more details.

These legacy types defined in :py:mod:`typing` are also supported:

====================== ===============================
Type                   Description
====================== ===============================
``List[str]``          list of ``str`` objects
``Tuple[int, int]``    tuple of two ``int`` objects (``Tuple[()]`` is the empty tuple)
``Tuple[int, ...]``    tuple of an arbitrary number of ``int`` objects
``Dict[str, int]``     dictionary from ``str`` keys to ``int`` values
``Type[C]``            type object of ``C`` (``C`` is a class/type variable/union of types)
====================== ===============================

---

## File: docs/source/cheat_sheet_py3.rst

.. _cheat-sheet-py3:

Type hints cheat sheet
======================

This document is a quick cheat sheet showing how to use type
annotations for various common types in Python.

Variables
*********

Technically many of the type annotations shown below are redundant,
since mypy can usually infer the type of a variable from its value.
See :ref:`type-inference-and-annotations` for more details.

.. code-block:: python

   # This is how you declare the type of a variable
   age: int = 1

   # You don't need to initialize a variable to annotate it
   a: int  # Ok (no value at runtime until assigned)

   # Doing so can be useful in conditional branches
   child: bool
   if age < 18:
       child = True
   else:
       child = False


Useful built-in types
*********************

.. code-block:: python

   # For most types, just use the name of the type in the annotation
   # Note that mypy can usually infer the type of a variable from its value,
   # so technically these annotations are redundant
   x: int = 1
   x: float = 1.0
   x: bool = True
   x: str = "test"
   x: bytes = b"test"

   # For collections, the type of the collection item is in brackets
   x: list[int] = [1]
   x: set[int] = {6, 7}

   # For mappings, we need the types of both keys and values
   x: dict[str, float] = {"field": 2.0}

   # For tuples of fixed size, we specify the types of all the elements
   x: tuple[int, str, float] = (3, "yes", 7.5)

   # For tuples of variable size, we use one type and ellipsis
   x: tuple[int, ...] = (1, 2, 3)

   # On Python 3.8 and earlier, the name of the collection type is
   # capitalized, and the type is imported from the 'typing' module
   from typing import List, Set, Dict, Tuple
   x: List[int] = [1]
   x: Set[int] = {6, 7}
   x: Dict[str, float] = {"field": 2.0}
   x: Tuple[int, str, float] = (3, "yes", 7.5)
   x: Tuple[int, ...] = (1, 2, 3)

   from typing import Union, Optional

   # Use the | operator when something could be one of a few types
   x: list[int | str] = [3, 5, "test", "fun"]
   # Union is equivalent
   x: list[Union[int, str]] = [3, 5, "test", "fun"]

   # Use X | None for a value that could be None; Optional[X] is the same as X | None
   x: str | None = "something" if some_condition() else None
   if x is not None:
       # Mypy understands x won't be None here because of the if-statement
       print(x.upper())
   # If you know a value can never be None due to some logic that mypy doesn't
   # understand, use an assert
   assert x is not None
   print(x.upper())

Functions
*********

.. code-block:: python

   from collections.abc import Iterator, Callable
   from typing import Union, Optional

   # This is how you annotate a function definition
   def stringify(num: int) -> str:
       return str(num)

   # And here's how you specify multiple arguments
   def plus(num1: int, num2: int) -> int:
       return num1 + num2

   # If a function does not return a value, use None as the return type
   # Default value for an argument goes after the type annotation
   def show(value: str, excitement: int = 10) -> None:
       print(value + "!" * excitement)

   # Note that arguments without a type are dynamically typed (treated as Any)
   # and that functions without any annotations are not checked
   def untyped(x):
       x.anything() + 1 + "string"  # no errors

   # This is how you annotate a callable (function) value
   x: Callable[[int, float], float] = f
   def register(callback: Callable[[str], int]) -> None: ...

   # A generator function that yields ints is secretly just a function that
   # returns an iterator of ints, so that's how we annotate it
   def gen(n: int) -> Iterator[int]:
       i = 0
       while i < n:
           yield i
           i += 1

   # You can of course split a function annotation over multiple lines
   def send_email(
       address: str | list[str],
       sender: str,
       cc: list[str] | None,
       bcc: list[str] | None,
       subject: str = '',
       body: list[str] | None = None,
   ) -> bool:
       ...

   # Mypy understands positional-only and keyword-only arguments
   # Positional-only arguments can also be marked by using a name starting with
   # two underscores
   def quux(x: int, /, *, y: int) -> None:
       pass

   quux(3, y=5)  # Ok
   quux(3, 5)  # error: Too many positional arguments for "quux"
   quux(x=3, y=5)  # error: Unexpected keyword argument "x" for "quux"

   # This says each positional arg and each keyword arg is a "str"
   def call(self, *args: str, **kwargs: str) -> str:
       reveal_type(args)  # Revealed type is "tuple[str, ...]"
       reveal_type(kwargs)  # Revealed type is "dict[str, str]"
       request = make_request(*args, **kwargs)
       return self.do_api_query(request)

Classes
*******

.. code-block:: 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

When you're puzzled or when things are complicated
**************************************************

.. code-block:: python

   from typing import Union, Any, Optional, TYPE_CHECKING, cast

   # To find out what type mypy infers for an expression anywhere in
   # your program, wrap it in reveal_type().  Mypy will print an error
   # message with the type; remove it again before running the code.
   reveal_type(1)  # Revealed type is "builtins.int"

   # If you initialize a variable with an empty container or "None"
   # you may have to help mypy a bit by providing an explicit type annotation
   x: list[str] = []
   x: str | None = None

   # Use Any if you don't know the type of something or it's too
   # dynamic to write a type for
   x: Any = mystery_function()
   # Mypy will let you do anything with x!
   x.whatever() * x["you"] + x("want") - any(x) and all(x) is super  # no errors

   # Use a "type: ignore" comment to suppress errors on a given line,
   # when your code confuses mypy or runs into an outright bug in mypy.
   # Good practice is to add a comment explaining the issue.
   x = confusing_function()  # type: ignore  # confusing_function won't return None here because ...

   # "cast" is a helper function that lets you override the inferred
   # type of an expression. It's only for mypy -- there's no runtime check.
   a = [4]
   b = cast(list[int], a)  # Passes fine
   c = cast(list[str], a)  # Passes fine despite being a lie (no runtime check)
   reveal_type(c)  # Revealed type is "builtins.list[builtins.str]"
   print(c)  # Still prints [4] ... the object is not changed or casted at runtime

   # Use "TYPE_CHECKING" if you want to have code that mypy can see but will not
   # be executed at runtime (or to have code that mypy can't see)
   if TYPE_CHECKING:
       import json
   else:
       import orjson as json  # mypy is unaware of this

In some cases type annotations can cause issues at runtime, see
:ref:`runtime_troubles` for dealing with this.

See :ref:`silencing-type-errors` for details on how to silence errors.

Standard "duck types"
*********************

In typical Python code, many functions that can take a list or a dict
as an argument only need their argument to be somehow "list-like" or
"dict-like".  A specific meaning of "list-like" or "dict-like" (or
something-else-like) is called a "duck type", and several duck types
that are common in idiomatic Python are standardized.

.. code-block:: python

   from collections.abc import Mapping, MutableMapping, Sequence, Iterable
   # or 'from typing import ...' (required in Python 3.8)

   # Use Iterable for generic iterables (anything usable in "for"),
   # and Sequence where a sequence (supporting "len" and "__getitem__") is
   # required
   def f(ints: Iterable[int]) -> list[str]:
       return [str(x) for x in ints]

   f(range(1, 3))

   # Mapping describes a dict-like object (with "__getitem__") that we won't
   # mutate, and MutableMapping one (with "__setitem__") that we might
   def f(my_mapping: Mapping[int, str]) -> list[int]:
       my_mapping[5] = 'maybe'  # mypy will complain about this line...
       return list(my_mapping.keys())

   f({3: 'yes', 4: 'no'})

   def f(my_mapping: MutableMapping[int, str]) -> set[str]:
       my_mapping[5] = 'maybe'  # ...but mypy is OK with this.
       return set(my_mapping.values())

   f({3: 'yes', 4: 'no'})

   import sys
   from typing import IO

   # Use IO[str] or IO[bytes] for functions that should accept or return
   # objects that come from an open() call (note that IO does not
   # distinguish between reading, writing or other modes)
   def get_sys_IO(mode: str = 'w') -> IO[str]:
       if mode == 'w':
           return sys.stdout
       elif mode == 'r':
           return sys.stdin
       else:
           return sys.stdout


You can even make your own duck types using :ref:`protocol-types`.

Forward references
******************

.. code-block:: python

   # You may want to reference a class before it is defined.
   # This is known as a "forward reference".
   def f(foo: A) -> int:  # This will fail at runtime with 'A' is not defined
       ...

   # However, if you add the following special import:
   from __future__ import annotations
   # It will work at runtime and type checking will succeed as long as there
   # is a class of that name later on in the file
   def f(foo: A) -> int:  # Ok
       ...

   # Another option is to just put the type in quotes
   def f(foo: 'A') -> int:  # Also ok
       ...

   class A:
       # This can also come up if you need to reference a class in a type
       # annotation inside the definition of that class
       @classmethod
       def create(cls) -> A:
           ...

See :ref:`forward-references` for more details.

Decorators
**********

Decorator functions can be expressed via generics. See
:ref:`declaring-decorators` for more details. Example using Python 3.12
syntax:

.. code-block:: python

    from collections.abc import Callable
    from typing import Any

    def bare_decorator[F: Callable[..., Any]](func: F) -> F:
        ...

    def decorator_args[F: Callable[..., Any]](url: str) -> Callable[[F], F]:
        ...

The same example using pre-3.12 syntax:

.. code-block:: python

    from collections.abc import Callable
    from typing import Any, TypeVar

    F = TypeVar('F', bound=Callable[..., Any])

    def bare_decorator(func: F) -> F:
        ...

    def decorator_args(url: str) -> Callable[[F], F]:
        ...

Coroutines and asyncio
**********************

See :ref:`async-and-await` for the full detail on typing coroutines and asynchronous code.

.. code-block:: python

   import asyncio

   # A coroutine is typed like a normal function
   async def countdown(tag: str, count: int) -> str:
       while count > 0:
           print(f'T-minus {count} ({tag})')
           await asyncio.sleep(0.1)
           count -= 1
       return "Blastoff!"

---

## File: docs/source/class_basics.rst

.. _class-basics:

Class basics
============

This section will help get you started annotating your
classes. Built-in classes such as ``int`` also follow these same
rules.

Instance and class attributes
*****************************

The mypy type checker detects if you are trying to access a missing
attribute, which is a very common programming error. For this to work
correctly, instance and class attributes must be defined or
initialized within the class. Mypy infers the types of attributes:

.. code-block:: python

   class A:
       def __init__(self, x: int) -> None:
           self.x = x  # Aha, attribute 'x' of type 'int'

   a = A(1)
   a.x = 2  # OK!
   a.y = 3  # Error: "A" has no attribute "y"

This is a bit like each class having an implicitly defined
:py:data:`__slots__ <object.__slots__>` attribute. This is only enforced during type
checking and not when your program is running.

You can declare types of variables in the class body explicitly using
a type annotation:

.. code-block:: python

   class A:
       x: list[int]  # Declare attribute 'x' of type list[int]

   a = A()
   a.x = [1]     # OK

As in Python generally, a variable defined in the class body can be used
as a class or an instance variable. (As discussed in the next section, you
can override this with a :py:data:`~typing.ClassVar` annotation.)

Similarly, you can give explicit types to instance variables defined
in a method:

.. code-block:: python

   class A:
       def __init__(self) -> None:
           self.x: list[int] = []

       def f(self) -> None:
           self.y: Any = 0

You can only define an instance variable within a method if you assign
to it explicitly using ``self``:

.. code-block:: python

   class A:
       def __init__(self) -> None:
           self.y = 1   # Define 'y'
           a = self
           a.x = 1      # Error: 'x' not defined

Annotating __init__ methods
***************************

The :py:meth:`__init__ <object.__init__>` method is somewhat special -- it doesn't return a
value.  This is best expressed as ``-> None``.  However, since many feel
this is redundant, it is allowed to omit the return type declaration
on :py:meth:`__init__ <object.__init__>` methods **if at least one argument is annotated**.  For
example, in the following classes :py:meth:`__init__ <object.__init__>` is considered fully
annotated:

.. code-block:: python

   class C1:
       def __init__(self) -> None:
           self.var = 42

   class C2:
       def __init__(self, arg: int):
           self.var = arg

However, if :py:meth:`__init__ <object.__init__>` has no annotated arguments and no return type
annotation, it is considered an untyped method:

.. code-block:: python

   class C3:
       def __init__(self):
           # This body is not type checked
           self.var = 42 + 'abc'

Class attribute annotations
***************************

You can use a :py:data:`ClassVar[t] <typing.ClassVar>` annotation to explicitly declare that a
particular attribute should not be set on instances:

.. code-block:: python

  from typing import ClassVar

  class A:
      x: ClassVar[int] = 0  # Class variable only

  A.x += 1  # OK

  a = A()
  a.x = 1  # Error: Cannot assign to class variable "x" via instance
  print(a.x)  # OK -- can be read through an instance

It's not necessary to annotate all class variables using
:py:data:`~typing.ClassVar`. An attribute without the :py:data:`~typing.ClassVar` annotation can
still be used as a class variable. However, mypy won't prevent it from
being used as an instance variable, as discussed previously:

.. code-block:: python

  class A:
      x = 0  # Can be used as a class or instance variable

  A.x += 1  # OK

  a = A()
  a.x = 1  # Also OK

Note that :py:data:`~typing.ClassVar` is not a class, and you can't use it with
:py:func:`isinstance` or :py:func:`issubclass`. It does not change Python
runtime behavior -- it's only for type checkers such as mypy (and
also helpful for human readers).

You can also omit the square brackets and the variable type in
a :py:data:`~typing.ClassVar` annotation, but this might not do what you'd expect:

.. code-block:: python

   class A:
       y: ClassVar = 0  # Type implicitly Any!

In this case the type of the attribute will be implicitly ``Any``.
This behavior will change in the future, since it's surprising.

An explicit :py:data:`~typing.ClassVar` may be particularly handy to distinguish
between class and instance variables with callable types. For example:

.. code-block:: python

   from collections.abc import Callable
   from typing import ClassVar

   class A:
       foo: Callable[[int], None]
       bar: ClassVar[Callable[[A, int], None]]
       bad: Callable[[A], None]

   A().foo(42)  # OK
   A().bar(42)  # OK
   A().bad()  # Error: Too few arguments

.. note::
   A :py:data:`~typing.ClassVar` type parameter cannot include type variables:
   ``ClassVar[T]`` and ``ClassVar[list[T]]``
   are both invalid if ``T`` is a type variable (see :ref:`generic-classes`
   for more about type variables).

Overriding statically typed methods
***********************************

When overriding a statically typed method, mypy checks that the
override has a compatible signature:

.. code-block:: python

   class Base:
       def f(self, x: int) -> None:
           ...

   class Derived1(Base):
       def f(self, x: str) -> None:   # Error: type of 'x' incompatible
           ...

   class Derived2(Base):
       def f(self, x: int, y: int) -> None:  # Error: too many arguments
           ...

   class Derived3(Base):
       def f(self, x: int) -> None:   # OK
           ...

   class Derived4(Base):
       def f(self, x: float) -> None:   # OK: mypy treats int as a subtype of float
           ...

   class Derived5(Base):
       def f(self, x: int, y: int = 0) -> None:   # OK: accepts more than the base
           ...                                    #     class method

.. note::

   You can also vary return types **covariantly** in overriding. For
   example, you could override the return type ``Iterable[int]`` with a
   subtype such as ``list[int]``. Similarly, you can vary argument types
   **contravariantly** -- subclasses can have more general argument types.

In order to ensure that your code remains correct when renaming methods,
it can be helpful to explicitly mark a method as overriding a base
method. This can be done with the ``@override`` decorator. ``@override``
can be imported from ``typing`` starting with Python 3.12 or from
``typing_extensions`` for use with older Python versions. If the base
method is then renamed while the overriding method is not, mypy will
show an error:

.. code-block:: python

   from typing import override

   class Base:
       def f(self, x: int) -> None:
           ...
       def g_renamed(self, y: str) -> None:
           ...

   class Derived1(Base):
       @override
       def f(self, x: int) -> None:   # OK
           ...

       @override
       def g(self, y: str) -> None:   # Error: no corresponding base method found
           ...

.. note::

   Use :ref:`--enable-error-code explicit-override <code-explicit-override>` to require
   that method overrides use the ``@override`` decorator. Emit an error if it is missing.

You can also override a statically typed method with a dynamically
typed one. This allows dynamically typed code to override methods
defined in library classes without worrying about their type
signatures.

As always, relying on dynamically typed code can be unsafe. There is no
runtime enforcement that the method override returns a value that is
compatible with the original return type, since annotations have no
effect at runtime:

.. code-block:: python

   class Base:
       def inc(self, x: int) -> int:
           return x + 1

   class Derived(Base):
       def inc(self, x):   # Override, dynamically typed
           return 'hello'  # Incompatible with 'Base', but no mypy error

Abstract base classes and multiple inheritance
**********************************************

Mypy supports Python :doc:`abstract base classes ` (ABCs). Abstract classes
have at least one abstract method or property that must be implemented
by any *concrete* (non-abstract) subclass. You can define abstract base
classes using the :py:class:`abc.ABCMeta` metaclass and the :py:func:`@abc.abstractmethod <abc.abstractmethod>`
function decorator. Example:

.. code-block:: 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

Note that mypy performs checking for unimplemented abstract methods
even if you omit the :py:class:`~abc.ABCMeta` metaclass. This can be useful if the
metaclass would cause runtime metaclass conflicts.

Since you can't create instances of ABCs, they are most commonly used in
type annotations. For example, this method accepts arbitrary iterables
containing arbitrary animals (instances of concrete ``Animal``
subclasses):

.. code-block:: python

   def feed_all(animals: Iterable[Animal], food: str) -> None:
       for animal in animals:
           animal.eat(food)

There is one important peculiarity about how ABCs work in Python --
whether a particular class is abstract or not is somewhat implicit.
In the example below, ``Derived`` is treated as an abstract base class
since ``Derived`` inherits an abstract ``f`` method from ``Base`` and
doesn't explicitly implement it. The definition of ``Derived``
generates no errors from mypy, since it's a valid ABC:

.. code-block:: python

   from abc import ABCMeta, abstractmethod

   class Base(metaclass=ABCMeta):
       @abstractmethod
       def f(self, x: int) -> None: pass

   class Derived(Base):  # No error -- Derived is implicitly abstract
       def g(self) -> None:
           ...

Attempting to create an instance of ``Derived`` will be rejected,
however:

.. code-block:: python

   d = Derived()  # Error: 'Derived' is abstract

.. note::

   It's a common error to forget to implement an abstract method.
   As shown above, the class definition will not generate an error
   in this case, but any attempt to construct an instance will be
   flagged as an error.

Mypy allows you to omit the body for an abstract method, but if you do so,
it is unsafe to call such method via ``super()``. For example:

.. code-block:: python

   from abc import abstractmethod
   class Base:
       @abstractmethod
       def foo(self) -> int: pass
       @abstractmethod
       def bar(self) -> int:
           return 0
   class Sub(Base):
       def foo(self) -> int:
           return super().foo() + 1  # error: Call to abstract method "foo" of "Base"
                                     # with trivial body via super() is unsafe
       @abstractmethod
       def bar(self) -> int:
           return super().bar() + 1  # This is OK however.

A class can inherit any number of classes, both abstract and
concrete. As with normal overrides, a dynamically typed method can
override or implement a statically typed method defined in any base
class, including an abstract method defined in an abstract base class.

You can implement an abstract property using either a normal
property or an instance variable.

Slots
*****

When a class has explicitly defined :std:term:`__slots__`,
mypy will check that all attributes assigned to are members of ``__slots__``:

.. code-block:: python

  class Album:
      __slots__ = ('name', 'year')

      def __init__(self, name: str, year: int) -> None:
         self.name = name
         self.year = year
         # Error: Trying to assign name "released" that is not in "__slots__" of type "Album"
         self.released = True

  my_album = Album('Songs about Python', 2021)

Mypy will only check attribute assignments against ``__slots__`` when
the following conditions hold:

1. All base classes (except builtin ones) must have explicit
   ``__slots__`` defined (this mirrors Python semantics).

2. ``__slots__`` does not include ``__dict__``. If ``__slots__``
   includes ``__dict__``, arbitrary attributes can be set, similar to
   when ``__slots__`` is not defined (this mirrors Python semantics).

3. All values in ``__slots__`` must be string literals.

---

## File: docs/source/command_line.rst

.. _command-line:

.. program:: mypy

The mypy command line
=====================

This section documents mypy's command line interface. You can view
a quick summary of the available flags by running :option:`mypy --help`.

.. note::

   Command line flags are liable to change between releases.


Specifying what to type check
*****************************

By default, you can specify what code you want mypy to type check
by passing in the paths to what you want to have type checked::

    $ mypy foo.py bar.py some_directory

Note that directories are checked recursively.

Mypy also lets you specify what code to type check in several other
ways. A short summary of the relevant flags is included below:
for full details, see :ref:`running-mypy`.

.. option:: -m MODULE, --module MODULE

    Asks mypy to type check the provided module. This flag may be
    repeated multiple times.

    Mypy *will not* recursively type check any submodules of the provided
    module.

.. option:: -p PACKAGE, --package PACKAGE

    Asks mypy to type check the provided package. This flag may be
    repeated multiple times.

    Mypy *will* recursively type check any submodules of the provided
    package. This flag is identical to :option:`--module` apart from this
    behavior.

.. option:: -c PROGRAM_TEXT, --command PROGRAM_TEXT

    Asks mypy to type check the provided string as a program.


.. option:: --exclude

    A regular expression that matches file names, directory names and paths
    which mypy should ignore while recursively discovering files to check.
    Use forward slashes on all platforms.

    For instance, to avoid discovering any files named `setup.py` you could
    pass ``--exclude '/setup\.py$'``. Similarly, you can ignore discovering
    directories with a given name by e.g. ``--exclude /build/`` or
    those matching a subpath with ``--exclude /project/vendor/``. To ignore
    multiple files / directories / paths, you can provide the --exclude
    flag more than once, e.g ``--exclude '/setup\.py$' --exclude '/build/'``.

    Note that this flag only affects recursive directory tree discovery, that
    is, when mypy is discovering files within a directory tree or submodules of
    a package to check. If you pass a file or module explicitly it will still be
    checked. For instance, ``mypy --exclude '/setup.py$'
    but_still_check/setup.py``.

    In particular, ``--exclude`` does not affect mypy's discovery of files
    via :ref:`import following <follow-imports>`. You can use a per-module
    :confval:`ignore_errors` config option to silence errors from a given module,
    or a per-module :confval:`follow_imports` config option to additionally avoid
    mypy from following imports and checking code you do not wish to be checked.

    Note that mypy will never recursively discover files and directories named
    "site-packages", "node_modules" or "__pycache__", or those whose name starts
    with a period, exactly as ``--exclude
    '/(site-packages|node_modules|__pycache__|\..*)/$'`` would. Mypy will also
    never recursively discover files with extensions other than ``.py`` or
    ``.pyi``.

.. option:: --exclude-gitignore

    This flag will add everything that matches ``.gitignore`` file(s) to :option:`--exclude`.


Optional arguments
******************

.. option:: -h, --help

    Show help message and exit.

.. option:: -v, --verbose

    More verbose messages.

.. option:: -V, --version

    Show program's version number and exit.

.. option:: -O FORMAT, --output FORMAT {json}

    Set a custom output format.

.. _config-file-flag:

Config file
***********

.. option:: --config-file CONFIG_FILE

    This flag makes mypy read configuration settings from the given file.

    By default settings are read from ``mypy.ini``, ``.mypy.ini``, ``pyproject.toml``, or ``setup.cfg``
    in the current directory. Settings override mypy's built-in defaults and
    command line flags can override settings.

    Specifying :option:`--config-file= <--config-file>` (with no filename) will ignore *all*
    config files.

    See :ref:`config-file` for the syntax of configuration files.

.. option:: --warn-unused-configs

    This flag makes mypy warn about unused ``[mypy-]`` config
    file sections.
    (This requires turning off incremental mode using :option:`--no-incremental`.)


.. _import-discovery:

Import discovery
****************

The following flags customize how exactly mypy discovers and follows
imports.

.. option:: --explicit-package-bases

    This flag tells mypy that top-level packages will be based in either the
    current directory, or a member of the ``MYPYPATH`` environment variable or
    :confval:`mypy_path` config option. This option is only useful
    in the absence of `__init__.py`. See :ref:`Mapping file
    paths to modules <mapping-paths-to-modules>` for details.

.. option:: --ignore-missing-imports

    This flag makes mypy ignore all missing imports. It is equivalent
    to adding ``# type: ignore`` comments to all unresolved imports
    within your codebase.

    Note that this flag does *not* suppress errors about missing names
    in successfully resolved modules. For example, if one has the
    following files::

        package/__init__.py
        package/mod.py

    Then mypy will generate the following errors with :option:`--ignore-missing-imports`:

    .. code-block:: python

        import package.unknown      # No error, ignored
        x = package.unknown.func()  # OK. 'func' is assumed to be of type 'Any'

        from package import unknown          # No error, ignored
        from package.mod import NonExisting  # Error: Module has no attribute 'NonExisting'

    For more details, see :ref:`ignore-missing-imports`.

.. option:: --follow-untyped-imports

    This flag makes mypy analyze imports from installed packages even if
    missing a :ref:`py.typed marker or stubs `.

    .. warning::

        Note that analyzing all unannotated modules might result in issues
        when analyzing code not designed to be type checked and may significantly
        increase how long mypy takes to run.

.. option:: --follow-imports {normal,silent,skip,error}

    This flag adjusts how mypy follows imported modules that were not
    explicitly passed in via the command line.

    The default option is ``normal``: mypy will follow and type check
    all modules. For more information on what the other options do,
    see :ref:`Following imports <follow-imports>`.

.. option:: --python-executable EXECUTABLE

    This flag will have mypy collect type information from :pep:`561`
    compliant packages installed for the Python executable ``EXECUTABLE``.
    If not provided, mypy will use PEP 561 compliant packages installed for
    the Python executable running mypy.

    See :ref:`installed-packages` for more on making PEP 561 compliant packages.

.. option:: --no-site-packages

    This flag will disable searching for :pep:`561` compliant packages. This
    will also disable searching for a usable Python executable.

    Use this  flag if mypy cannot find a Python executable for the version of
    Python being checked, and you don't need to use PEP 561 typed packages.
    Otherwise, use :option:`--python-executable`.

.. option:: --no-silence-site-packages

    By default, mypy will suppress any error messages generated within :pep:`561`
    compliant packages. Adding this flag will disable this behavior.

.. option:: --fast-module-lookup

    The default logic used to scan through search paths to resolve imports has a
    quadratic worse-case behavior in some cases, which is for instance triggered
    by a large number of folders sharing a top-level namespace as in::

        foo/
            company/
                foo/
                    a.py
        bar/
            company/
                bar/
                    b.py
        baz/
            company/
                baz/
                    c.py
        ...

    If you are in this situation, you can enable an experimental fast path by
    setting the :option:`--fast-module-lookup` option.


.. option:: --no-namespace-packages

    This flag disables import discovery of namespace packages (see :pep:`420`).
    In particular, this prevents discovery of packages that don't have an
    ``__init__.py`` (or ``__init__.pyi``) file.

    This flag affects how mypy finds modules and packages explicitly passed on
    the command line. It also affects how mypy determines fully qualified module
    names for files passed on the command line. See :ref:`Mapping file paths to
    modules <mapping-paths-to-modules>` for details.


.. _platform-configuration:

Platform configuration
**********************

By default, mypy will assume that you intend to run your code using the same
operating system and Python version you are using to run mypy itself. The
following flags let you modify this behavior.

For more information on how to use these flags, see :ref:`version_and_platform_checks`.

.. option:: --python-version X.Y

    This flag will make mypy type check your code as if it were
    run under Python version X.Y. Without this option, mypy will default to using
    whatever version of Python is running mypy.

    This flag will attempt to find a Python executable of the corresponding
    version to search for :pep:`561` compliant packages. If you'd like to
    disable this, use the :option:`--no-site-packages` flag (see
    :ref:`import-discovery` for more details).

.. option:: --platform PLATFORM

    This flag will make mypy type check your code as if it were
    run under the given operating system. Without this option, mypy will
    default to using whatever operating system you are currently using.

    The ``PLATFORM`` parameter may be any string supported by
    :py:data:`sys.platform`.

.. _always-true:

.. option:: --always-true NAME

    This flag will treat all variables named ``NAME`` as
    compile-time constants that are always true.  This flag may
    be repeated.

.. option:: --always-false NAME

    This flag will treat all variables named ``NAME`` as
    compile-time constants that are always false.  This flag may
    be repeated.


.. _disallow-dynamic-typing:

Disallow dynamic typing
***********************

The ``Any`` type is used to represent a value that has a :ref:`dynamic type <dynamic-typing>`.
The ``--disallow-any`` family of flags will disallow various uses of the ``Any`` type in
a module -- this lets us strategically disallow the use of dynamic typing in a controlled way.

The following options are available:

.. option:: --disallow-any-unimported

    This flag disallows usage of types that come from unfollowed imports
    (such types become aliases for ``Any``). Unfollowed imports occur either
    when the imported module does not exist or when :option:`--follow-imports=skip <--follow-imports>`
    is set.

.. option:: --disallow-any-expr

    This flag disallows all expressions in the module that have type ``Any``.
    If an expression of type ``Any`` appears anywhere in the module
    mypy will output an error unless the expression is immediately
    used as an argument to :py:func:`~typing.cast` or assigned to a variable with an
    explicit type annotation.

    In addition, declaring a variable of type ``Any``
    or casting to type ``Any`` is not allowed. Note that calling functions
    that take parameters of type ``Any`` is still allowed.

.. option:: --disallow-any-decorated

    This flag disallows functions that have ``Any`` in their signature
    after decorator transformation.

.. option:: --disallow-any-explicit

    This flag disallows explicit ``Any`` in type positions such as type
    annotations and generic type parameters.

.. option:: --disallow-any-generics

    This flag disallows usage of generic types that do not specify explicit
    type parameters. For example, you can't use a bare ``x: list``. Instead, you
    must always write something like ``x: list[int]``.

.. option:: --disallow-subclassing-any

    This flag reports an error whenever a class subclasses a value of
    type ``Any``.  This may occur when the base class is imported from
    a module that doesn't exist (when using
    :option:`--ignore-missing-imports`) or is
    ignored due to :option:`--follow-imports=skip <--follow-imports>` or a
    ``# type: ignore`` comment on the ``import`` statement.

    Since the module is silenced, the imported class is given a type of ``Any``.
    By default mypy will assume that the subclass correctly inherited
    the base class even though that may not actually be the case.  This
    flag makes mypy raise an error instead.


.. _untyped-definitions-and-calls:

Untyped definitions and calls
*****************************

The following flags configure how mypy handles untyped function
definitions or calls.

.. option:: --disallow-untyped-calls

    This flag reports an error whenever a function with type annotations
    calls a function defined without annotations.

.. option:: --untyped-calls-exclude

    This flag allows one to selectively disable :option:`--disallow-untyped-calls`
    for functions and methods defined in specific packages, modules, or classes.
    Note that each exclude entry acts as a prefix. For example (assuming there
    are no type annotations for ``third_party_lib`` available):

    .. code-block:: python

        # mypy --disallow-untyped-calls
        #      --untyped-calls-exclude=third_party_lib.module_a
        #      --untyped-calls-exclude=foo.A
        from third_party_lib.module_a import some_func
        from third_party_lib.module_b import other_func
        import foo

        some_func()  # OK, function comes from module `third_party_lib.module_a`
        other_func()  # E: Call to untyped function "other_func" in typed context

        foo.A().meth()  # OK, method was defined in class `foo.A`
        foo.B().meth()  # E: Call to untyped function "meth" in typed context

        # file foo.py
        class A:
            def meth(self): pass
        class B:
            def meth(self): pass

.. option:: --disallow-untyped-defs

    This flag reports an error whenever it encounters a function definition
    without type annotations or with incomplete type annotations.
    (a superset of :option:`--disallow-incomplete-defs`).

    For example, it would report an error for :code:`def f(a, b)` and :code:`def f(a: int, b)`.

.. option:: --disallow-incomplete-defs

    This flag reports an error whenever it encounters a partly annotated
    function definition, while still allowing entirely unannotated definitions.

    For example, it would report an error for :code:`def f(a: int, b)` but not :code:`def f(a, b)`.

.. option:: --check-untyped-defs

    This flag is less severe than the previous two options -- it type checks
    the body of every function, regardless of whether it has type annotations.
    (By default the bodies of functions without annotations are not type
    checked.)

    It will assume all arguments have type ``Any`` and always infer ``Any``
    as the return type.

.. option:: --disallow-untyped-decorators

    This flag reports an error whenever a function with type annotations
    is decorated with a decorator without annotations.


.. _none-and-optional-handling:

None and Optional handling
**************************

The following flags adjust how mypy handles values of type ``None``.

.. _implicit-optional:

.. option:: --implicit-optional

    This flag causes mypy to treat parameters with a ``None``
    default value as having an implicit optional type (``T | None``).

    For example, if this flag is set, mypy would assume that the ``x``
    parameter is actually of type ``int | None`` in the code snippet below,
    since the default parameter is ``None``:

    .. code-block:: python

        def foo(x: int = None) -> None:
            print(x)

    **Note:** This was disabled by default starting in mypy 0.980.

.. _no_strict_optional:

.. option:: --no-strict-optional

    This flag effectively disables checking of optional
    types and ``None`` values. With this option, mypy doesn't
    generally check the use of ``None`` values -- it is treated
    as compatible with every type.

    .. warning::

        ``--no-strict-optional`` is evil. Avoid using it and definitely do
        not use it without understanding what it does.


.. _configuring-warnings:

Configuring warnings
********************

The following flags enable warnings for code that is sound but is
potentially problematic or redundant in some way.

.. option:: --warn-redundant-casts

    This flag will make mypy report an error whenever your code uses
    an unnecessary cast that can safely be removed.

.. option:: --warn-unused-ignores

    This flag will make mypy report an error whenever your code uses
    a ``# type: ignore`` comment on a line that is not actually
    generating an error message.

    This flag, along with the :option:`--warn-redundant-casts` flag, are both
    particularly useful when you are upgrading mypy. Previously,
    you may have needed to add casts or ``# type: ignore`` annotations
    to work around bugs in mypy or missing stubs for 3rd party libraries.

    These two flags let you discover cases where either workarounds are
    no longer necessary.

.. option:: --no-warn-no-return

    By default, mypy will generate errors when a function is missing
    return statements in some execution paths. The only exceptions
    are when:

    -   The function has a ``None`` or ``Any`` return type
    -   The function has an empty body and is marked as an abstract method,
        is in a protocol class, or is in a stub file
    -  The execution path can never return; for example, if an exception
        is always raised

    Passing in :option:`--no-warn-no-return` will disable these error
    messages in all cases.

.. option:: --warn-return-any

    This flag causes mypy to generate a warning when returning a value
    with type ``Any`` from a function declared with a non-``Any`` return type.

.. option:: --warn-unreachable

    This flag will make mypy report an error whenever it encounters
    code determined to be unreachable or redundant after performing type analysis.
    This can be a helpful way of detecting certain kinds of bugs in your code.

    For example, enabling this flag will make mypy report that the ``x > 7``
    check is redundant and that the ``else`` block below is unreachable.

    .. code-block:: python

        def process(x: int) -> None:
            # Error: Right operand of "or" is never evaluated
            if isinstance(x, int) or x > 7:
                # Error: Unsupported operand types for + ("int" and "str")
                print(x + "bad")
            else:
                # Error: 'Statement is unreachable' error
                print(x + "bad")

    To help prevent mypy from generating spurious warnings, the "Statement is
    unreachable" warning will be silenced in exactly three cases:

    1.  When the unreachable statement is a ``raise`` statement, is an
        ``assert False`` statement, or calls a function that has the :py:data:`~typing.NoReturn`
        return type hint. In other words, when the unreachable statement
        throws an error or terminates the program in some way.
    2.  When the unreachable statement is ``return NotImplemented``. This
        is allowed by mypy due to its use in operator overloading.
    3.  When the unreachable statement was *intentionally* marked as unreachable
        using :ref:`version_and_platform_checks`.

    .. note::

        Mypy currently cannot detect and report unreachable or redundant code
        inside any functions using :ref:`value-constrained type variables <value-constrained-type-variables>`.

        This limitation will be removed in future releases of mypy.

.. option:: --report-deprecated-as-note

    If error code ``deprecated`` is enabled, mypy emits errors if your code
    imports or uses deprecated features. This flag converts such errors to
    notes, causing mypy to eventually finish with a zero exit code. Features
    are considered deprecated when decorated with ``warnings.deprecated``.

.. option:: --deprecated-calls-exclude

    This flag allows one to selectively disable :ref:`deprecated<code-deprecated>` warnings
    for functions and methods defined in specific packages, modules, or classes.
    Note that each exclude entry acts as a prefix. For example (assuming ``foo.A.func`` is deprecated):

    .. code-block:: python

        # mypy --enable-error-code deprecated
        #      --deprecated-calls-exclude=foo.A
        import foo

        foo.A().func()  # OK, the deprecated warning is ignored

        # file foo.py
        from typing_extensions import deprecated
        class A:
            @deprecated("Use A.func2 instead")
            def func(self): pass

.. _miscellaneous-strictness-flags:

Miscellaneous strictness flags
******************************

This section documents any other flags that do not neatly fall under any
of the above sections.

.. option:: --allow-untyped-globals

    This flag causes mypy to suppress errors caused by not being able to fully
    infer the types of global and class variables.

.. option:: --allow-redefinition

    By default, mypy won't allow a variable to be redefined with an
    unrelated type. This flag enables the redefinition of *unannotated*
    variables with an arbitrary type. This also requires
    :option:`--local-partial-types <mypy --no-local-partial-types>`, which is
    enabled by default starting from mypy 2.0. Example:

    .. code-block:: python

        def maybe_convert(n: int, b: bool) -> int | str:
            if b:
                x = str(n)  # Assign "str"
            else:
                x = n       # Assign "int"
            # Type of "x" is "int | str" here.
            return x

    Without this flag, mypy only supports inferring optional types
    (``X | None``) from multiple assignments. With this option enabled,
    mypy can infer arbitrary union types.

    This also enables an unannotated variable to have different types in different
    code locations:

    .. code-block:: python

        if check():
            for x in range(n):
                # Type of "x" is "int" here.
                ...
        else:
            for x in ['a', 'b']:
                # Type of "x" is "str" here.
                ...

    Function arguments are special, changing their type within function body
    is allowed even if they are annotated, but that annotation is used to infer
    types of r.h.s. of all subsequent assignments. Such middle-ground semantics
    provides good balance for majority of common use cases. For example:

    .. code-block:: python

        def process(values: list[float]) -> None:
            if not values:
                values = [0, 0, 0]
            reveal_type(values)  # Revealed type is list[float]

    Note: We are planning to turn this flag on by default in a future mypy
    release.

.. option:: --allow-redefinition-new

    Deprecated alias for :option:`--allow-redefinition <mypy --allow-redefinition>`.

.. option:: --allow-redefinition-old

    This is an older, more limited variant of
    :option:`--allow-redefinition <mypy --allow-redefinition>`.
    This flag enables redefinition of a variable with an
    arbitrary type *in some contexts*: only redefinitions within the
    same block and nesting depth as the original definition are allowed.

    We have no plans to remove this flag, but
    :option:`--allow-redefinition <mypy --allow-redefinition>`
    is recommended for new use cases.

    Example where this can be useful:

    .. code-block:: python

       def process(items: list[str]) -> None:
           # 'items' has type list[str]
           items = [item.split() for item in items]
           # 'items' now has type list[list[str]]

    The variable must be used before it can be redefined:

    .. code-block:: python

        def process(items: list[str]) -> None:
           items = "mypy"  # invalid redefinition to str because the variable hasn't been used yet
           print(items)
           items = "100"  # valid, items now has type str
           items = int(items)  # valid, items now has type int

.. option:: --no-local-partial-types

    Disable local partial types to enable legacy type inference mode for
    containers.

    Local partial types prevent inferring a container type for a variable, when
    the initial assignment happens at module top level or in a class body, and
    the container item type is only set in a function. Example:

    .. code-block:: python

        a = []  # Need type annotation unless using --no-local-partial-types

        def func() -> None:
            a.append(1)

        reveal_type(a)  # "list[int]" if using --no-local-partial-types

    Local partial types are enabled by default starting from mypy 2.0. The
    mypy daemon requires local partial types.

.. option:: --no-implicit-reexport

    By default, imported values to a module are treated as exported and mypy allows
    other modules to import them. This flag changes the behavior to not re-export unless
    the item is imported using from-as or is included in ``__all__``. Note this is
    always treated as enabled for stub files. For example:

    .. code-block:: python

       # This won't re-export the value
       from foo import bar

       # Neither will this
       from foo import bar as bang

       # This will re-export it as bar and allow other modules to import it
       from foo import bar as bar

       # This will also re-export bar
       from foo import bar
       __all__ = ['bar']


.. option:: --strict-equality

    By default, mypy allows always-false comparisons like ``42 == 'no'``.
    Use this flag to prohibit such comparisons of non-overlapping types, and
    similar identity and container checks:

    .. code-block:: python

       items: list[int]
       if 'some string' in items:  # Error: non-overlapping container check!
           ...

       text: str
       if text != b'other bytes':  # Error: non-overlapping equality check!
           ...

       assert text is not None  # OK, check against None is allowed


.. option:: --strict-equality-for-none

    This flag extends :option:`--strict-equality <mypy --strict-equality>` for checks
    against ``None``:

    .. code-block:: python

       text: str
       assert text is not None  # Error: non-overlapping identity check!

    Note that :option:`--strict-equality-for-none <mypy --strict-equality-for-none>`
    only works in combination with :option:`--strict-equality <mypy --strict-equality>`.

.. option:: --no-strict-bytes

    Treat ``bytearray`` and ``memoryview`` as subtypes of ``bytes``. This is not true
    at runtime and can lead to unexpected behavior. This was the default behavior prior
    to mypy 2.0.

    .. code-block:: python

       def f(buf: bytes) -> None:
           assert isinstance(buf, bytes)  # Raises runtime AssertionError with bytearray/memoryview
           with open("binary_file", "wb") as fp:
               fp.write(buf)

       # Using --no-strict-bytes disables the following errors
       f(bytearray(b""))  # Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
       f(memoryview(b""))  # Argument 1 to "f" has incompatible type "memoryview"; expected "bytes"

       # If `f` accepts any object that implements the buffer protocol,
       # consider using Buffer instead:
       from collections.abc import Buffer  # "from typing_extensions" in Python 3.11 and earlier

       def f(buf: Buffer) -> None:
           with open("binary_file", "wb") as fp:
               fp.write(buf)

       f(b"")  # Ok
       f(bytearray(b""))  # Ok
       f(memoryview(b""))  # Ok


.. option:: --extra-checks

    This flag enables additional checks that are technically correct but may be
    impractical. In particular, it prohibits partial overlap in ``TypedDict`` updates,
    and makes arguments prepended via ``Concatenate`` positional-only. For example:

    .. code-block:: python

       from typing import TypedDict

       class Foo(TypedDict):
           a: int

       class Bar(TypedDict):
           a: int
           b: int

       def test(foo: Foo, bar: Bar) -> None:
           # This is technically unsafe since foo can have a subtype of Foo at
           # runtime, where type of key "b" is incompatible with int, see below
           bar.update(foo)

       class Bad(Foo):
           b: str
       bad: Bad = {"a": 0, "b": "no"}
       test(bad, bar)

    In future more checks may be added to this flag if:

    * The corresponding use cases are rare, thus not justifying a dedicated
      strictness flag.

    * The new check cannot be supported as an opt-in error code.

.. option:: --strict

    This flag mode enables a defined subset of optional error-checking flags.
    This subset primarily includes checks for inadvertent type unsoundness (i.e
    strict will catch type errors as long as intentional methods like type ignore
    or casting were not used.)

    Note: the :option:`--warn-unreachable` flag
    is not automatically enabled by the strict flag.

    The strict flag does not take precedence over other strict-related flags.
    Directly specifying a flag of alternate behavior will override the
    behavior of strict, regardless of the order in which they are passed.
    You can see the list of flags enabled by strict mode in the full
    :option:`mypy --help` output.

    Note: the exact list of flags enabled by running :option:`--strict` may change
    over time.

    .. include:: strict_list.rst
    ..
        The above file is autogenerated and included during html generation.
        (That's an include directive, and this is a comment.)
        It would be fine to generate it at some other time instead,
        theoretically, but we already had a convenient hook during html gen.


.. option:: --disable-error-code

    This flag allows disabling one or multiple error codes globally.
    See :ref:`error-codes` for more information.

    .. code-block:: python

        # no flag
        x = 'a string'
        x.trim()  # error: "str" has no attribute "trim"  [attr-defined]

        # When using --disable-error-code attr-defined
        x = 'a string'
        x.trim()

.. option:: --enable-error-code

    This flag allows enabling one or multiple error codes globally.
    See :ref:`error-codes` for more information.

    Note: This flag will override disabled error codes from the
    :option:`--disable-error-code <mypy --disable-error-code>` flag.

    .. code-block:: python

        # When using --disable-error-code attr-defined
        x = 'a string'
        x.trim()

        # --disable-error-code attr-defined --enable-error-code attr-defined
        x = 'a string'
        x.trim()  # error: "str" has no attribute "trim"  [attr-defined]


.. _configuring-error-messages:

Configuring error messages
**************************

The following flags let you adjust how much detail mypy displays
in error messages.

.. option:: --show-error-context

    This flag will precede all errors with "note" messages explaining the
    context of the error. For example, consider the following program:

    .. code-block:: python

        class Test:
            def foo(self, x: int) -> int:
                return x + "bar"

    Mypy normally displays an error message that looks like this::

        main.py:3: error: Unsupported operand types for + ("int" and "str")

    If we enable this flag, the error message now looks like this::

        main.py: note: In member "foo" of class "Test":
        main.py:3: error: Unsupported operand types for + ("int" and "str")

.. option:: --show-column-numbers

    This flag will add column offsets to error messages.
    For example, the following indicates an error in line 12, column 9
    (note that column offsets are 0-based)::

        main.py:12:9: error: Unsupported operand types for / ("int" and "str")

.. option:: --show-error-code-links

    This flag will also display a link to error code documentation, anchored to the error code reported by mypy.
    The corresponding error code will be highlighted within the documentation page.
    If we enable this flag, the error message now looks like this::

        main.py:3: error: Unsupported operand types for - ("int" and "str")  [operator]
        main.py:3: note: See 'https://mypy.rtfd.io/en/stable/_refs.html#code-operator' for more info



.. option:: --show-error-end

    This flag will make mypy show not just that start position where
    an error was detected, but also the end position of the relevant expression.
    This way various tools can easily highlight the whole error span. The format is
    ``file:line:column:end_line:end_column``. This option implies
    ``--show-column-numbers``.

.. option:: --hide-error-codes

    This flag will hide the error code ``[<code>]`` from error messages. By default, the error
    code is shown after each error message::

        prog.py:1: error: "str" has no attribute "trim"  [attr-defined]

    See :ref:`error-codes` for more information.

.. option:: --pretty

    Use visually nicer output in error messages: use soft word wrap,
    show source code snippets, and show error location markers.

.. option:: --no-color-output

    This flag will disable color output in error messages, enabled by default.

.. option:: --no-error-summary

    This flag will disable error summary. By default mypy shows a summary line
    including total number of errors, number of files with errors, and number
    of files checked.

.. option:: --show-absolute-path

    Show absolute paths to files.

.. option:: --soft-error-limit N

    This flag will adjust the limit after which mypy will (sometimes)
    disable reporting most additional errors. The limit only applies
    if it seems likely that most of the remaining errors will not be
    useful or they may be overly noisy. If ``N`` is negative, there is
    no limit. The default limit is -1.


.. _incremental:

Incremental mode
****************

By default, mypy will store type information into a cache. Mypy
will use this information to avoid unnecessary recomputation when
it type checks your code again.  This can help speed up the type
checking process, especially when most parts of your program have
not changed since the previous mypy run.

If you want to speed up how long it takes to recheck your code
beyond what incremental mode can offer, try running mypy in
:ref:`daemon mode <mypy_daemon>`.

.. option:: --no-incremental

    This flag disables incremental mode: mypy will no longer reference
    the cache when re-run.

    Note that mypy will still write out to the cache even when
    incremental mode is disabled: see the :option:`--cache-dir` flag below
    for more details.

.. option:: --cache-dir DIR

    By default, mypy stores all cache data inside of a folder named
    ``.mypy_cache`` in the current directory. This flag lets you
    change this folder. This flag can also be useful for controlling
    cache use when using :ref:`remote caching <remote-cache>`.

    This setting will override the ``MYPY_CACHE_DIR`` environment
    variable if it is set.

    Mypy will also always write to the cache even when incremental
    mode is disabled so it can "warm up" the cache. To disable
    writing to the cache, use ``--cache-dir=/dev/null`` (UNIX)
    or ``--cache-dir=nul`` (Windows).

.. option:: --no-sqlite-cache

    Avoid using `SQLite`_ database to store the cache, instead write cache data
    out to individual files.

.. option:: --cache-fine-grained

    Include fine-grained dependency information in the cache for the mypy daemon.

.. option:: --skip-version-check

    By default, mypy will ignore cache data generated by a different
    version of mypy. This flag disables that behavior.

.. option:: --skip-cache-mtime-checks

    Skip cache internal consistency checks based on mtime.


.. _parallel:

Parallel type-checking
**********************

By default, mypy checks all modules in the same Python process. This can be slow
for large code bases. Mypy offers experimental parallel type-checking mode using
multiple worker processes. In parallel mode, modules that do not depend om each
other are type-checked in parallel. :ref:`Incremental cache ` is
used to manage most of the shared state. Parallel type-checking also requires
:option:`--local-partial-types <mypy --no-local-partial-types>`, which is
enabled by default starting from mypy 2.0.

.. option:: -n NUMBER, --num-workers NUMBER

    Use ``NUMBER`` parallel worker processes (in addition to the coordinator
    process) to perform type-checking. Specifying ``--num-workers 0`` (default)
    disables parallel checking. Automatic detection of the optimal number
    of workers is not supported yet.

    This setting will override the ``MYPY_NUM_WORKERS`` environment
    variable if it is set.

Notes:

* An import cycle is always processed as a whole by a worker process. Thus,
  avoiding large import cycles in your code will *significantly* improve
  type-checking speed.

* Specifying a number of workers that is larger than the number of *physical*
  CPU cores is not beneficial, since mypy is usually CPU bound. Best way to
  tune the number of workers on a given machine is to start from 3-4 workers
  and increase the number while you see a performance improvement.

* Parallel mode requires and automatically enables :option:`--native-parser`.


Advanced options
****************

The following flags are useful mostly for people who are interested
in developing or debugging mypy internals.

.. option:: --pdb

    This flag will invoke the Python debugger when mypy encounters
    a fatal error.

.. option:: --show-traceback, --tb

    If set, this flag will display a full traceback when mypy
    encounters a fatal error.

.. option:: --raise-exceptions

    Raise exception on fatal error.

.. option:: --custom-typing-module MODULE

    This flag lets you use a custom module as a substitute for the
    :py:mod:`typing` module.

.. option:: --custom-typeshed-dir DIR

    This flag specifies the directory where mypy looks for standard library typeshed
    stubs, instead of the typeshed that ships with mypy.  This is
    primarily intended to make it easier to test typeshed changes before
    submitting them upstream, but also allows you to use a forked version of
    typeshed.

    Note that this doesn't affect third-party library stubs. To test third-party stubs,
    for example try ``MYPYPATH=stubs/six mypy ...``.

.. _warn-incomplete-stub:

.. option:: --warn-incomplete-stub

    This flag modifies both the :option:`--disallow-untyped-defs` and
    :option:`--disallow-incomplete-defs` flags so they also report errors
    if stubs in typeshed are missing type annotations or has incomplete
    annotations. If both flags are missing, :option:`--warn-incomplete-stub`
    also does nothing.

    This flag is mainly intended to be used by people who want contribute
    to typeshed and would like a convenient way to find gaps and omissions.

    If you want mypy to report an error when your codebase *uses* an untyped
    function, whether that function is defined in typeshed or not, use the
    :option:`--disallow-untyped-calls` flag. See :ref:`untyped-definitions-and-calls`
    for more details.

.. _shadow-file:

.. option:: --shadow-file SOURCE_FILE SHADOW_FILE

    When mypy is asked to type check ``SOURCE_FILE``, this flag makes mypy
    read from and type check the contents of ``SHADOW_FILE`` instead. However,
    diagnostics will continue to refer to ``SOURCE_FILE``.

    Specifying this argument multiple times (``--shadow-file X1 Y1 --shadow-file X2 Y2``)
    will allow mypy to perform multiple substitutions.

    This allows tooling to create temporary files with helpful modifications
    without having to change the source file in place. For example, suppose we
    have a pipeline that adds ``reveal_type`` for certain variables.
    This pipeline is run on ``original.py`` to produce ``temp.py``.
    Running ``mypy --shadow-file original.py temp.py original.py`` will then
    cause mypy to type check the contents of ``temp.py`` instead of  ``original.py``,
    but error messages will still reference ``original.py``.

.. option:: --native-parser

    This enables fast Rust-based parser that parses directly to mypy AST.
    It will become the default parser in one of the next mypy releases.


Report generation
*****************

If these flags are set, mypy will generate a report in the specified
format into the specified directory.

.. option:: --any-exprs-report DIR

    Causes mypy to generate a text file report documenting how many
    expressions of type ``Any`` are present within your codebase.

.. option:: --cobertura-xml-report DIR

    Causes mypy to generate a Cobertura XML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. option:: --html-report / --xslt-html-report DIR

    Causes mypy to generate an HTML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. option:: --linecount-report DIR

    Causes mypy to generate a text file report documenting the functions
    and lines that are typed and untyped within your codebase.

.. option:: --linecoverage-report DIR

    Causes mypy to generate a JSON file that maps each source file's
    absolute filename to a list of line numbers that belong to typed
    functions in that file.

.. option:: --lineprecision-report DIR

    Causes mypy to generate a flat text file report with per-module
    statistics of how many lines are typechecked etc.

.. option:: --txt-report / --xslt-txt-report DIR

    Causes mypy to generate a text file type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. option:: --xml-report DIR

    Causes mypy to generate an XML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.


Enabling incomplete/experimental features
*****************************************

.. option:: --enable-incomplete-feature {PreciseTupleTypes,InlineTypedDict}

    Some features may require several mypy releases to implement, for example
    due to their complexity, potential for backwards incompatibility, or
    ambiguous semantics that would benefit from feedback from the community.
    You can enable such features for early preview using this flag. Note that
    it is not guaranteed that all features will be ultimately enabled by
    default. In *rare cases* we may decide to not go ahead with certain
    features.

List of currently incomplete/experimental features:

* ``PreciseTupleTypes``: this feature will infer more precise tuple types in
  various scenarios. Before variadic types were added to the Python type system
  by :pep:`646`, it was impossible to express a type like "a tuple with
  at least two integers". The best type available was ``tuple[int, ...]``.
  Therefore, mypy applied very lenient checking for variable-length tuples.
  Now this type can be expressed as ``tuple[int, int, *tuple[int, ...]]``.
  For such more precise types (when explicitly *defined* by a user) mypy,
  for example, warns about unsafe index access, and generally handles them
  in a type-safe manner. However, to avoid problems in existing code, mypy
  does not *infer* these precise types when it technically can. Here are
  notable examples where ``PreciseTupleTypes`` infers more precise types:

  .. code-block:: python

     numbers: tuple[int, ...]

     more_numbers = (1, *numbers, 1)
     reveal_type(more_numbers)
     # Without PreciseTupleTypes: tuple[int, ...]
     # With PreciseTupleTypes: tuple[int, *tuple[int, ...], int]

     other_numbers = (1, 1) + numbers
     reveal_type(other_numbers)
     # Without PreciseTupleTypes: tuple[int, ...]
     # With PreciseTupleTypes: tuple[int, int, *tuple[int, ...]]

     if len(numbers) > 2:
         reveal_type(numbers)
         # Without PreciseTupleTypes: tuple[int, ...]
         # With PreciseTupleTypes: tuple[int, int, int, *tuple[int, ...]]
     else:
         reveal_type(numbers)
         # Without PreciseTupleTypes: tuple[int, ...]
         # With PreciseTupleTypes: tuple[()] | tuple[int] | tuple[int, int]

* ``InlineTypedDict``: this feature enables non-standard syntax for inline
  :ref:`TypedDicts <typeddict>`, for example:

  .. code-block:: python

     def test_values() -> {"width": int, "description": str}:
         return {"width": 42, "description": "test"}



Miscellaneous
*************

.. option:: --install-types

    This flag causes mypy to install known missing stub packages for
    third-party libraries using pip.  It will display the pip command
    that will be run, and expects a confirmation before installing
    anything. For security reasons, these stubs are limited to only a
    small subset of manually selected packages that have been
    verified by the typeshed team. These packages include only stub
    files and no executable code.

    If you use this option without providing any files or modules to
    type check, mypy will install stub packages suggested during the
    previous mypy run. If there are files or modules to type check,
    mypy first type checks those, and proposes to install missing
    stubs at the end of the run, but only if any missing modules were
    detected.

    .. note::

        This is new in mypy 0.900. Previous mypy versions included a
        selection of third-party package stubs, instead of having
        them installed separately.

.. option:: --non-interactive

   When used together with :option:`--install-types <mypy
   --install-types>`, this causes mypy to install all suggested stub
   packages using pip without asking for confirmation, and then
   continues to perform type checking using the installed stubs, if
   some files or modules are provided to type check.

   This is implemented as up to two mypy runs internally. The first run
   is used to find missing stub packages, and output is shown from
   this run only if no missing stub packages were found. If missing
   stub packages were found, they are installed and then another run
   is performed.

.. option:: --junit-xml JUNIT_XML_OUTPUT_FILE

    Causes mypy to generate a JUnit XML test result document with
    type checking results. This can make it easier to integrate mypy
    with continuous integration (CI) tools.

.. option:: --junit-format {global,per_file}

    If --junit-xml is set, specifies format.
    global (default): single test with all errors;
    per_file: one test entry per file with failures.

.. option:: --find-occurrences CLASS.MEMBER

    This flag will make mypy print out all usages of a class member
    based on static type information. This feature is experimental.

.. option:: --scripts-are-modules

    This flag will give command line arguments that appear to be
    scripts (i.e. files whose name does not end in ``.py``)
    a module name derived from the script name rather than the fixed
    name :py:mod:`__main__`.

    This lets you check more than one script in a single mypy invocation.
    (The default :py:mod:`__main__` is technically more correct, but if you
    have many scripts that import a large package, the behavior enabled
    by this flag is often more convenient.)

.. _lxml: https://pypi.org/project/lxml/
.. _SQLite: https://www.sqlite.org/

---

## File: docs/source/common_issues.rst

.. _common_issues:

Common issues and solutions
===========================

This section has examples of cases when you need to update your code
to use static typing, and ideas for working around issues if mypy
doesn't work as expected. Statically typed code is often identical to
normal Python code (except for type annotations), but sometimes you need
to do things slightly differently.

.. _annotations_needed:

No errors reported for obviously wrong code
-------------------------------------------

There are several common reasons why obviously wrong code is not
flagged as an error.

**The function containing the error is not annotated.**

Functions that
do not have any annotations (neither for any argument nor for the
return type) are not type-checked, and even the most blatant type
errors (e.g. ``2 + 'a'``) pass silently.  The solution is to add
annotations. Where that isn't possible, functions without annotations
can be checked using :option:`--check-untyped-defs <mypy --check-untyped-defs>`.

Example:

.. code-block:: python

    def foo(a):
        return '(' + a.split() + ')'  # No error!

This gives no error even though ``a.split()`` is "obviously" a list
(the author probably meant ``a.strip()``).  The error is reported
once you add annotations:

.. code-block:: python

    def foo(a: str) -> str:
        return '(' + a.split() + ')'
    # error: Unsupported operand types for + ("str" and "list[str]")

If you don't know what types to add, you can use ``Any``, but beware:

**One of the values involved has type 'Any'.**

Extending the above
example, if we were to leave out the annotation for ``a``, we'd get
no error:

.. code-block:: python

    def foo(a) -> str:
        return '(' + a.split() + ')'  # No error!

The reason is that if the type of ``a`` is unknown, the type of
``a.split()`` is also unknown, so it is inferred as having type
``Any``, and it is no error to add a string to an ``Any``.

If you're having trouble debugging such situations,
:ref:`reveal_type() <reveal-type>` might come in handy.

Note that sometimes library stubs with imprecise type information
can be a source of ``Any`` values.

:py:meth:`__init__ <object.__init__>` **method has no annotated
arguments and no return type annotation.**

This is basically a combination of the two cases above, in that ``__init__``
without annotations can cause ``Any`` types leak into instance variables:

.. code-block:: python

    class Bad:
        def __init__(self):
            self.value = "asdf"
            1 + "asdf"  # No error!

    bad = Bad()
    bad.value + 1           # No error!
    reveal_type(bad)        # Revealed type is "__main__.Bad"
    reveal_type(bad.value)  # Revealed type is "Any"

    class Good:
        def __init__(self) -> None:  # Explicitly return None
            self.value = value


**Some imports may be silently ignored**.

A common source of unexpected ``Any`` values is the
:option:`--ignore-missing-imports <mypy --ignore-missing-imports>` flag.

When you use :option:`--ignore-missing-imports <mypy --ignore-missing-imports>`,
any imported module that cannot be found is silently replaced with ``Any``.

To help debug this, simply leave out
:option:`--ignore-missing-imports <mypy --ignore-missing-imports>`.
As mentioned in :ref:`fix-missing-imports`, setting ``ignore_missing_imports=True``
on a per-module basis will make bad surprises less likely and is highly encouraged.

Use of the :option:`--follow-imports=skip <mypy --follow-imports>` flags can also
cause problems. Use of these flags is strongly discouraged and only required in
relatively niche situations. See :ref:`follow-imports` for more information.

**mypy considers some of your code unreachable**.

See :ref:`unreachable` for more information.

**A function annotated as returning a non-optional type returns 'None'
and mypy doesn't complain**.

.. code-block:: python

    def foo() -> str:
        return None  # No error!

You may have disabled strict optional checking (see
:ref:`--no-strict-optional <no_strict_optional>` for more).

.. _silencing_checker:

Spurious errors and locally silencing the checker
-------------------------------------------------

You can use a ``# type: ignore`` comment to silence the type checker
on a particular line. For example, let's say our code is using
the C extension module ``frobnicate``, and there's no stub available.
Mypy will complain about this, as it has no information about the
module:

.. code-block:: python

    import frobnicate  # Error: No module "frobnicate"
    frobnicate.start()

You can add a ``# type: ignore`` comment to tell mypy to ignore this
error:

.. code-block:: python

    import frobnicate  # type: ignore
    frobnicate.start()  # Okay!

The second line is now fine, since the ignore comment causes the name
``frobnicate`` to get an implicit ``Any`` type.

The type ignore comment must be at the start of the comments on a line.
This type ignore will not take effect:

.. code-block:: python

    import frobnicate  #example other comment # type: ignore
    frobnicate.start()

.. note::

    You can use the form ``# type: ignore[<code>]`` to only ignore
    specific errors on the line. This way you are less likely to
    silence unexpected errors that are not safe to ignore, and this
    will also document what the purpose of the comment is.  See
    :ref:`error-codes` for more information.

.. note::

    The ``# type: ignore`` comment will only assign the implicit ``Any``
    type if mypy cannot find information about that particular module. So,
    if we did have a stub available for ``frobnicate`` then mypy would
    ignore the ``# type: ignore`` comment and typecheck the stub as usual.

Another option is to explicitly annotate values with type ``Any`` --
mypy will let you perform arbitrary operations on ``Any``
values. Sometimes there is no more precise type you can use for a
particular value, especially if you use dynamic Python features
such as :py:meth:`__getattr__ <object.__getattr__>`:

.. code-block:: python

   class Wrapper:
       ...
       def __getattr__(self, a: str) -> Any:
           return getattr(self._wrapped, a)

Finally, you can create a stub file (``.pyi``) for a file that
generates spurious errors. Mypy will only look at the stub file
and ignore the implementation, since stub files take precedence
over ``.py`` files.

Ignoring a whole file
---------------------

* To only ignore errors, use a top-level ``# mypy: ignore-errors`` comment instead.
* To only ignore errors with a specific error code, use a top-level
  ``# mypy: disable-error-code="..."`` comment. Example: ``# mypy: disable-error-code="truthy-bool, ignore-without-code"``
* To replace the contents of a module with ``Any``, use a per-module ``follow_imports = skip``.
  See :ref:`Following imports <follow-imports>` for details.

Note that a ``# type: ignore`` comment at the top of a module (before any statements,
including imports or docstrings) has the effect of ignoring the entire contents of the module.
This behaviour can be surprising and result in
"Module ... has no attribute ... [attr-defined]" errors.

Issues with code at runtime
---------------------------

Idiomatic use of type annotations can sometimes run up against what a given
version of Python considers legal code. These can result in some of the
following errors when trying to run your code:

* ``ImportError`` from circular imports
* ``NameError: name "X" is not defined`` from forward references
* ``TypeError: 'type' object is not subscriptable`` from types that are not generic at runtime
* ``ImportError`` or ``ModuleNotFoundError`` from use of stub definitions not available at runtime
* ``TypeError: unsupported operand type(s) for |: 'type' and 'type'`` from use of new syntax

For dealing with these, see :ref:`runtime_troubles`.

Mypy runs are slow
------------------

If your mypy runs feel slow, you should probably use the :ref:`mypy
daemon <mypy_daemon>`, which can speed up incremental mypy runtimes by
a factor of 10 or more. :ref:`Remote caching <remote-cache>` can
make cold mypy runs several times faster.

Furthermore: as of `mypy 1.13 <https://mypy-lang.blogspot.com/2024/10/mypy-113-released.html>`_,
mypy allows use of the orjson library for handling the cache instead of the stdlib json, for
improved performance. You can ensure the presence of orjson using the ``faster-cache`` extra:

    python3 -m pip install -U mypy[faster-cache]

Mypy may depend on orjson by default in the future.

Types of empty collections
--------------------------

You often need to specify the type when you assign an empty list or
dict to a new variable, as mentioned earlier:

.. code-block:: python

   a: list[int] = []

Without the annotation mypy can't always figure out the
precise type of ``a``.

You can use a simple empty list literal in a dynamically typed function (as the
type of ``a`` would be implicitly ``Any`` and need not be inferred), if type
of the variable has been declared or inferred before, or if you perform a simple
modification operation in the same scope (such as ``append`` for a list):

.. code-block:: python

   a = []  # Okay because followed by append, inferred type list[int]
   for i in range(n):
       a.append(i * i)

However, in more complex cases an explicit type annotation can be
required (mypy will tell you this). Often the annotation can
make your code easier to understand, so it doesn't only help mypy but
everybody who is reading the code!

Redefinitions with incompatible types
-------------------------------------

Each name within a function only has a single 'declared' type. You can
reuse for loop indices etc., but if you want to use a variable with
multiple types within a single function, you may need to instead use
multiple variables (or maybe declare the variable with an ``Any`` type).

.. code-block:: python

   def f() -> None:
       n = 1
       ...
       n = 'x'  # error: Incompatible types in assignment (expression has type "str", variable has type "int")

.. note::

   Using the :option:`--allow-redefinition <mypy --allow-redefinition>`
   flag can suppress this error in several cases.

Note that you can redefine a variable with a more *precise* or a more
concrete type. For example, you can redefine a sequence (which does
not support ``sort()``) as a list and sort it in-place:

.. code-block:: python

    def f(x: Sequence[int]) -> None:
        # Type of x is Sequence[int] here; we don't know the concrete type.
        x = list(x)
        # Type of x is list[int] here.
        x.sort()  # Okay!

See :ref:`type-narrowing` for more information.

.. _variance:

Invariance vs covariance
------------------------

Most mutable generic collections are invariant. When using the legacy
``TypeVar`` syntax, mypy considers all user-defined generic classes invariant
by default (see :ref:`variance-of-generics` for motivation). When using the
:pep:`695` syntax (``class MyClass[T]: ...``), variance is inferred from
usage rather than defaulting to invariant.

The fact that mutable sequences are usually invariant can lead to some
unexpected errors when combined with type inference. For example:

.. code-block:: python

   class A: ...
   class B(A): ...

   lst = [A(), A()]  # Inferred type is list[A]
   new_lst = [B(), B()]  # inferred type is list[B]
   lst = new_lst  # mypy will complain about this, because List is invariant

Possible strategies in such situations are:

* Use an explicit type annotation:

  .. code-block:: python

     new_lst: list[A] = [B(), B()]
     lst = new_lst  # OK

* Make a copy of the right hand side:

  .. code-block:: python

     lst = list(new_lst) # Also OK

* Use immutable collections as annotations whenever possible:

  .. code-block:: python

     def f_bad(x: list[A]) -> A:
         return x[0]
     f_bad(new_lst) # Fails

     def f_good(x: Sequence[A]) -> A:
         return x[0]
     f_good(new_lst) # OK

Declaring a supertype as variable type
--------------------------------------

Sometimes the inferred type is a subtype (subclass) of the desired
type. The type inference uses the first assignment to infer the type
of a name:

.. code-block:: python

   class Shape: ...
   class Circle(Shape): ...
   class Triangle(Shape): ...

   shape = Circle()    # mypy infers the type of shape to be Circle
   shape = Triangle()  # error: Incompatible types in assignment (expression has type "Triangle", variable has type "Circle")

You can just give an explicit type for the variable in cases such the
above example:

.. code-block:: python

   shape: Shape = Circle()  # The variable s can be any Shape, not just Circle
   shape = Triangle()       # OK

Complex type tests
------------------

Mypy can usually infer the types correctly when using :py:func:`isinstance `,
:py:func:`issubclass `,
or ``type(obj) is some_class`` type tests,
and even :ref:`user-defined type guards <type-guards>`,
but for other kinds of checks you may need to add an
explicit type cast:

.. code-block:: python

  from collections.abc import Sequence
  from typing import cast

  def find_first_str(a: Sequence[object]) -> str:
      index = next((i for i, s in enumerate(a) if isinstance(s, str)), -1)
      if index < 0:
          raise ValueError('No str found')

      found = a[index]  # Has type "object", despite the fact that we know it is "str"
      return cast(str, found)  # We need an explicit cast to make mypy happy

Alternatively, you can use an ``assert`` statement together with some
of the supported type inference techniques:

.. code-block:: python

  def find_first_str(a: Sequence[object]) -> str:
      index = next((i for i, s in enumerate(a) if isinstance(s, str)), -1)
      if index < 0:
          raise ValueError('No str found')

      found = a[index]  # Has type "object", despite the fact that we know it is "str"
      assert isinstance(found, str)  # Now, "found" will be narrowed to "str"
      return found  # No need for the explicit "cast()" anymore

.. note::

    Note that the :py:class:`object` type used in the above example is similar
    to ``Object`` in Java: it only supports operations defined for *all*
    objects, such as equality and :py:func:`isinstance`. The type ``Any``,
    in contrast, supports all operations, even if they may fail at
    runtime. The cast above would have been unnecessary if the type of
    ``o`` was ``Any``.

.. note::

   You can read more about type narrowing techniques :ref:`here <type-narrowing>`.

Type inference in Mypy is designed to work well in common cases, to be
predictable and to let the type checker give useful error
messages. More powerful type inference strategies often have complex
and difficult-to-predict failure modes and could result in very
confusing error messages. The tradeoff is that you as a programmer
sometimes have to give the type checker a little help.

.. _version_and_platform_checks:

Python version and system platform checks
-----------------------------------------

Mypy supports the ability to perform Python version checks and platform
checks (e.g. Windows vs Posix), ignoring code paths that won't be run on
the targeted Python version or platform. This allows you to more effectively
typecheck code that supports multiple versions of Python or multiple operating
systems.

More specifically, mypy will understand the use of :py:data:`sys.version_info` and
:py:data:`sys.platform` checks within ``if/elif/else`` statements. For example:

.. code-block:: python

   import sys

   # Distinguishing between different versions of Python:
   if sys.version_info >= (3, 13):
       # Python 3.13+ specific definitions and imports
   else:
       # Other definitions and imports

   # Distinguishing between different operating systems:
   if sys.platform.startswith("linux"):
       # Linux-specific code
   elif sys.platform == "darwin":
       # Mac-specific code
   elif sys.platform == "win32":
       # Windows-specific code
   else:
       # Other systems

As a special case, you can also use one of these checks in a top-level
(unindented) ``assert``; this makes mypy skip the rest of the file.
Example:

.. code-block:: python

   import sys

   assert sys.platform != 'win32'

   # The rest of this file doesn't apply to Windows.

Some other expressions exhibit similar behavior; in particular,
:py:data:`~typing.TYPE_CHECKING`, variables named ``MYPY`` or ``TYPE_CHECKING``, and any variable
whose name is passed to :option:`--always-true <mypy --always-true>` or :option:`--always-false <mypy --always-false>`.
(However, ``True`` and ``False`` are not treated specially!)

.. note::

   Mypy currently does not support more complex checks, and does not assign
   any special meaning when assigning a :py:data:`sys.version_info` or :py:data:`sys.platform`
   check to a variable. This may change in future versions of mypy.

By default, mypy will use your current version of Python and your current
operating system as default values for :py:data:`sys.version_info` and
:py:data:`sys.platform`.

To target a different Python version, use the :option:`--python-version X.Y <mypy --python-version>` flag.
For example, to verify your code typechecks if were run using Python 3.8, pass
in :option:`--python-version 3.8 <mypy --python-version>` from the command line. Note that you do not need
to have Python 3.8 installed to perform this check.

To target a different operating system, use the :option:`--platform PLATFORM <mypy --platform>` flag.
For example, to verify your code typechecks if it were run in Windows, pass
in :option:`--platform win32 <mypy --platform>`. See the documentation for :py:data:`sys.platform`
for examples of valid platform parameters.

.. _reveal-type:

Displaying the type of an expression
------------------------------------

You can use ``reveal_type(expr)`` to ask mypy to display the inferred
static type of an expression. This can be useful when you don't quite
understand how mypy handles a particular piece of code. Example:

.. code-block:: python

   reveal_type((1, 'hello'))  # Revealed type is "tuple[builtins.int, builtins.str]"

You can also use ``reveal_locals()`` at any line in a file
to see the types of all local variables at once. Example:

.. code-block:: python

   a = 1
   b = 'one'
   reveal_locals()
   # Revealed local types are:
   #     a: builtins.int
   #     b: builtins.str
.. note::

    ``reveal_type`` and ``reveal_locals`` are handled specially by mypy during
    type checking, and don't have to be defined or imported.

    However, if you want to run your code,
    you'll have to remove any ``reveal_type`` and ``reveal_locals``
    calls from your program or else Python will give you an error at runtime.

    Alternatively, you can import ``reveal_type`` from ``typing_extensions``
    or ``typing`` (on Python 3.11 and newer)

.. _silencing-linters:

Silencing linters
-----------------

In some cases, linters will complain about unused imports or code. In
these cases, you can silence them with a comment after type comments, or on
the same line as the import:

.. code-block:: python

   # to silence complaints about unused imports
   from typing import List  # noqa
   a = None  # type: List[int]


To silence the linter on the same line as a type comment
put the linter comment *after* the type comment:

.. code-block:: python

    a = some_complex_thing()  # type: ignore  # noqa

Covariant subtyping of mutable protocol members is rejected
-----------------------------------------------------------

Mypy rejects this because this is potentially unsafe.
Consider this example:

.. code-block:: python

   from typing import Protocol

   class P(Protocol):
       x: float

   def fun(arg: P) -> None:
       arg.x = 3.14

   class C:
       x = 42
   c = C()
   fun(c)  # This is not safe
   c.x << 5  # Since this will fail!

To work around this problem consider whether "mutating" is actually part
of a protocol. If not, then one can use a :py:class:`@property ` in
the protocol definition:

.. code-block:: python

   from typing import Protocol

   class P(Protocol):
       @property
       def x(self) -> float:
          pass

   def fun(arg: P) -> None:
       ...

   class C:
       x = 42
   fun(C())  # OK

Dealing with conflicting names
------------------------------

Suppose you have a class with a method whose name is the same as an
imported (or built-in) type, and you want to use the type in another
method signature.  E.g.:

.. code-block:: python

   class Message:
       def bytes(self):
           ...
       def register(self, path: bytes):  # error: Invalid type "mod.Message.bytes"
           ...

The third line elicits an error because mypy sees the argument type
``bytes`` as a reference to the method by that name.  Other than
renaming the method, a workaround is to use an alias:

.. code-block:: python

   bytes_ = bytes
   class Message:
       def bytes(self):
           ...
       def register(self, path: bytes_):
           ...

Using a development mypy build
------------------------------

You can install the latest development version of mypy from source. Clone the
`mypy repository on GitHub <https://github.com/python/mypy>`_, and then run
``pip install`` locally:

.. code-block:: text

    git clone https://github.com/python/mypy.git
    cd mypy
    python3 -m pip install --upgrade .

To install a development version of mypy that is mypyc-compiled, see the
instructions at the `mypyc wheels repo <https://github.com/mypyc/mypy_mypyc-wheels>`_.

Variables vs type aliases
-------------------------

Mypy has both *type aliases* and variables with types like ``type[...]``. These are
subtly different, and it's important to understand how they differ to avoid pitfalls.

1. A variable with type ``type[...]`` is defined using an assignment with an
   explicit type annotation:

   .. code-block:: python

     class A: ...
     tp: type[A] = A

2. You can define a type alias using an assignment without an explicit type annotation
   at the top level of a module:

   .. code-block:: python

     class A: ...
     Alias = A

   You can also use ``TypeAlias`` (:pep:`613`) to define an *explicit type alias*:

   .. code-block:: python

     from typing import TypeAlias

     class A: ...
     Alias: TypeAlias = A

   You should always use ``TypeAlias`` to define a type alias in a class body or
   inside a function.

The main difference is that the target of an alias is precisely known statically, and this
means that they can be used in type annotations and other *type contexts*. Type aliases
can't be defined conditionally (unless using
:ref:`supported Python version and platform checks <version_and_platform_checks>`):

   .. code-block:: python

     class A: ...
     class B: ...

     if random() > 0.5:
         Alias = A
     else:
         # error: Cannot assign multiple types to name "Alias" without an
         # explicit "Type[...]" annotation
         Alias = B

     tp: type[object]  # "tp" is a variable with a type object value
     if random() > 0.5:
         tp = A
     else:
         tp = B  # This is OK

     def fun1(x: Alias) -> None: ...  # OK
     def fun2(x: tp) -> None: ...  # Error: "tp" is not valid as a type

Incompatible overrides
----------------------

It's unsafe to override a method with a more specific argument type,
as it violates the `Liskov substitution principle
<https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle>`_.
For return types, it's unsafe to override a method with a more general
return type.

Other incompatible signature changes in method overrides, such as
adding an extra required parameter, or removing an optional parameter,
will also generate errors. The signature of a method in a subclass
should accept all valid calls to the base class method. Mypy
treats a subclass as a subtype of the base class. An instance of a
subclass is valid everywhere where an instance of the base class is
valid.

This example demonstrates both safe and unsafe overrides:

.. code-block:: python

    from collections.abc import Sequence, Iterable

    class A:
        def test(self, t: Sequence[int]) -> Sequence[str]:
            ...

    class GeneralizedArgument(A):
        # A more general argument type is okay
        def test(self, t: Iterable[int]) -> Sequence[str]:  # OK
            ...

    class NarrowerArgument(A):
        # A more specific argument type isn't accepted
        def test(self, t: list[int]) -> Sequence[str]:  # Error
            ...

    class NarrowerReturn(A):
        # A more specific return type is fine
        def test(self, t: Sequence[int]) -> list[str]:  # OK
            ...

    class GeneralizedReturn(A):
        # A more general return type is an error
        def test(self, t: Sequence[int]) -> Iterable[str]:  # Error
            ...

You can use ``# type: ignore[override]`` to silence the error. Add it
to the line that generates the error, if you decide that type safety is
not necessary:

.. code-block:: python

    class NarrowerArgument(A):
        def test(self, t: list[int]) -> Sequence[str]:  # type: ignore[override]
            ...

.. _unreachable:

Unreachable code
----------------

Mypy may consider some code as *unreachable*, even if it might not be
immediately obvious why.  It's important to note that mypy will *not*
type check such code. Consider this example:

.. code-block:: python

    class Foo:
        bar: str = ''

    def bar() -> None:
        foo: Foo = Foo()
        return
        x: int = 'abc'  # Unreachable -- no error

It's easy to see that any statement after ``return`` is unreachable,
and hence mypy will not complain about the mistyped code below
it. For a more subtle example, consider this code:

.. code-block:: python

    class Foo:
        bar: str = ''

    def bar() -> None:
        foo: Foo = Foo()
        assert foo.bar is None
        x: int = 'abc'  # Unreachable -- no error

Again, mypy will not report any errors. The type of ``foo.bar`` is
``str``, and mypy reasons that it can never be ``None``.  Hence the
``assert`` statement will always fail and the statement below will
never be executed.  (Note that in Python, ``None`` is not an empty
reference but an object of type ``None``.)

In this example mypy will go on to check the last line and report an
error, since mypy thinks that the condition could be either True or
False:

.. code-block:: python

    class Foo:
        bar: str = ''

    def bar() -> None:
        foo: Foo = Foo()
        if not foo.bar:
            return
        x: int = 'abc'  # Reachable -- error

If you use the :option:`--warn-unreachable <mypy --warn-unreachable>` flag, mypy will generate
an error about each unreachable code block.

Narrowing and inner functions
-----------------------------

Because closures in Python are late-binding (https://docs.python-guide.org/writing/gotchas/#late-binding-closures),
mypy will not narrow the type of a captured variable in an inner function.
This is best understood via an example:

.. code-block:: python

    def foo(x: int | None) -> Callable[[], int]:
        if x is None:
            x = 5
        print(x + 1)  # mypy correctly deduces x must be an int here
        def inner() -> int:
            return x + 1  # but (correctly) complains about this line

        x = None  # because x could later be assigned None
        return inner

    inner = foo(5)
    inner()  # this will raise an error when called

To get this code to type check, you could assign ``y = x`` after ``x`` has been
narrowed, and use ``y`` in the inner function, or add an assert in the inner
function.

.. _incorrect-self:

Incorrect use of ``Self``
-------------------------

``Self`` is not the type of the current class; it's a type variable with upper
bound of the current class. That is, it represents the type of the current class
or of potential subclasses.

.. code-block:: python

    from typing import Self

    class Foo:
        @classmethod
        def constructor(cls) -> Self:
            # Instead, either call cls() or change the annotation to -> Foo
            return Foo()  # error: Incompatible return value type (got "Foo", expected "Self")

    class Bar(Foo):
        ...

    reveal_type(Foo.constructor())  # note: Revealed type is "Foo"
    # In the context of the subclass Bar, the Self return type promises
    # that the return value will be Bar
    reveal_type(Bar.constructor())  # note: Revealed type is "Bar"

---

## File: docs/source/config_file.rst

.. _config-file:

The mypy configuration file
===========================

Mypy is very configurable. This is most useful when introducing typing to
an existing codebase. See :ref:`existing-code` for concrete advice for
that situation.

Mypy supports reading configuration settings from a file. By default, mypy will
discover configuration files by walking up the file system (up until the root of
a repository or the root of the filesystem). In each directory, it will look for
the following configuration files (in this order):

    1. ``mypy.ini``
    2. ``.mypy.ini``
    3. ``pyproject.toml`` (containing a ``[tool.mypy]`` section)
    4. ``setup.cfg`` (containing a ``[mypy]`` section)

If no configuration file is found by this method, mypy will then look for
configuration files in the following locations (in this order):

    1. ``$XDG_CONFIG_HOME/mypy/config``
    2. ``~/.config/mypy/config``
    3. ``~/.mypy.ini``

The :option:`--config-file <mypy --config-file>` command-line flag has the
highest precedence and must point towards a valid configuration file;
otherwise mypy will report an error and exit. Without the command line option,
mypy will look for configuration files in the precedence order above.

It is important to understand that there is no merging of configuration
files, as it would lead to ambiguity.

Most flags correspond closely to :ref:`command-line flags
<command-line>` but there are some differences in flag names and some
flags may take a different value based on the module being processed.

Some flags support user home directory and environment variable expansion.
To refer to the user home directory, use ``~`` at the beginning of the path.
To expand environment variables use ``$VARNAME`` or ``${VARNAME}``.


Config file format
******************

The configuration file format is the usual
:doc:`ini file ` format. It should contain
section names in square brackets and flag settings of the form
`NAME = VALUE`. Comments start with ``#`` characters.

- A section named ``[mypy]`` must be present.  This specifies
  the global flags.

- Additional sections named ``[mypy-PATTERN1,PATTERN2,...]`` may be
  present, where ``PATTERN1``, ``PATTERN2``, etc., are comma-separated
  patterns of fully-qualified module names, with some components optionally
  replaced by the '*' character (e.g. ``foo.bar``, ``foo.bar.*``, ``foo.*.baz``).
  These sections specify additional flags that only apply to *modules*
  whose name matches at least one of the patterns.

  A pattern of the form ``qualified_module_name`` matches only the named module,
  while ``dotted_module_name.*`` matches ``dotted_module_name`` and any
  submodules (so ``foo.bar.*`` would match all of ``foo.bar``,
  ``foo.bar.baz``, and ``foo.bar.baz.quux``).

  Patterns may also be "unstructured" wildcards, in which stars may
  appear in the middle of a name (e.g
  ``site.*.migrations.*``). Stars match zero or more module
  components (so ``site.*.migrations.*`` can match ``site.migrations``).

  .. _config-precedence:

  When options conflict, the precedence order for configuration is:

    1. :ref:`Inline configuration ` in the source file
    2. Sections with concrete module names (``foo.bar``)
    3. Sections with "unstructured" wildcard patterns (``foo.*.baz``),
       with sections later in the configuration file overriding
       sections earlier.
    4. Sections with "well-structured" wildcard patterns
       (``foo.bar.*``), with more specific overriding more general.
    5. Command line options.
    6. Top-level configuration file options.

The difference in precedence order between "structured" patterns (by
specificity) and "unstructured" patterns (by order in the file) is
unfortunate, and is subject to change in future versions.

.. note::

   The :confval:`warn_unused_configs` flag may be useful to debug misspelled
   section names.

.. note::

   Configuration flags are liable to change between releases.


Per-module and global options
*****************************

Some of the config options may be set either globally (in the ``[mypy]`` section)
or on a per-module basis (in sections like ``[mypy-foo.bar]``).

If you set an option both globally and for a specific module, the module configuration
options take precedence. This lets you set global defaults and override them on a
module-by-module basis. If multiple pattern sections match a module, :ref:`the options from the
most specific section are used where they disagree <config-precedence>`.

Some other options, as specified in their description,
may only be set in the global section (``[mypy]``).


Inverting option values
***********************

Options that take a boolean value may be inverted by adding ``no_`` to
their name or by (when applicable) swapping their prefix from
``disallow`` to ``allow`` (and vice versa).


Example ``mypy.ini``
********************

Here is an example of a ``mypy.ini`` file. To use this config file, place it at the root
of your repo and run mypy.

.. code-block:: 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

This config file specifies two global options in the ``[mypy]`` section. These two
options will:

1.  Report an error whenever a function returns a value that is inferred
    to have type ``Any``.

2.  Report any config options that are unused by mypy. (This will help us catch typos
    when making changes to our config file).

Next, this module specifies three per-module options. The first two options change how mypy
type checks code in ``mycode.foo.*`` and ``mycode.bar``, which we assume here are two modules
that you wrote. The final config option changes how mypy type checks ``somelibrary``, which we
assume here is some 3rd party library you've installed and are importing. These options will:

1.  Selectively disallow untyped function definitions only within the ``mycode.foo``
    package -- that is, only for function definitions defined in the
    ``mycode/foo`` directory.

2.  Selectively *disable* the "function is returning any" warnings within
    ``mycode.bar`` only. This overrides the global default we set earlier.

3.  Suppress any error messages generated when your codebase tries importing the
    module ``somelibrary``. This is useful if ``somelibrary`` is some 3rd party library
    missing type hints.


.. _config-file-import-discovery:

Import discovery
****************

For more information, see the :ref:`Import discovery `
section of the command line docs.

.. confval:: mypy_path

    :type: string

    Specifies the paths to use, after trying the paths from ``MYPYPATH`` environment
    variable.  Useful if you'd like to keep stubs in your repo, along with the config file.
    Multiple paths are always separated with a ``:`` or ``,`` regardless of the platform.
    User home directory and environment variables will be expanded.

    Relative paths are treated relative to the working directory of the mypy command,
    not the config file.
    Use the ``MYPY_CONFIG_FILE_DIR`` environment variable to refer to paths relative to
    the config file (e.g. ``mypy_path = $MYPY_CONFIG_FILE_DIR/src``).

    This option may only be set in the global section (``[mypy]``).

    **Note:** On Windows, use UNC paths to avoid using ``:`` (e.g. ``\\127.0.0.1\X$\MyDir`` where ``X`` is the drive letter).

.. confval:: files

    :type: comma-separated list of strings

    A comma-separated list of paths which should be checked by mypy if none are given on the command
    line. Supports recursive file globbing using :py:mod:`glob`, where ``*`` (e.g. ``*.py``) matches
    files in the current directory and ``**/`` (e.g. ``**/*.py``) matches files in any directories below
    the current one. User home directory and environment variables will be expanded.

    This option may only be set in the global section (``[mypy]``).

.. confval:: modules

    :type: comma-separated list of strings

    A comma-separated list of packages which should be checked by mypy if none are given on the command
    line. Mypy *will not* recursively type check any submodules of the provided
    module.

    This option may only be set in the global section (``[mypy]``).


.. confval:: packages

    :type: comma-separated list of strings

    A comma-separated list of packages which should be checked by mypy if none are given on the command
    line.  Mypy *will* recursively type check any submodules of the provided
    package. This flag is identical to :confval:`modules` apart from this
    behavior.

    This option may only be set in the global section (``[mypy]``).

.. confval:: exclude

    :type: regular expression

    A regular expression that matches file names, directory names and paths
    which mypy should ignore while recursively discovering files to check.
    Use forward slashes (``/``) as directory separators on all platforms.

    .. code-block:: ini

      [mypy]
      exclude = (?x)(
          ^one\.py$    # files named "one.py"
          | two\.pyi$  # or files ending with "two.pyi"
          | ^three\.   # or files starting with "three."
        )

    Crafting a single regular expression that excludes multiple files while remaining
    human-readable can be a challenge. The above example demonstrates one approach.
    ``(?x)`` enables the ``VERBOSE`` flag for the subsequent regular expression, which
    :py:data:`ignores most whitespace and supports comments <re.VERBOSE>`.
    The above is equivalent to: ``(^one\.py$|two\.pyi$|^three\.)``.

    For more details, see :option:`--exclude <mypy --exclude>`.

    This option may only be set in the global section (``[mypy]``).

    .. note::

       Note that the TOML equivalent differs slightly. It can be either a single string
       (including a multi-line string) -- which is treated as a single regular
       expression -- or an array of such strings. The following TOML examples are
       equivalent to the above INI example.

       Array of strings:

       .. code-block:: toml

          [tool.mypy]
          exclude = [
              "^one\\.py$",  # TOML's double-quoted strings require escaping backslashes
              'two\.pyi$',  # but TOML's single-quoted strings do not
              '^three\.',
          ]

       A single, multi-line string:

       .. code-block:: toml

          [tool.mypy]
          exclude = '''(?x)(
              ^one\.py$    # files named "one.py"
              | two\.pyi$  # or files ending with "two.pyi"
              | ^three\.   # or files starting with "three."
          )'''  # TOML's single-quoted strings do not require escaping backslashes

       See :ref:`using-a-pyproject-toml`.

.. confval:: exclude_gitignore

    :type: boolean
    :default: False

    This flag will add everything that matches ``.gitignore`` file(s) to :confval:`exclude`.
    This option may only be set in the global section (``[mypy]``).

.. confval:: namespace_packages

    :type: boolean
    :default: True

    Enables :pep:`420` style namespace packages.  See the
    corresponding flag :option:`--no-namespace-packages <mypy --no-namespace-packages>`
    for more information.

    This option may only be set in the global section (``[mypy]``).

.. confval:: explicit_package_bases

    :type: boolean
    :default: False

    This flag tells mypy that top-level packages will be based in either the
    current directory, or a member of the ``MYPYPATH`` environment variable or
    :confval:`mypy_path` config option. This option is only useful in
    the absence of `__init__.py`. See :ref:`Mapping file
    paths to modules <mapping-paths-to-modules>` for details.

    This option may only be set in the global section (``[mypy]``).

.. confval:: ignore_missing_imports

    :type: boolean
    :default: False

    Suppresses error messages about imports that cannot be resolved.

    If this option is used in a per-module section, the module name should
    match the name of the *imported* module, not the module containing the
    import statement.

.. confval:: follow_untyped_imports

    :type: boolean
    :default: False

    Makes mypy analyze imports from installed packages even if missing a
    :ref:`py.typed marker or stubs `.

    If this option is used in a per-module section, the module name should
    match the name of the *imported* module, not the module containing the
    import statement.

    .. warning::

        Note that analyzing all unannotated modules might result in issues
        when analyzing code not designed to be type checked and may significantly
        increase how long mypy takes to run.

.. confval:: follow_imports

    :type: string
    :default: ``normal``

    Directs what to do with imports when the imported module is found
    as a ``.py`` file and not part of the files, modules and packages
    provided on the command line.

    The four possible values are ``normal``, ``silent``, ``skip`` and
    ``error``.  For explanations see the discussion for the
    :option:`--follow-imports <mypy --follow-imports>` command line flag.

    Using this option in a per-module section (potentially with a wildcard,
    as described at the top of this page) is a good way to prevent mypy from
    checking portions of your code.

    If this option is used in a per-module section, the module name should
    match the name of the *imported* module, not the module containing the
    import statement.

.. confval:: follow_imports_for_stubs

    :type: boolean
    :default: False

    Determines whether to respect the :confval:`follow_imports` setting even for
    stub (``.pyi``) files.

    Used in conjunction with :confval:`follow_imports=skip <follow_imports>`, this can be used
    to suppress the import of a module from ``typeshed``, replacing it
    with ``Any``.

    Used in conjunction with :confval:`follow_imports=error <follow_imports>`, this can be used
    to make any use of a particular ``typeshed`` module an error.

    .. note::

         This is not supported by the mypy daemon.

.. confval:: python_executable

    :type: string

    Specifies the path to the Python executable to inspect to collect
    a list of available :ref:`PEP 561 packages `. User
    home directory and environment variables will be expanded. Defaults to
    the executable used to run mypy.

    This option may only be set in the global section (``[mypy]``).

.. confval:: no_site_packages

    :type: boolean
    :default: False

    Disables using type information in installed packages (see :pep:`561`).
    This will also disable searching for a usable Python executable. This acts
    the same as :option:`--no-site-packages <mypy --no-site-packages>` command
    line flag.

.. confval:: no_silence_site_packages

    :type: boolean
    :default: False

    Enables reporting error messages generated within installed packages (see
    :pep:`561` for more details on distributing type information). Those error
    messages are suppressed by default, since you are usually not able to
    control errors in 3rd party code.

    This option may only be set in the global section (``[mypy]``).


Platform configuration
**********************

.. confval:: python_version

    :type: string

    Specifies the Python version used to parse and check the target
    program.  The string should be in the format ``MAJOR.MINOR`` --
    for example ``3.10``.  The default is the version of the Python
    interpreter used to run mypy.

    This option may only be set in the global section (``[mypy]``).

.. confval:: platform

    :type: string

    Specifies the OS platform for the target program, for example
    ``darwin`` or ``win32`` (meaning OS X or Windows, respectively).
    The default is the current platform as revealed by Python's
    :py:data:`sys.platform` variable.

    This option may only be set in the global section (``[mypy]``).

.. confval:: always_true

    :type: comma-separated list of strings

    Specifies a list of variables that mypy will treat as
    compile-time constants that are always true.

.. confval:: always_false

    :type: comma-separated list of strings

    Specifies a list of variables that mypy will treat as
    compile-time constants that are always false.


Disallow dynamic typing
***********************

For more information, see the :ref:`Disallow dynamic typing <disallow-dynamic-typing>`
section of the command line docs.

.. confval:: disallow_any_unimported

    :type: boolean
    :default: False

    Disallows usage of types that come from unfollowed imports (anything imported from
    an unfollowed import is automatically given a type of ``Any``).

.. confval:: disallow_any_expr

    :type: boolean
    :default: False

    Disallows all expressions in the module that have type ``Any``.

.. confval:: disallow_any_decorated

    :type: boolean
    :default: False

    Disallows functions that have ``Any`` in their signature after decorator transformation.

.. confval:: disallow_any_explicit

    :type: boolean
    :default: False

    Disallows explicit ``Any`` in type positions such as type annotations and generic
    type parameters.

.. confval:: disallow_any_generics

    :type: boolean
    :default: False

    Disallows usage of generic types that do not specify explicit type parameters.

.. confval:: disallow_subclassing_any

    :type: boolean
    :default: False

    Disallows subclassing a value of type ``Any``.


Untyped definitions and calls
*****************************

For more information, see the :ref:`Untyped definitions and calls `
section of the command line docs.

.. confval:: disallow_untyped_calls

    :type: boolean
    :default: False

    Disallows calling functions without type annotations from functions with type
    annotations. Note that when used in per-module options, it enables/disables
    this check **inside** the module(s) specified, not for functions that come
    from that module(s), for example config like this:

    .. code-block:: ini

        [mypy]
        disallow_untyped_calls = True

        [mypy-some.library.*]
        disallow_untyped_calls = False

    will disable this check inside ``some.library``, not for your code that
    imports ``some.library``. If you want to selectively disable this check for
    all your code that imports ``some.library`` you should instead use
    :confval:`untyped_calls_exclude`, for example:

    .. code-block:: ini

        [mypy]
        disallow_untyped_calls = True
        untyped_calls_exclude = some.library

.. confval:: untyped_calls_exclude

    :type: comma-separated list of strings

    Selectively excludes functions and methods defined in specific packages,
    modules, and classes from action of :confval:`disallow_untyped_calls`.
    This also applies to all submodules of packages (i.e. everything inside
    a given prefix). Note, this option does not support per-file configuration,
    the exclusions list is defined globally for all your code.

.. confval:: disallow_untyped_defs

    :type: boolean
    :default: False

    Disallows defining functions without type annotations or with incomplete type
    annotations (a superset of :confval:`disallow_incomplete_defs`).

    For example, it would report an error for :code:`def f(a, b)` and :code:`def f(a: int, b)`.

.. confval:: disallow_incomplete_defs

    :type: boolean
    :default: False

    Disallows defining functions with incomplete type annotations, while still
    allowing entirely unannotated definitions.

    For example, it would report an error for :code:`def f(a: int, b)` but not :code:`def f(a, b)`.

.. confval:: check_untyped_defs

    :type: boolean
    :default: False

    Type-checks the interior of functions without type annotations.

.. confval:: disallow_untyped_decorators

    :type: boolean
    :default: False

    Reports an error whenever a function with type annotations is decorated with a
    decorator without annotations.


.. _config-file-none-and-optional-handling:

None and Optional handling
**************************

For more information, see the :ref:`None and Optional handling <none-and-optional-handling>`
section of the command line docs.

.. confval:: implicit_optional

    :type: boolean
    :default: False

    Causes mypy to treat parameters with a ``None``
    default value as having an implicit optional type (``T | None``).

    **Note:** This was True by default in mypy versions 0.980 and earlier.

.. confval:: strict_optional

    :type: boolean
    :default: True

    Effectively disables checking of optional
    types and ``None`` values. With this option, mypy doesn't
    generally check the use of ``None`` values -- it is treated
    as compatible with every type.

    .. warning::

        ``strict_optional = false`` is evil. Avoid using it and definitely do
        not use it without understanding what it does.


Configuring warnings
********************

For more information, see the :ref:`Configuring warnings <configuring-warnings>`
section of the command line docs.

.. confval:: warn_redundant_casts

    :type: boolean
    :default: False

    Warns about casting an expression to its inferred type.

    This option may only be set in the global section (``[mypy]``).

.. confval:: warn_unused_ignores

    :type: boolean
    :default: False

    Warns about unneeded ``# type: ignore`` comments.

.. confval:: warn_no_return

    :type: boolean
    :default: True

    Shows errors for missing return statements on some execution paths.

.. confval:: warn_return_any

    :type: boolean
    :default: False

    Shows a warning when returning a value with type ``Any`` from a function
    declared with a non- ``Any`` return type.

.. confval:: warn_unreachable

    :type: boolean
    :default: False

    Shows a warning when encountering any code inferred to be unreachable or
    redundant after performing type analysis.

.. confval:: deprecated_calls_exclude

    :type: comma-separated list of strings

    Selectively excludes functions and methods defined in specific packages,
    modules, and classes from the :ref:`deprecated<code-deprecated>` error code.
    This also applies to all submodules of packages (i.e. everything inside
    a given prefix). Note, this option does not support per-file configuration,
    the exclusions list is defined globally for all your code.


Suppressing errors
******************

Note: these configuration options are available in the config file only. There is
no analog available via the command line options.

.. confval:: ignore_errors

    :type: boolean
    :default: False

    Ignores all non-fatal errors.


Miscellaneous strictness flags
******************************

For more information, see the :ref:`Miscellaneous strictness flags <miscellaneous-strictness-flags>`
section of the command line docs.

.. confval:: allow_untyped_globals

    :type: boolean
    :default: False

    Causes mypy to suppress errors caused by not being able to fully
    infer the types of global and class variables.

.. confval:: allow_redefinition

    :type: boolean
    :default: False

    By default, mypy won't allow a variable to be redefined with an
    unrelated type. This flag enables the redefinition of unannotated
    variables with an arbitrary type. This also requires
    :confval:`local_partial_types`, which is enabled by default starting
    from mypy 2.0. Example:

    .. code-block:: python

        def maybe_convert(n: int, b: bool) -> int | str:
            if b:
                x = str(n)  # Assign "str"
            else:
                x = n       # Assign "int"
            # Type of "x" is "int | str" here.
            return x

    This also enables an unannotated variable to have different types in different
    code locations:

    .. code-block:: python

        if check():
            for x in range(n):
                # Type of "x" is "int" here.
                ...
        else:
            for x in ['a', 'b']:
                # Type of "x" is "str" here.
                ...

    Function arguments are special, changing their type within function body
    is allowed even if they are annotated, but that annotation is used to infer
    types of r.h.s. of all subsequent assignments. Such middle-ground semantics
    provides good balance for majority of common use cases. For example:

    .. code-block:: python

        def process(values: list[float]) -> None:
            if not values:
                values = [0, 0, 0]
            reveal_type(values)  # Revealed type is list[float]

    Note: We are planning to turn this flag on by default in a future mypy
    release.

.. confval:: allow_redefinition_new

    :type: boolean
    :default: False

    Deprecated alias for :confval:`allow_redefinition`.

.. confval:: allow_redefinition_old

    :type: boolean
    :default: False

    Allows variables to be redefined with an arbitrary type, as long as the redefinition
    is in the same block and nesting level as the original definition.
    Example where this can be useful:

    .. code-block:: python

       def process(items: list[str]) -> None:
           # 'items' has type list[str]
           items = [item.split() for item in items]
           # 'items' now has type list[list[str]]

    The variable must be used before it can be redefined:

    .. code-block:: python

        def process(items: list[str]) -> None:
           items = "mypy"  # invalid redefinition to str because the variable hasn't been used yet
           print(items)
           items = "100"  # valid, items now has type str
           items = int(items)  # valid, items now has type int

.. confval:: local_partial_types

    :type: boolean
    :default: True

    This prevents inferring a variable type from an empty container (such as a list or
    a dictionary) created at module top level or class body and updated in
    a function. This must be enabled when using the :ref:`mypy daemon <mypy_daemon>`.

.. confval:: disable_error_code

    :type: comma-separated list of strings

    Allows disabling one or multiple error codes globally.

.. confval:: enable_error_code

    :type: comma-separated list of strings

    Allows enabling one or multiple error codes globally.

    Note: This option will override disabled error codes from the disable_error_code option.

.. confval:: extra_checks

   :type: boolean
   :default: False

   This flag enables additional checks that are technically correct but may be impractical.
   See :option:`mypy --extra-checks` for more info.

.. confval:: implicit_reexport

    :type: boolean
    :default: True

    By default, imported values to a module are treated as exported and mypy allows
    other modules to import them. When false, mypy will not re-export unless
    the item is imported using from-as or is included in ``__all__``. Note that mypy
    treats stub files as if this is always disabled. For example:

    .. code-block:: python

       # This won't re-export the value
       from foo import bar
       # This will re-export it as bar and allow other modules to import it
       from foo import bar as bar
       # This will also re-export bar
       from foo import bar
       __all__ = ['bar']

.. confval:: strict_equality

   :type: boolean
   :default: False

   Prohibit equality checks, identity checks, and container checks between
   non-overlapping types (except ``None``).

.. confval:: strict_equality_for_none

   :type: boolean
   :default: False

   Include ``None`` in strict equality checks (requires :confval:`strict_equality`
   to be activated).

.. confval:: strict_bytes

   :type: boolean
   :default: True

   If disabled, mypy treats ``bytearray`` and ``memoryview`` as subtypes of ``bytes``.
   This has been enabled by default since mypy 2.0.

.. confval:: strict

   :type: boolean
   :default: False

   Enable all optional error checking flags.  You can see the list of
   flags enabled by strict mode in the full :option:`mypy --help`
   output.

   Note: the exact list of flags enabled by :confval:`strict` may
   change over time.


Configuring error messages
**************************

For more information, see the :ref:`Configuring error messages <configuring-error-messages>`
section of the command line docs.

These options may only be set in the global section (``[mypy]``).

.. confval:: show_error_context

    :type: boolean
    :default: False

    Prefixes each error with the relevant context.

.. confval:: show_column_numbers

    :type: boolean
    :default: False

    Shows column numbers in error messages.

.. confval:: show_error_code_links

    :type: boolean
    :default: False

    Shows documentation link to corresponding error code.

.. confval:: hide_error_codes

    :type: boolean
    :default: False

    Hides error codes in error messages. See :ref:`error-codes` for more information.

.. confval:: pretty

    :type: boolean
    :default: False

    Use visually nicer output in error messages: use soft word wrap,
    show source code snippets, and show error location markers.

.. confval:: color_output

    :type: boolean
    :default: True

    Shows error messages with color enabled.

.. confval:: error_summary

    :type: boolean
    :default: True

    Shows a short summary line after error messages.

.. confval:: show_absolute_path

    :type: boolean
    :default: False

    Show absolute paths to files.

Incremental mode
****************

These options may only be set in the global section (``[mypy]``).

.. confval:: incremental

    :type: boolean
    :default: True

    Enables :ref:`incremental mode `.

.. confval:: cache_dir

    :type: string
    :default: ``.mypy_cache``

    Specifies the location where mypy stores incremental cache info.
    User home directory and environment variables will be expanded.
    This setting will be overridden by the ``MYPY_CACHE_DIR`` environment
    variable.

    Note that the cache is only read when incremental mode is enabled
    but is always written to, unless the value is set to ``/dev/null``
    (UNIX) or ``nul`` (Windows).

.. confval:: sqlite_cache

    :type: boolean
    :default: True

    Use an `SQLite`_ database to store the cache.

.. confval:: cache_fine_grained

    :type: boolean
    :default: False

    Include fine-grained dependency information in the cache for the mypy daemon.

.. confval:: skip_version_check

    :type: boolean
    :default: False

    Makes mypy use incremental cache data even if it was generated by a
    different version of mypy. (By default, mypy will perform a version
    check and regenerate the cache if it was written by older versions of mypy.)

.. confval:: skip_cache_mtime_checks

    :type: boolean
    :default: False

    Skip cache internal consistency checks based on mtime.


Parallel type-checking configuration
************************************

These options may only be set in the global section (``[mypy]``).

.. confval:: num_workers

    :type: integer
    :default: 0

    Use specific number of parallel worker processes for type-checking, see
    :ref:`parallel type-checking ` for more details.
    This setting will be overridden by the ``MYPY_NUM_WORKERS`` environment
    variable.


Advanced options
****************

These options may only be set in the global section (``[mypy]``).

.. confval:: plugins

    :type: comma-separated list of strings

    A comma-separated list of mypy plugins. See :ref:`extending-mypy-using-plugins`.

.. confval:: pdb

    :type: boolean
    :default: False

    Invokes :mod:`pdb` on fatal error.

.. confval:: show_traceback

    :type: boolean
    :default: False

    Shows traceback on fatal error.

.. confval:: raise_exceptions

    :type: boolean
    :default: False

    Raise exception on fatal error.

.. confval:: custom_typing_module

    :type: string

    Specifies a custom module to use as a substitute for the :py:mod:`typing` module.

.. confval:: custom_typeshed_dir

    :type: string

    This specifies the directory where mypy looks for standard library typeshed
    stubs, instead of the typeshed that ships with mypy.  This is
    primarily intended to make it easier to test typeshed changes before
    submitting them upstream, but also allows you to use a forked version of
    typeshed.

    User home directory and environment variables will be expanded.

    Note that this doesn't affect third-party library stubs. To test third-party stubs,
    for example try ``MYPYPATH=stubs/six mypy ...``.

.. confval:: warn_incomplete_stub

    :type: boolean
    :default: False

    Warns about missing type annotations in typeshed.  This is only relevant
    in combination with :confval:`disallow_untyped_defs` or :confval:`disallow_incomplete_defs`.

.. confval:: native_parser

    :type: boolean
    :default: False

    This enables fast Rust-based parser that parses directly to mypy AST.
    It will become the default parser in one of the next mypy releases.


Report generation
*****************

If these options are set, mypy will generate a report in the specified
format into the specified directory.

.. warning::

  Generating reports disables incremental mode and can significantly slow down
  your workflow. It is recommended to enable reporting only for specific runs
  (e.g. in CI).

.. confval:: any_exprs_report

    :type: string

    Causes mypy to generate a text file report documenting how many
    expressions of type ``Any`` are present within your codebase.

.. confval:: cobertura_xml_report

    :type: string

    Causes mypy to generate a Cobertura XML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. confval:: html_report / xslt_html_report

    :type: string

    Causes mypy to generate an HTML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. confval:: linecount_report

    :type: string

    Causes mypy to generate a text file report documenting the functions
    and lines that are typed and untyped within your codebase.

.. confval:: linecoverage_report

    :type: string

    Causes mypy to generate a JSON file that maps each source file's
    absolute filename to a list of line numbers that belong to typed
    functions in that file.

.. confval:: lineprecision_report

    :type: string

    Causes mypy to generate a flat text file report with per-module
    statistics of how many lines are typechecked etc.

.. confval:: txt_report / xslt_txt_report

    :type: string

    Causes mypy to generate a text file type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.

.. confval:: xml_report

    :type: string

    Causes mypy to generate an XML type checking coverage report.

    To generate this report, you must either manually install the `lxml`_
    library or specify mypy installation with the setuptools extra
    ``mypy[reports]``.


Miscellaneous
*************

These options may only be set in the global section (``[mypy]``).

.. confval:: junit_xml

    :type: string

    Causes mypy to generate a JUnit XML test result document with
    type checking results. This can make it easier to integrate mypy
    with continuous integration (CI) tools.

.. confval:: junit_format

    :type: string
    :default: ``global``

    If junit_xml is set, specifies format.
    global (default): single test with all errors;
    per_file: one test entry per file with failures.

.. confval:: scripts_are_modules

    :type: boolean
    :default: False

    Makes script ``x`` become module ``x`` instead of ``__main__``.  This is
    useful when checking multiple scripts in a single run.

.. confval:: warn_unused_configs

    :type: boolean
    :default: False

    Warns about per-module sections in the config file that do not
    match any files processed when invoking mypy.
    (This requires turning off incremental mode using :confval:`incremental = False `.)

.. confval:: verbosity

    :type: integer
    :default: 0

    Controls how much debug output will be generated.  Higher numbers are more verbose.


.. _using-a-pyproject-toml:

Using a pyproject.toml file
***************************

Instead of using a ``mypy.ini`` file, a ``pyproject.toml`` file (as specified by
`PEP 518`_) may be used instead. A few notes on doing so:

* The ``[mypy]`` section should have ``tool.`` prepended to its name:

  * I.e., ``[mypy]`` would become ``[tool.mypy]``

* The module specific sections should be moved into ``[[tool.mypy.overrides]]`` sections:

  * For example, ``[mypy-packagename]`` would become:

.. code-block:: toml

  [[tool.mypy.overrides]]
  module = 'packagename'
  ...

* Multi-module specific sections can be moved into a single ``[[tool.mypy.overrides]]`` section with a
  module property set to an array of modules:

  * For example, ``[mypy-packagename,packagename2]`` would become:

.. code-block:: toml

  [[tool.mypy.overrides]]
  module = [
      'packagename',
      'packagename2'
  ]
  ...

* The following care should be given to values in the ``pyproject.toml`` files as compared to ``ini`` files:

  * Strings must be wrapped in double quotes, or single quotes if the string contains special characters

  * Boolean values should be all lower case

Please see the `TOML Documentation`_ for more details and information on
what is allowed in a ``toml`` file. See `PEP 518`_ for more information on the layout
and structure of the ``pyproject.toml`` file.

Example ``pyproject.toml``
**************************

Here is an example of a ``pyproject.toml`` file. To use this config file, place it at the root
of your repo (or append it to the end of an existing ``pyproject.toml`` file) and run mypy.

.. code-block:: 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

.. _lxml: https://pypi.org/project/lxml/
.. _SQLite: https://www.sqlite.org/
.. _PEP 518: https://www.python.org/dev/peps/pep-0518/
.. _TOML Documentation: https://toml.io/

---

## File: docs/source/duck_type_compatibility.rst

Duck type compatibility
-----------------------

In Python, certain types are compatible even though they aren't subclasses of
each other. For example, ``int`` objects are valid whenever ``float`` objects
are expected. Mypy supports this idiom via *duck type compatibility*. This is
supported for a small set of built-in types:

* ``int`` is duck type compatible with ``float`` and ``complex``.
* ``float`` is duck type compatible with ``complex``.

.. note::
   ``bytearray`` and ``memoryview`` were duck type compatible with ``bytes``
   by default prior to mypy 2.0. This can still be enabled with
   :option:`--no-strict-bytes <mypy --no-strict-bytes>`.

For example, mypy considers an ``int`` object to be valid whenever a
``float`` object is expected.  Thus code like this is nice and clean
and also behaves as expected:

.. code-block:: python

   import math

   def degrees_to_radians(degrees: float) -> float:
       return math.pi * degrees / 180

   n = 90  # Inferred type 'int'
   print(degrees_to_radians(n))  # Okay!

You can also often use :ref:`protocol-types` to achieve a similar effect in
a more principled and extensible fashion. Protocols don't apply to
cases like ``int`` being compatible with ``float``, since ``float`` is not
a protocol class but a regular, concrete class, and many standard library
functions expect concrete instances of ``float`` (or ``int``).

---

## File: docs/source/dynamic_typing.rst

.. _dynamic-typing:

Dynamically typed code
======================

In :ref:`getting-started-dynamic-vs-static`, we discussed how bodies of functions
that don't have any explicit type annotations in their function are "dynamically typed"
and that mypy will not check them. In this section, we'll talk a little bit more
about what that means and how you can enable dynamic typing on a more fine grained basis.

In cases where your code is too magical for mypy to understand, you can make a
variable or parameter dynamically typed by explicitly giving it the type
``Any``. Mypy will let you do basically anything with a value of type ``Any``,
including assigning a value of type ``Any`` to a variable of any type (or vice
versa).

.. code-block:: python

   from typing import Any

   num = 1         # Statically typed (inferred to be int)
   num = 'x'       # error: Incompatible types in assignment (expression has type "str", variable has type "int")

   dyn: Any = 1    # Dynamically typed (type Any)
   dyn = 'x'       # OK

   num = dyn       # No error, mypy will let you assign a value of type Any to any variable
   num += 1        # Oops, mypy still thinks num is an int

You can think of ``Any`` as a way to locally disable type checking.
See :ref:`silencing-type-errors` for other ways you can shut up
the type checker.

Operations on Any values
------------------------

You can do anything using a value with type ``Any``, and the type checker
will not complain:

.. code-block:: python

    def f(x: Any) -> int:
        # All of these are valid!
        x.foobar(1, y=2)
        print(x[3] + 'f')
        if x:
            x.z = x(2)
        open(x).read()
        return x

Values derived from an ``Any`` value also usually have the type ``Any``
implicitly, as mypy can't infer a more precise result type. For
example, if you get the attribute of an ``Any`` value or call a
``Any`` value the result is ``Any``:

.. code-block:: python

    def f(x: Any) -> None:
        y = x.foo()
        reveal_type(y)  # Revealed type is "Any"
        z = y.bar("mypy will let you do anything to y")
        reveal_type(z)  # Revealed type is "Any"

``Any`` types may propagate through your program, making type checking
less effective, unless you are careful.

Function parameters without annotations are also implicitly ``Any``:

.. code-block:: python

    def f(x) -> None:
        reveal_type(x)  # Revealed type is "Any"
        x.can.do["anything", x]("wants", 2)

You can make mypy warn you about untyped function parameters using the
:option:`--disallow-untyped-defs <mypy --disallow-untyped-defs>` flag.

Generic types missing type parameters will have those parameters implicitly
treated as ``Any``:

.. code-block:: python

    def f(x: list) -> None:
        reveal_type(x)        # Revealed type is "builtins.list[Any]"
        reveal_type(x[0])     # Revealed type is "Any"
        x[0].anything_goes()  # OK

You can make mypy warn you about missing generic parameters using the
:option:`--disallow-any-generics <mypy --disallow-any-generics>` flag.

Finally, another major source of ``Any`` types leaking into your program is from
third party libraries that mypy does not know about. This is particularly the case
when using the :option:`--ignore-missing-imports <mypy --ignore-missing-imports>`
flag. See :ref:`fix-missing-imports` for more information about this.

.. _any-vs-object:

Any vs. object
--------------

The type :py:class:`object` is another type that can have an instance of arbitrary
type as a value. Unlike ``Any``, :py:class:`object` is an ordinary static type (it
is similar to ``Object`` in Java), and only operations valid for *all*
types are accepted for :py:class:`object` values. These are all valid:

.. code-block:: python

    def f(o: object) -> None:
        if o:
            print(o)
        print(isinstance(o, int))
        o = 2
        o = 'foo'

These are, however, flagged as errors, since not all objects support these
operations:

.. code-block:: python

    def f(o: object) -> None:
        o.foo()       # Error!
        o + 2         # Error!
        open(o)       # Error!
        n: int = 1
        n = o         # Error!


If you're not sure whether you need to use :py:class:`object` or ``Any``, use
:py:class:`object` -- only switch to using ``Any`` if you get a type checker
complaint.

You can use different :ref:`type narrowing <type-narrowing>`
techniques to narrow :py:class:`object` to a more specific
type (subtype) such as ``int``. Type narrowing is not needed with
dynamically typed values (values with type ``Any``).