diff --git a/docs/source/builtin_types.rst b/docs/source/builtin_types.rst index 5aa84922307d..6abd5250fc42 100644 --- a/docs/source/builtin_types.rst +++ b/docs/source/builtin_types.rst @@ -1,7 +1,13 @@ Built-in types ============== -These are examples of some of the most common 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 @@ -9,9 +15,66 @@ Type Description ``int`` integer ``float`` floating point number ``bool`` boolean value (subclass of ``int``) -``str`` string (unicode) +``str`` string (unicode in Python 3) ``bytes`` 8-bit string ``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 +............. + +In Python 3.9 and later, 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) +====================== =============================== + +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` in Python 3.9. + +See :ref:`generic-builtins` for more details, including how you can +use these in annotations also in Python 3.7 and 3.8. + +These legacy types defined in :py:mod:`typing` are needed if you need to support +Python 3.8 and earlier: + +====================== =============================== +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 @@ -19,27 +82,13 @@ Type Description ``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) -``Any`` dynamically typed value with an arbitrary type ====================== =============================== -The type ``Any`` and type constructors such as ``List``, ``Dict``, -``Iterable`` and ``Sequence`` are defined in the :py:mod:`typing` module. +``List`` is an alias for the built-in type ``list`` that supports +indexing (and similarly for ``dict``/``Dict`` and +``tuple``/``Tuple``). -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. ``Dict`` and -``List`` are aliases for the built-ins ``dict`` and ``list``, respectively. - -``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. Note that even -though they are similar to abstract base classes defined in -:py:mod:`collections.abc` (formerly ``collections``), they are not identical. In -particular, prior to Python 3.9, the built-in collection type objects do not -support indexing. - -In Python 3.9 and later, built-in collection type objects support indexing. This -means that you can use built-in classes or those from :py:mod:`collections.abc` -instead of importing from :py:mod:`typing`. See :ref:`generic-builtins` for more -details. +Note that even though ``Iterable``, ``Sequence`` and ``Mapping`` look +similar to abstract base classes defined in :py:mod:`collections.abc` +(formerly ``collections``), they are not identical, since the latter +don't support indexing prior to Python 3.9. diff --git a/docs/source/cheat_sheet_py3.rst b/docs/source/cheat_sheet_py3.rst index 98b5eb43bcc2..60892e9144ab 100644 --- a/docs/source/cheat_sheet_py3.rst +++ b/docs/source/cheat_sheet_py3.rst @@ -54,21 +54,29 @@ Built-in types x: str = "test" x: bytes = b"test" - # For collections, the name of the type is capitalized, and the - # name of the type inside the collection is in brackets + # For collections, the type of the collection item is in brackets + # (Python 3.9+) + x: list[int] = [1] + x: set[int] = {6, 7} + + # In Python 3.8 and earlier, the name of the collection type is + # capitalized, and the type is imported from 'typing' x: List[int] = [1] x: Set[int] = {6, 7} - # Same as above, but with type comment syntax + # Same as above, but with type comment syntax (Python 3.5 and earlier) x = [1] # type: List[int] # For mappings, we need the types of both keys and values + x: dict[str, float] = {'field': 2.0} # Python 3.9+ 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) # Python 3.9+ 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) # Python 3.9+ x: Tuple[int, ...] = (1, 2, 3) # Use Optional[] for values that could be None diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 0beef90fb25c..11aa73fbf5d0 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -538,6 +538,7 @@ section of the command line docs. :default: False Disallows inferring variable type for ``None`` from two assignments in different scopes. + This is always implicitly enabled when using the :ref:`mypy daemon `. .. confval:: disable_error_code diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 08e614c73984..398a6f566cfc 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -160,22 +160,19 @@ Arguments with default values can be annotated like so: for key, value in kwargs: print(key, value) -The typing module -***************** +Additional types, and the typing module +*************************************** 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"? -You can find many of these more complex static types inside of the :py:mod:`typing` -module. For example, to indicate that some function can accept a list of -strings, use the :py:class:`~typing.List` type: +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 - from typing import List - - def greet_all(names: List[str]) -> None: + def greet_all(names: list[str]) -> None: for name in names: print('Hello ' + name) @@ -185,20 +182,38 @@ strings, use the :py:class:`~typing.List` type: greet_all(names) # Ok! greet_all(ages) # Error due to incompatible types -The :py:class:`~typing.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:`~typing.List` -by writing ``List[str]``. This lets mypy know that ``greet_all`` accepts specifically +The ``list`` type is an example of something called a *generic type*: it can +accept one or more *type parameters*. In this case, we *parameterized* ``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 this particular case, the type signature is perhaps a little too rigid. +In Python 3.8 and earlier, you can instead import the +:py:class:`~typing.List` type from the :py:mod:`typing` module: + +.. code-block:: python + + from typing import List # Python 3.8 and earlier + + def greet_all(names: List[str]) -> None: + for name in names: + print('Hello ' + name) + + ... + +You can find many of these more complex static types in the :py:mod:`typing` module. + +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 the :py:class:`~typing.Iterable` type instead of :py:class:`~typing.List`: +You can express this idea using the +:py:class:`collections.abc.Iterable` type instead of +:py:class:`~typing.List` (or :py:class:`typing.Iterable` in Python +3.8 and earlier): .. code-block:: python - from typing import Iterable + from collections.abc import Iterable # or "from typing import Iterable" def greet_all(names: Iterable[str]) -> None: for name in names: @@ -239,13 +254,21 @@ and a more detailed overview (including information on how to make your own generic types or your own type aliases) by looking through the :ref:`type system reference `. -One final note: when adding types, the convention is to import types -using the form ``from typing import Iterable`` (as opposed to doing -just ``import typing`` or ``import typing as t`` or ``from typing import *``). +.. note:: + + When adding types, the convention is to import types + using the form ``from typing import Union`` (as opposed to doing + just ``import typing`` or ``import typing as t`` or ``from typing import *``). -For brevity, we often omit these :py:mod:`typing` imports in code examples, but -mypy will give an error if you use types such as :py:class:`~typing.Iterable` -without first importing them. + 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:`~typing.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 not using a recent Python. Local type inference ******************** @@ -267,7 +290,7 @@ 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]: + def nums_below(numbers: Iterable[float], limit: float) -> list[float]: output = [] for num in numbers: if num < limit: @@ -289,10 +312,13 @@ syntax like so: .. code-block:: python + # If you're using Python 3.9+ + my_global_dict: dict[int, float] = {} + # If you're using Python 3.6+ my_global_dict: Dict[int, float] = {} - # If you want compatibility with older versions of Python + # If you want compatibility with even older versions of Python my_global_dict = {} # type: Dict[int, float] .. _stubs-intro: diff --git a/docs/source/index.rst b/docs/source/index.rst index 3295f9ca38cc..e833b72cdfdd 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -37,8 +37,8 @@ Mypy is a static type checker for Python 3 and Python 2.7. class_basics runtime_troubles protocols - python2 dynamic_typing + python2 casts duck_type_compatibility stubs diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index 8b368e5100ad..91a27e5d727f 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -241,27 +241,6 @@ more specific type: since the caller may have to use :py:func:`isinstance` before doing anything interesting with the value. -.. _alternative_union_syntax: - -X | Y syntax for Unions ------------------------ - -:pep:`604` introduced an alternative way for spelling union types. In Python -3.10 and later, you can write ``Union[int, str]`` as ``int | str``. It is -possible to use this syntax in versions of Python where it isn't supported by -the runtime with some limitations, see :ref:`runtime_troubles`. - -.. code-block:: python - - from typing import List - - t1: int | str # equivalent to Union[int, str] - - t2: int | None # equivalent to Optional[int] - - # Usable in type comments - t3 = 42 # type: int | str - .. _strict_optional: Optional types and the None type @@ -428,6 +407,27 @@ case you should add an explicit ``Optional[...]`` annotation (or type comment). ``Optional[...]`` type. It's possible that this will become the default behavior in the future. +.. _alternative_union_syntax: + +X | Y syntax for Unions +----------------------- + +:pep:`604` introduced an alternative way for spelling union types. In Python +3.10 and later, you can write ``Union[int, str]`` as ``int | str``. It is +possible to use this syntax in versions of Python where it isn't supported by +the runtime with some limitations (see :ref:`runtime_troubles`). + +.. code-block:: python + + from typing import List + + t1: int | str # equivalent to Union[int, str] + + t2: int | None # equivalent to Optional[int] + + # Usable in type comments + t3 = 42 # type: int | str + .. _no_strict_optional: Disabling strict optional checking diff --git a/docs/source/running_mypy.rst b/docs/source/running_mypy.rst index 866b57cf91df..3d5b9ff6d17a 100644 --- a/docs/source/running_mypy.rst +++ b/docs/source/running_mypy.rst @@ -397,7 +397,7 @@ How mypy determines fully qualified module names depends on if the options With :option:`--explicit-package-bases `, mypy will locate the nearest parent directory that is a member of the ``MYPYPATH`` environment variable, the :confval:`mypy_path` config or is the current - working directory. mypy will then use the relative path to determine the + working directory. Mypy will then use the relative path to determine the fully qualified module name. For example, say your directory tree consists solely of