.. _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.

Can't install mypy using pip
----------------------------

If installation fails, you've probably hit one of these issues:

* Mypy needs Python 3.6 or later to run.
* You may have to run pip like this:
  ``python3 -m pip install mypy``.

.. _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 have imprecise type information,
e.g. the :py:func:`pow` builtin returns ``Any`` (see `typeshed issue 285
<https://github.com/python/typeshed/issues/285>`_ for the reason).

:py:meth:`__init__ <object.__init__>` **method has no annotated
arguments or return type annotation.** :py:meth:`__init__ <object.__init__>`
is considered fully-annotated **if at least one argument is annotated**,
while mypy will infer the return type as ``None``.
The implication is that, for a :py:meth:`__init__ <object.__init__>` method
that has no argument, you'll have to explicitly annotate the return type
as ``None`` to type-check this :py:meth:`__init__ <object.__init__>` method:

.. code-block:: python

    def foo(s: str) -> str:
        return s

    class A():
        def __init__(self, value: str): # Return type inferred as None, considered as typed method
            self.value = value
            foo(1) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"

    class B():
        def __init__(self):  # No argument is annotated, considered as untyped method
            foo(1)  # No error!

    class C():
        def __init__(self) -> None:  # Must specify return type to type-check
            foo(1) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"

**Some imports may be silently ignored**.  Another source of
unexpected ``Any`` values are the :option:`--ignore-missing-imports
<mypy --ignore-missing-imports>` and :option:`--follow-imports=skip
<mypy --follow-imports>` flags.  When you use :option:`--ignore-missing-imports <mypy --ignore-missing-imports>`,
any imported module that cannot be found is silently replaced with
``Any``.  When using :option:`--follow-imports=skip <mypy --follow-imports>` the same is true for
modules for which a ``.py`` file is found but that are not specified
on the command line.  (If a ``.pyi`` stub is found it is always
processed normally, regardless of the value of
:option:`--follow-imports <mypy --follow-imports>`.)  To help debug the former situation (no
module found at all) leave out :option:`--ignore-missing-imports <mypy --ignore-missing-imports>`; to get
clarity about the latter use :option:`--follow-imports=error <mypy --follow-imports>`.  You can
read up about these and other useful flags in :ref:`command-line`.

**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` 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.

.. 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
---------------------

A ``# type: ignore`` comment at the top of a module (before any statements,
including imports or docstrings) has the effect of ignoring the *entire* module.

.. code-block:: python

    # type: ignore

    import foo

    foo.bar()

Unexpected errors about 'None' and/or 'Optional' types
------------------------------------------------------

Starting from mypy 0.600, mypy uses
:ref:`strict optional checking <strict_optional>` by default,
and the ``None`` value is not compatible with non-optional types.
It's easy to switch back to the older behavior where ``None`` was
compatible with arbitrary types (see :ref:`no_strict_optional`).
You can also fall back to this behavior if strict optional
checking would require a large number of ``assert foo is not None``
checks to be inserted, and you want to minimize the number
of code changes required to get a clean mypy run.

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.

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 declare it
with the ``Any`` type.

.. code-block:: python

   def f() -> None:
       n = 1
       ...
       n = 'x'        # Type error: n has type int

.. note::

   This limitation could be lifted in a future mypy
   release.

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!

.. _variance:

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

Most mutable generic collections are invariant, and mypy considers all
user-defined generic classes invariant by default
(see :ref:`variance-of-generics` for motivation). This could 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 (assume here that ``Shape`` is the base class of both
``Circle`` and ``Triangle``):

.. code-block:: python

   shape = Circle()    # Infer shape to be Circle
   ...
   shape = Triangle()  # Type error: Triangle is not a Circle

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

.. code-block:: python

   shape = Circle() # type: Shape   # 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 <isinstance>`,
:py:func:`issubclass <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 typing import Sequence, 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, 8):
       # Python 3.8+ specific definitions and imports
   elif sys.version_info[0] >= 3:
       # Python 3 specific definitions and imports
   else:
       # Python 2 specific 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``, 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 2, pass
in :option:`--python-version 2.7 <mypy --python-version>` from the command line. Note that you do not need
to have Python 2.7 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 only understood by mypy and
   don't exist in Python. If you try to run your program, you'll have to
   remove any ``reveal_type`` and ``reveal_locals`` calls before you can
   run your code. Both are always available and you don't need to import
   them.

.. _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_extensions 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 <property>` in
the protocol definition:

.. code-block:: python

   from typing_extensions 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 work-around 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
    sudo python3 -m pip install --upgrade .

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  # "from typing_extensions" in Python 3.9 and earlier

     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 typing import Sequence, List, 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 mis-typed 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: Optional[int]) -> 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.
