.. _getting-started:

Getting started
===============

This chapter introduces some core concepts of mypy, including function
annotations, the :py:mod:`typing` module, stub files, and more.

If you're looking for a quick intro, see the
:ref:`mypy cheatsheet <cheat-sheet-py3>`.

If you're unfamiliar with the concepts of static and dynamic type checking,
be sure to read this chapter carefully, as the rest of the documentation
may not make much sense otherwise.

Installing and running mypy
***************************

Mypy requires Python 3.10 or later to run.  You can install mypy using pip:

.. code-block:: shell

    $ python3 -m pip install mypy

Once mypy is installed, run it by using the ``mypy`` tool:

.. code-block:: shell

    $ mypy program.py

This command makes mypy *type check* your ``program.py`` file and print
out any errors it finds. Mypy will type check your code *statically*: this
means that it will check for errors without ever running your code, just
like a linter.

This also means that you are always free to ignore the errors mypy reports,
if you so wish. You can always use the Python interpreter to run your code,
even if mypy reports errors.

However, if you try directly running mypy on your existing Python code, it
will most likely report little to no errors. This is a feature! It makes it
easy to adopt mypy incrementally.

In order to get useful diagnostics from mypy, you must add *type annotations*
to your code. See the section below for details.

.. _getting-started-dynamic-vs-static:

Dynamic vs static typing
************************

A function without type annotations is considered to be *dynamically typed* by mypy:

.. code-block:: python

   def greeting(name):
       return 'Hello ' + name

By default, mypy will **not** type check dynamically typed functions. This means
that with a few exceptions, mypy will not report any errors with regular unannotated Python.

This is the case even if you misuse the function!

.. code-block:: python

   def greeting(name):
       return 'Hello ' + name

   # These calls will fail when the program runs, but mypy does not report an error
   # because "greeting" does not have type annotations.
   greeting(123)
   greeting(b"Alice")

We can get mypy to detect these kinds of bugs by adding *type annotations* (also
known as *type hints*). For example, you can tell mypy that ``greeting`` both accepts
and returns a string like so:

.. code-block:: python

   # The "name: str" annotation says that the "name" argument should be a string
   # The "-> str" annotation says that "greeting" will return a string
   def greeting(name: str) -> str:
       return 'Hello ' + name

This function is now *statically typed*: mypy will use the provided type hints
to detect incorrect use of the ``greeting`` function and incorrect use of
variables within the ``greeting`` function. For example:

.. code-block:: python

   def greeting(name: str) -> str:
       return 'Hello ' + name

   greeting(3)         # Argument 1 to "greeting" has incompatible type "int"; expected "str"
   greeting(b'Alice')  # Argument 1 to "greeting" has incompatible type "bytes"; expected "str"
   greeting("World!")  # No error

   def bad_greeting(name: str) -> str:
       return 'Hello ' * name  # Unsupported operand types for * ("str" and "str")

Being able to pick whether you want a function to be dynamically or statically
typed can be very helpful. For example, if you are migrating an existing
Python codebase to use static types, it's usually easier to migrate by incrementally
adding type hints to your code rather than adding them all at once. Similarly,
when you are prototyping a new feature, it may be convenient to initially implement
the code using dynamic typing and only add type hints later once the code is more stable.

Once you are finished migrating or prototyping your code, you can make mypy warn you
if you add a dynamic function by mistake by using the :option:`--disallow-untyped-defs <mypy --disallow-untyped-defs>`
flag. You can also get mypy to provide some limited checking of dynamically typed
functions by using the :option:`--check-untyped-defs <mypy --check-untyped-defs>` flag.
See :ref:`command-line` for more information on configuring mypy.

Strict mode and configuration
*****************************

Mypy has a *strict mode* that enables a number of additional checks,
like :option:`--disallow-untyped-defs <mypy --disallow-untyped-defs>`.

If you run mypy with the :option:`--strict <mypy --strict>` flag, you
will basically never get a type related error at runtime without a corresponding
mypy error, unless you explicitly circumvent mypy somehow.

However, this flag will probably be too aggressive if you are trying
to add static types to a large, existing codebase. See :ref:`existing-code`
for suggestions on how to handle that case.

Mypy is very configurable, so you can start with using ``--strict``
and toggle off individual checks. For instance, if you use many third
party libraries that do not have types,
:option:`--ignore-missing-imports <mypy --ignore-missing-imports>`
may be useful. See :ref:`getting-to-strict` for how to build up to ``--strict``.

See :ref:`command-line` and :ref:`config-file` for a complete reference on
configuration options.

More complex types
******************

So far, we've added type hints that use only basic concrete types like
``str`` and ``float``. What if we want to express more complex types,
such as "a list of strings" or "an iterable of ints"?

For example, to indicate that some function can accept a list of
strings, use the ``list[str]`` type (Python 3.9 and later):

.. code-block:: python

   def greet_all(names: list[str]) -> None:
       for name in names:
           print('Hello ' + name)

   names = ["Alice", "Bob", "Charlie"]
   ages = [10, 20, 30]

   greet_all(names)   # Ok!
   greet_all(ages)    # Error due to incompatible types

The :py:class:`list` type is an example of something called a *generic type*: it can
accept one or more *type parameters*. In this case, we *parameterized* :py:class:`list`
by writing ``list[str]``. This lets mypy know that ``greet_all`` accepts specifically
lists containing strings, and not lists containing ints or any other type.

In the above examples, the type signature is perhaps a little too rigid.
After all, there's no reason why this function must accept *specifically* a list --
it would run just fine if you were to pass in a tuple, a set, or any other custom iterable.

You can express this idea using :py:class:`collections.abc.Iterable`:

