Skip to content

Crossreferences to standard library in mypy docs, part 4 #7685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
72 changes: 38 additions & 34 deletions docs/source/generics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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__
(<class 'list'>, typing.MutableSequence)
.. code-block:: python

>>> from typing import List
>>> List[int]
typing.List[int]
>>> List[int].__bases__
(<class 'list'>, typing.MutableSequence)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gvanrossum keeping your advice in mind in this code example:

.. code-block:: python
>>> print(type(ss))
<class 'str'>

I have added the code-block directives here as well.


Generic types could be instantiated or subclassed as usual classes,
but the above examples illustrate that type variables are erased at
Expand All @@ -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:

Expand Down Expand Up @@ -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 <protocol-types>`.
like :py:class:`~typing.Iterable`, which use :ref:`structural subtyping <protocol-types>`.

``Generic[...]`` can be omitted from bases if there are
:py:class:`Generic <typing.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,
Expand Down Expand Up @@ -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] <typing.Type>`:

.. code-block:: python

Expand Down Expand Up @@ -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:

Expand All @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -462,9 +466,9 @@ this is correct for ``concat``, since ``concat`` actually returns a
>>> print(type(ss))
<class 'str'>

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] <typing.Pattern>` 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:
Expand All @@ -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

Expand Down Expand Up @@ -557,15 +561,15 @@ 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
*****************

Mypy supports generic protocols (see also :ref:`protocol-types`). Several
:ref:`predefined protocols <predefined_protocols>` are generic, such as
``Iterable[T]``, and you can define additional generic protocols. Generic
:py:class:`Iterable[T] <typing.Iterable>`, and you can define additional generic protocols. Generic
protocols mostly follow the normal rules for generic classes. Example:

.. code-block:: python
Expand Down
18 changes: 9 additions & 9 deletions docs/source/installed_packages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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 <setuptools:index>`, you must pass the option ``zip_safe=False`` to
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another external library is mentioned here that can be referenced as well.

``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
Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion docs/source/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another error of mine from a previous PR...

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
Expand Down
8 changes: 4 additions & 4 deletions docs/source/literal_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 <final_attrs>`:
you can instead change the variable to be ``Final`` (see :ref:`final_attrs`):

.. code-block:: python

Expand All @@ -124,7 +124,7 @@ you can instead change the variable to be :ref:`Final <final_attrs>`:
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:
Expand All @@ -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
Expand Down