diff --git a/docs/source/conf.py b/docs/source/conf.py index d8f86a821d41..3b547c9c745b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -273,4 +273,5 @@ 'attrs': ('http://www.attrs.org/en/stable', None), 'cython': ('http://docs.cython.org/en/latest', None), 'monkeytype': ('https://monkeytype.readthedocs.io/en/latest', None), + 'setuptools': ('https://setuptools.readthedocs.io/en/latest', None), } diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 0f7f3eefd650..e23433af59a1 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -81,23 +81,27 @@ You may wonder what happens at runtime when you index of ``Stack`` that returns instances of the original class on instantiation: ->>> print(Stack) -__main__.Stack ->>> print(Stack[int]) -__main__.Stack[int] ->>> print(Stack[int]().__class__) -__main__.Stack - -Note that built-in types ``list``, ``dict`` and so on do not support -indexing in Python. This is why we have the aliases ``List``, ``Dict`` -and so on in the ``typing`` module. Indexing these aliases gives +.. code-block:: python + + >>> print(Stack) + __main__.Stack + >>> print(Stack[int]) + __main__.Stack[int] + >>> print(Stack[int]().__class__) + __main__.Stack + +Note that built-in types :py:class:`list`, :py:class:`dict` and so on do not support +indexing in Python. This is why we have the aliases :py:class:`~typing.List`, :py:class:`~typing.Dict` +and so on in the :py:mod:`typing` module. Indexing these aliases gives you a class that directly inherits from the target class in Python: ->>> from typing import List ->>> List[int] -typing.List[int] ->>> List[int].__bases__ -(, typing.MutableSequence) +.. code-block:: python + + >>> from typing import List + >>> List[int] + typing.List[int] + >>> List[int].__bases__ + (, typing.MutableSequence) Generic types could be instantiated or subclassed as usual classes, but the above examples illustrate that type variables are erased at @@ -111,7 +115,7 @@ operator. Defining sub-classes of generic classes *************************************** -User-defined generic classes and generic classes defined in ``typing`` +User-defined generic classes and generic classes defined in :py:mod:`typing` can be used as base classes for another classes, both generic and non-generic. For example: @@ -148,13 +152,13 @@ non-generic. For example: .. note:: - You have to add an explicit ``Mapping`` base class + You have to add an explicit :py:class:`~typing.Mapping` base class if you want mypy to consider a user-defined class as a mapping (and - ``Sequence`` for sequences, etc.). This is because mypy doesn't use + :py:class:`~typing.Sequence` for sequences, etc.). This is because mypy doesn't use *structural subtyping* for these ABCs, unlike simpler protocols - like ``Iterable``, which use :ref:`structural subtyping `. + like :py:class:`~typing.Iterable`, which use :ref:`structural subtyping `. -``Generic[...]`` can be omitted from bases if there are +:py:class:`Generic ` can be omitted from bases if there are other base classes that include type variables, such as ``Mapping[KT, VT]`` in the above example. If you include ``Generic[...]`` in bases, then it should list all type variables present in other bases (or more, @@ -276,7 +280,7 @@ In this way, for example, you can typecheck chaining of setter methods: Without using generic ``self``, the last two lines could not be type-checked properly. Other uses are factory methods, such as copy and deserialization. -For class methods, you can also define generic ``cls``, using ``Type[T]``: +For class methods, you can also define generic ``cls``, using :py:class:`Type[T] `: .. code-block:: python @@ -328,12 +332,12 @@ a subtype of ``A``, these are defined as follows: Let us illustrate this by few simple examples: -* ``Union`` is covariant in all variables: ``Union[Cat, int]`` is a subtype +* :py:data:`~typing.Union` is covariant in all variables: ``Union[Cat, int]`` is a subtype of ``Union[Animal, int]``, ``Union[Dog, int]`` is also a subtype of ``Union[Animal, int]``, etc. - Most immutable containers such as ``Sequence`` and ``FrozenSet`` are also + Most immutable containers such as :py:class:`~typing.Sequence` and :py:class:`~typing.FrozenSet` are also covariant. -* ``Callable`` is an example of type that behaves contravariant in types of +* :py:data:`~typing.Callable` is an example of type that behaves contravariant in types of arguments, namely ``Callable[[Employee], int]`` is a subtype of ``Callable[[Manager], int]``. To understand this, consider a function: @@ -345,7 +349,7 @@ Let us illustrate this by few simple examples: This function needs a callable that can calculate a salary for managers, and if we give it a callable that can calculate a salary for an arbitrary employee, it's still safe. -* ``List`` is an invariant generic type. Naively, one would think +* :py:class:`~typing.List` is an invariant generic type. Naively, one would think that it is covariant, but let us consider this code: .. code-block:: python @@ -364,7 +368,7 @@ Let us illustrate this by few simple examples: add_one(my_things) # This may appear safe, but... my_things[0].rotate() # ...this will fail - Another example of invariant type is ``Dict``. Most mutable containers + Another example of invariant type is :py:class:`~typing.Dict`. Most mutable containers are invariant. By default, mypy assumes that all user-defined generics are invariant. @@ -406,10 +410,10 @@ as its value. A typical example is a type variable that can only have values AnyStr = TypeVar('AnyStr', str, bytes) -This is actually such a common type variable that ``AnyStr`` is -defined in ``typing`` and we don't need to define it ourselves. +This is actually such a common type variable that :py:data:`~typing.AnyStr` is +defined in :py:mod:`typing` and we don't need to define it ourselves. -We can use ``AnyStr`` to define a function that can concatenate +We can use :py:data:`~typing.AnyStr` to define a function that can concatenate two strings or bytes objects, but it can't be called with other argument types: @@ -462,9 +466,9 @@ this is correct for ``concat``, since ``concat`` actually returns a >>> print(type(ss)) -You can also use a ``TypeVar`` with a restricted set of possible +You can also use a :py:class:`~typing.TypeVar` with a restricted set of possible values when defining a generic class. For example, mypy uses the type -``typing.Pattern[AnyStr]`` for the return value of ``re.compile``, +:py:class:`Pattern[AnyStr] ` for the return value of :py:func:`re.compile`, since regular expressions can be based on a string or a bytes pattern. .. _type-variable-upper-bound: @@ -475,7 +479,7 @@ Type variables with upper bounds A type variable can also be restricted to having values that are subtypes of a specific type. This type is called the upper bound of the type variable, and is specified with the ``bound=...`` keyword -argument to ``TypeVar``. +argument to :py:class:`~typing.TypeVar`. .. code-block:: python @@ -557,7 +561,7 @@ non-function (e.g. ``my_decorator(1)``) will be rejected. Also note that the ``wrapper()`` function is not type-checked. Wrapper functions are typically small enough that this is not a big -problem. This is also the reason for the ``cast()`` call in the +problem. This is also the reason for the :py:func:`~typing.cast` call in the ``return`` statement in ``my_decorator()``. See :ref:`casts`. Generic protocols @@ -565,7 +569,7 @@ Generic protocols Mypy supports generic protocols (see also :ref:`protocol-types`). Several :ref:`predefined protocols ` are generic, such as -``Iterable[T]``, and you can define additional generic protocols. Generic +:py:class:`Iterable[T] `, and you can define additional generic protocols. Generic protocols mostly follow the normal rules for generic classes. Example: .. code-block:: python diff --git a/docs/source/installed_packages.rst b/docs/source/installed_packages.rst index 26f087b968e9..0014ac53b275 100644 --- a/docs/source/installed_packages.rst +++ b/docs/source/installed_packages.rst @@ -4,11 +4,11 @@ Using installed packages ======================== :pep:`561` specifies how to mark a package as supporting type checking. -Below is a summary of how to create :pep:`561` compatible packages and have +Below is a summary of how to create PEP 561 compatible packages and have mypy use them in type checking. -Using :pep:`561` compatible packages with mypy -********************************************** +Using PEP 561 compatible packages with mypy +******************************************* Generally, you do not need to do anything to use installed packages that support typing for the Python executable used to run mypy. Note that most @@ -36,8 +36,8 @@ to find the package, it must be installed. For a package ``foo``, the name of the stub-only package (``foo-stubs``) is not a legal package name, so mypy will not find it, unless it is installed. -Making :pep:`561` compatible packages -************************************* +Making PEP 561 compatible packages +********************************** :pep:`561` notes three main ways to distribute type information. The first is a package that has only inline type annotations in the code itself. The second is @@ -60,7 +60,7 @@ structure as follows lib.py py.typed -the setup.py might look like +the ``setup.py`` might look like .. code-block:: python @@ -76,7 +76,7 @@ the setup.py might look like .. note:: - If you use setuptools, you must pass the option ``zip_safe=False`` to + If you use :doc:`setuptools `, you must pass the option ``zip_safe=False`` to ``setup()``, or mypy will not be able to find the installed package. Some packages have a mix of stub files and runtime files. These packages also @@ -91,7 +91,7 @@ require a ``py.typed`` file. An example can be seen below lib.pyi py.typed -the setup.py might look like: +the ``setup.py`` might look like: .. code-block:: python @@ -121,7 +121,7 @@ had stubs for ``package_c``, we might do the following: __init__.pyi lib.pyi -the setup.py might look like: +the ``setup.py`` might look like: .. code-block:: python diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 642ba5d048a3..892a50645b95 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -8,7 +8,7 @@ annotations are just hints for mypy and don't interfere when running your progra You run your program with a standard Python interpreter, and the annotations are treated effectively as comments. -Using the Python 3 function annotation syntax (using the :pep`484` notation) or +Using the Python 3 function annotation syntax (using the :pep:`484` notation) or a comment-based annotation syntax for Python 2 code, you will be able to efficiently annotate your code and use mypy to check the code for common errors. Mypy has a powerful and easy-to-use type system with modern features diff --git a/docs/source/literal_types.rst b/docs/source/literal_types.rst index 71e95532c2ea..d85bc24a02ff 100644 --- a/docs/source/literal_types.rst +++ b/docs/source/literal_types.rst @@ -5,7 +5,7 @@ Literal types .. note:: - Literal is an officially supported feature, but is highly experimental + ``Literal`` is an officially supported feature, but is highly experimental and should be considered to be in alpha stage. It is very likely that future releases of mypy will modify the behavior of literal types, either by adding new features or by tuning or removing problematic ones. @@ -111,7 +111,7 @@ are **not** assumed to be literals: reveal_type(b) # Revealed type is 'int' If you find repeating the value of the variable in the type hint to be tedious, -you can instead change the variable to be :ref:`Final `: +you can instead change the variable to be ``Final`` (see :ref:`final_attrs`): .. code-block:: python @@ -124,7 +124,7 @@ you can instead change the variable to be :ref:`Final `: reveal_type(c) # Revealed type is 'int' expects_literal(c) # ...but this type checks! -If you do not provide an explicit type in the Final, the type of ``c`` becomes +If you do not provide an explicit type in the ``Final``, the type of ``c`` becomes context-sensitive: mypy will basically try "substituting" the original assigned value whenever it's used before performing type checking. So, mypy will type-check the above program almost as if it were written like so: @@ -141,7 +141,7 @@ the above program almost as if it were written like so: This is why ``expects_literal(19)`` type-checks despite the fact that ``reveal_type(c)`` reports ``int``. -So while changing a variable to be Final is not quite the same thing as adding +So while changing a variable to be ``Final`` is not quite the same thing as adding an explicit ``Literal[...]`` annotation, it often leads to the same effect in practice. Limitations