.. code-block:: python

   from collections.abc import Iterable  # or "from typing import Iterable"

   def greet_all(names: Iterable[str]) -> None:
       for name in names:
           print('Hello ' + name)

This behavior is actually a fundamental aspect of the PEP 484 type system: when
we annotate some variable with a type ``T``, we are actually telling mypy that
variable can be assigned an instance of ``T``, or an instance of a *subtype* of ``T``.
That is, ``list[str]`` is a subtype of ``Iterable[str]``.

This also applies to inheritance, so if you have a class ``Child`` that inherits from
``Parent``, then a value of type ``Child`` can be assigned to a variable of type ``Parent``.
For example, a ``RuntimeError`` instance can be passed to a function that is annotated
as taking an ``Exception``.

As another example, suppose you want to write a function that can accept *either*
ints or strings, but no other types. You can express this using a
union type. For example, ``int`` is a subtype of ``int | str``:

.. code-block:: python

   def normalize_id(user_id: int | str) -> str:
       if isinstance(user_id, int):
           return f'user-{100_000 + user_id}'
       else:
           return user_id

The :py:mod:`typing` module contains many other useful types.

For a quick overview, look through the :ref:`mypy cheatsheet <cheat-sheet-py3>`.

For a detailed overview (including information on how to make your own
generic types or your own type aliases), look through the
:ref:`type system reference <overview-type-system-reference>`.

.. note::

   When adding types, the convention is to import types
   using the form ``from typing import <name>`` (as opposed to doing
   just ``import typing`` or ``import typing as t`` or ``from typing import *``).

   For brevity, we often omit imports from :py:mod:`typing` or :py:mod:`collections.abc`
   in code examples, but mypy will give an error if you use types such as
   :py:class:`~collections.abc.Iterable` without first importing them.

.. note::

   In some examples we use capitalized variants of types, such as
   ``List``, and sometimes we use plain ``list``. They are equivalent,
   but the prior variant is needed if you are using Python 3.8 or earlier.

Local type inference
********************

Once you have added type hints to a function (i.e. made it statically typed),
mypy will automatically type check that function's body. While doing so,
mypy will try and *infer* as many details as possible.

We saw an example of this in the ``normalize_id`` function above -- mypy understands
basic :py:func:`isinstance <isinstance>` checks and so can infer that the ``user_id`` variable was of
type ``int`` in the if-branch and of type ``str`` in the else-branch.

As another example, consider the following function. Mypy can type check this function
without a problem: it will use the available context and deduce that ``output`` must be
of type ``list[float]`` and that ``num`` must be of type ``float``:

.. code-block:: python

   def nums_below(numbers: Iterable[float], limit: float) -> list[float]:
       output = []
       for num in numbers:
           if num < limit:
               output.append(num)
       return output

For more details, see :ref:`type-inference-and-annotations`.

Types from libraries
********************

Mypy can also understand how to work with types from libraries that you use.

For instance, mypy comes out of the box with an intimate knowledge of the
Python standard library. For example, here is a function which uses the
``Path`` object from the :doc:`pathlib standard library module <python:library/pathlib>`:

.. code-block:: python

    from pathlib import Path

    def load_template(template_path: Path, name: str) -> str:
        # Mypy knows that `template_path` has a `read_text` method that returns a str
        template = template_path.read_text()
        # ...so it understands this line type checks
        return template.replace('USERNAME', name)

If a third party library you use :ref:`declares support for type checking <installed-packages>`,
mypy will type check your use of that library based on the type hints
it contains.

However, if the third party library does not have type hints, mypy will
complain about missing type information.

.. code-block:: text

  prog.py:1: error: Library stubs not installed for "yaml"
  prog.py:1: note: Hint: "python3 -m pip install types-PyYAML"
  prog.py:2: error: Library stubs not installed for "requests"
  prog.py:2: note: Hint: "python3 -m pip install types-requests"
  ...

In this case, you can provide mypy a different source of type information,
by installing a *stub* package. A stub package is a package that contains
type hints for another library, but no actual code.

.. code-block:: shell

  $ python3 -m pip install types-PyYAML types-requests

Stubs packages for a distribution are often named ``types-<distribution>``.
Note that a distribution name may be different from the name of the package that
you import. For example, ``types-PyYAML`` contains stubs for the ``yaml``
package.

For more discussion on strategies for handling errors about libraries without
type information, refer to :ref:`fix-missing-imports`.

For more information about stubs, see :ref:`stub-files`.

Next steps
**********

If you are in a hurry and don't want to read lots of documentation
before getting started, here are some pointers to quick learning
resources:

* Read the :ref:`mypy cheatsheet <cheat-sheet-py3>`.

* Read :ref:`existing-code` if you have a significant existing
  codebase without many type annotations.

* Read the `blog post <https://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/>`_
  about the Zulip project's experiences with adopting mypy.

* If you prefer watching talks instead of reading, here are
  some ideas:

  * Carl Meyer:
    `Type Checked Python in the Real World <https://www.youtube.com/watch?v=pMgmKJyWKn8>`_
    (PyCon 2018)

  * Greg Price:
    `Clearer Code at Scale: Static Types at Zulip and Dropbox <https://www.youtube.com/watch?v=0c46YHS3RY8>`_
    (PyCon 2018)

* Look at :ref:`solutions to common issues <common_issues>` with mypy if
  you encounter problems.

* You can ask questions about mypy in the
  `mypy issue tracker <https://github.com/python/mypy/issues>`_ and
  typing `Gitter chat <https://gitter.im/python/typing>`_.

* For general questions about Python typing, try posting at
  `typing discussions <https://github.com/python/typing/discussions>`_.

You can also continue reading this document and skip sections that
aren't relevant for you. You don't need to read sections in order.
