From 7e601c078e0694bcf6f66d83d2cf4f01c45ea8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oleg=20H=C3=B6fling?= Date: Fri, 4 Oct 2019 13:50:11 +0200 Subject: [PATCH 1/2] added crossrefs to standard library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oleg Höfling --- docs/source/additional_features.rst | 38 ++-- docs/source/builtin_types.rst | 23 +- docs/source/casts.rst | 8 +- docs/source/class_basics.rst | 62 +++--- docs/source/command_line.rst | 47 ++-- docs/source/common_issues.rst | 53 ++--- docs/source/conf.py | 2 +- docs/source/config_file.rst | 22 +- docs/source/duck_type_compatibility.rst | 6 +- docs/source/dynamic_typing.rst | 12 +- docs/source/error_code_list.rst | 23 +- docs/source/error_code_list2.rst | 15 +- docs/source/extending_mypy.rst | 49 +++-- docs/source/faq.rst | 16 +- docs/source/final_attrs.rst | 52 ++--- docs/source/generics.rst | 79 +++---- docs/source/getting_started.rst | 47 ++-- docs/source/installed_packages.rst | 16 +- docs/source/introduction.rst | 2 +- docs/source/kinds_of_types.rst | 57 ++--- docs/source/literal_types.rst | 38 ++-- docs/source/metaclasses.rst | 15 +- docs/source/more_types.rst | 206 +++++++++--------- docs/source/protocols.rst | 170 +++++++-------- docs/source/python2.rst | 8 +- docs/source/python36.rst | 8 +- docs/source/running_mypy.rst | 32 +-- docs/source/stubgen.rst | 4 +- docs/source/stubs.rst | 6 +- docs/source/supported_python_features.rst | 10 +- .../source/type_inference_and_annotations.rst | 15 +- 31 files changed, 593 insertions(+), 548 deletions(-) diff --git a/docs/source/additional_features.rst b/docs/source/additional_features.rst index 33af4d3bb393..57fe67ea4547 100644 --- a/docs/source/additional_features.rst +++ b/docs/source/additional_features.rst @@ -26,8 +26,8 @@ They can be defined using the :py:func:`@dataclasses.dataclass test = Application("Testing...") # OK bad = Application("Testing...", "with plugin") # Error: List[str] expected -Mypy will detect special methods (such as ``__lt__``) depending on the flags used to -define dataclasses. For example: +Mypy will detect special methods (such as :py:meth:`__lt__ `) +depending on the flags used to define dataclasses. For example: .. code-block:: python @@ -72,10 +72,11 @@ and :pep:`557`. Caveats/Known Issues ==================== -Some functions in the ``dataclasses`` module, such as ``replace()`` and ``asdict()``, +Some functions in the :py:mod:`dataclasses` module, such as +:py:func:`~dataclasses.replace` and :py:func:`~dataclasses.asdict`, have imprecise (too permissive) types. This will be fixed in future releases. -Mypy does not yet recognize aliases of ``dataclasses.dataclass``, and will +Mypy does not yet recognize aliases of :py:func:`dataclasses.dataclass`, and will probably never recognize dynamically computed decorators. The following examples do **not** work: @@ -140,9 +141,9 @@ If you're using ``auto_attribs=True`` you must use variable annotations. three: int = attr.ib(8) Typeshed has a couple of "white lie" annotations to make type checking -easier. ``attr.ib`` and ``attr.Factory`` actually return objects, but the -annotation says these return the types that they expect to be assigned to. -That enables this to work: +easier. :py:func:`attr.ib` and :py:class:`attr.Factory` actually +return objects, but the annotation says these return the types that +they expect to be assigned to. That enables this to work: .. code-block:: python @@ -175,7 +176,7 @@ Caveats/Known Issues * Currently, ``converter`` only supports named functions. If mypy finds something else it will complain about not understanding the argument and the type annotation in - ``__init__`` will be replaced by ``Any``. + :py:meth:`__init__ ` will be replaced by :py:data:`~typing.Any`. * :ref:`Validator decorators ` and `default decorators `_ @@ -249,7 +250,7 @@ Your CI script might work like this: * Create a tarball from the ``.mypy_cache`` directory. * Determine the current git master branch commit id (say, using - ``git rev-parse HEAD``). + :code:`git rev-parse HEAD`). * Upload the tarball to the shared repository with a name derived from the commit id. @@ -348,13 +349,14 @@ Extended Callable types This feature is deprecated. You can use :ref:`callback protocols ` as a replacement. -As an experimental mypy extension, you can specify ``Callable`` types -that support keyword arguments, optional arguments, and more. When -you specify the arguments of a Callable, you can choose to supply just -the type of a nameless positional argument, or an "argument specifier" -representing a more complicated form of argument. This allows one to -more closely emulate the full range of possibilities given by the -``def`` statement in Python. +As an experimental mypy extension, you can specify +:py:data:`~typing.Callable` types that support keyword arguments, +optional arguments, and more. When you specify the arguments of a +``Callable``, you can choose to supply just the type of a nameless +positional argument, or an "argument specifier" representing a +more complicated form of argument. This allows one to more closely +emulate the full range of possibilities given by the ``def`` statement +in Python. As an example, here's a complicated function definition and the corresponding ``Callable``: @@ -434,7 +436,7 @@ purpose: In all cases, the ``type`` argument defaults to ``Any``, and if the ``name`` argument is omitted the argument has no name (the name is required for ``NamedArg`` and ``DefaultNamedArg``). A basic -``Callable`` such as +:py:data:`~typing.Callable` such as .. code-block:: python @@ -446,7 +448,7 @@ is equivalent to the following: MyFunc = Callable[[Arg(int), Arg(str), Arg(int)], float] -A ``Callable`` with unspecified argument types, such as +A :py:data:`~typing.Callable` with unspecified argument types, such as .. code-block:: python diff --git a/docs/source/builtin_types.rst b/docs/source/builtin_types.rst index aabab9b22da8..94d8e27578fc 100644 --- a/docs/source/builtin_types.rst +++ b/docs/source/builtin_types.rst @@ -22,19 +22,22 @@ Type Description ``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 ``typing`` module. +The type :py:data:`~typing.Any` and type constructors such as :py:class:`~typing.List`, +:py:class:`~typing.Dict`, :py:class:`~typing.Iterable` and :py:class:`~typing.Sequence` +are defined in the :py:mod:`typing` module. 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. +``List`` are aliases for the built-ins :py:class:`dict` and :py:class:`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 ``collections.abc`` -(formerly ``collections``), they are not identical, since the built-in -collection type objects do not support indexing. +``Iterable``, ``Sequence``, and :py:class:`~typing.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, since the built-in collection type objects +do not support indexing. diff --git a/docs/source/casts.rst b/docs/source/casts.rst index 741513744a3e..75864f607601 100644 --- a/docs/source/casts.rst +++ b/docs/source/casts.rst @@ -6,8 +6,8 @@ Casts and type assertions Mypy supports type casts that are usually used to coerce a statically typed value to a subtype. Unlike languages such as Java or C#, however, mypy casts are only used as hints for the type checker, and they -don't perform a runtime type check. Use the function ``cast`` to perform a -cast: +don't perform a runtime type check. Use the function :py:func:`~typing.cast` +to perform a cast: .. code-block:: python @@ -34,8 +34,8 @@ quite understand what is going on. assert isinstance(o, int) print(o + 5) # OK: type of 'o' is 'int' here -You don't need a cast for expressions with type ``Any``, or when -assigning to a variable with type ``Any``, as was explained earlier. +You don't need a cast for expressions with type :py:data:`~typing.Any`, +or when assigning to a variable with type ``Any``, as was explained earlier. You can also use ``Any`` as the cast target type -- this lets you perform any operations on the result. For example: diff --git a/docs/source/class_basics.rst b/docs/source/class_basics.rst index a89a7e2637e7..95a49ed149be 100644 --- a/docs/source/class_basics.rst +++ b/docs/source/class_basics.rst @@ -1,9 +1,10 @@ Class basics ============ + This section will help get you started annotating your -classes. Built-in classes such as ``int`` also follow these same -rules. +classes. Built-in classes such as :py:class:`int` also +follow these same rules. Instance and class attributes ***************************** @@ -24,8 +25,8 @@ initialized within the class. Mypy infers the types of attributes: a.y = 3 # Error: 'A' has no attribute 'y' This is a bit like each class having an implicitly defined -``__slots__`` attribute. This is only enforced during type -checking and not when your program is running. +:py:data:`__slots__ ` attribute. This is only +enforced during type checking and not when your program is running. You can declare types of variables in the class body explicitly using a type annotation: @@ -40,7 +41,7 @@ a type annotation: As in Python generally, a variable defined in the class body can be used as a class or an instance variable. (As discussed in the next section, you -can override this with a ``ClassVar`` annotation.) +can override this with a :py:data:`~typing.ClassVar` annotation.) Type comments work as well, if you need to support Python versions earlier than 3.6: @@ -78,15 +79,15 @@ to it explicitly using ``self``: a = self a.x = 1 # Error: 'x' not defined -Annotating `__init__` methods -***************************** +Annotating ``__init__`` methods +******************************* -The ``__init__`` method is somewhat special -- it doesn't return a -value. This is best expressed as ``-> None``. However, since many feel -this is redundant, it is allowed to omit the return type declaration -on ``__init__`` methods **if at least one argument is annotated**. For -example, in the following classes ``__init__`` is considered fully -annotated: +The :py:meth:`__init__ ` method is somewhat special -- +it doesn't return a value. This is best expressed as ``-> None``. +However, since many feel this is redundant, it is allowed to omit +the return type declaration on ``__init__`` methods **if at least +one argument is annotated**. For example, in the following classes +``__init__`` is considered fully annotated: .. code-block:: python @@ -111,8 +112,9 @@ annotation, it is considered an untyped method: Class attribute annotations *************************** -You can use a ``ClassVar[t]`` annotation to explicitly declare that a -particular attribute should not be set on instances: +You can use a :py:data:`ClassVar[t] ` annotation +to explicitly declare that a particular attribute should not be set +on instances: .. code-block:: python @@ -149,9 +151,9 @@ being used as an instance variable, as discussed previously: a.x = 1 # Also OK Note that ``ClassVar`` is not a class, and you can't use it with -``isinstance()`` or ``issubclass()``. It does not change Python -runtime behavior -- it's only for type checkers such as mypy (and -also helpful for human readers). +:py:func:`isinstance` or :py:func:`issubclass`. +It does not change Python runtime behavior -- it's only for +type checkers such as mypy (and also helpful for human readers). You can also omit the square brackets and the variable type in a ``ClassVar`` annotation, but this might not do what you'd expect: @@ -161,14 +163,15 @@ a ``ClassVar`` annotation, but this might not do what you'd expect: class A: y: ClassVar = 0 # Type implicitly Any! -In this case the type of the attribute will be implicitly ``Any``. +In this case the type of the attribute will be implicitly +:py:data:`~typing.Any`. This behavior will change in the future, since it's surprising. .. note:: - A ``ClassVar`` type parameter cannot include type variables: - ``ClassVar[T]`` and ``ClassVar[List[T]]`` - are both invalid if ``T`` is a type variable (see :ref:`generic-classes` - for more about type variables). + A :py:data:`~typing.ClassVar` type parameter cannot include + type variables: ``ClassVar[T]`` and ``ClassVar[List[T]]`` + are both invalid if ``T`` is a type variable (see + :ref:`generic-classes` for more about type variables). Overriding statically typed methods *********************************** @@ -235,8 +238,9 @@ Abstract base classes and multiple inheritance Mypy supports Python abstract base classes (ABCs). Abstract classes have at least one abstract method or property that must be implemented by any *concrete* (non-abstract) subclass. You can define abstract base -classes using the ``abc.ABCMeta`` metaclass and the ``abc.abstractmethod`` -function decorator. Example: +classes using the :py:class:`abc.ABCMeta` metaclass and the +:py:func:`@abc.abstractmethod ` function decorator. +Example: .. code-block:: python @@ -263,12 +267,12 @@ function decorator. Example: .. note:: - In Python 2.7 you have to use ``@abc.abstractproperty`` to define - an abstract property. + In Python 2.7 you have to use :py:func:`@abc.abstractproperty + ` to define an abstract property. Note that mypy performs checking for unimplemented abstract methods -even if you omit the ``ABCMeta`` metaclass. This can be useful if the -metaclass would cause runtime metaclass conflicts. +even if you omit the :py:class:`~abc.ABCMeta` metaclass. This can be +useful if the metaclass would cause runtime metaclass conflicts. Since you can't create instances of ABCs, they are most commonly used in type annotations. For example, this method accepts arbitrary iterables diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index a757c911b847..3289c5cbccdd 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -129,17 +129,17 @@ imports. ``--python-executable EXECUTABLE`` This flag will have mypy collect type information from :pep:`561` compliant packages installed for the Python executable ``EXECUTABLE``. - If not provided, mypy will use :pep:`561` compliant packages installed for + If not provided, mypy will use PEP 561 compliant packages installed for the Python executable running mypy. - See :ref:`installed-packages` for more on making :pep:`561` compliant packages. + See :ref:`installed-packages` for more on making PEP 561 compliant packages. ``--no-site-packages`` This flag will disable searching for :pep:`561` compliant packages. This will also disable searching for a usable Python executable. Use this flag if mypy cannot find a Python executable for the version of - Python being checked, and you don't need to use :pep:`561` typed packages. + Python being checked, and you don't need to use PEP 561 typed packages. Otherwise, use ``--python-executable``. ``--no-silence-site-packages`` @@ -197,9 +197,10 @@ For more information on how to use these flags, see :ref:`version_and_platform_c Disallow dynamic typing *********************** -The ``Any`` type is used represent a value that has a :ref:`dynamic type `. -The ``--disallow-any`` family of flags will disallow various uses of the ``Any`` type in -a module -- this lets us strategically disallow the use of dynamic typing in a controlled way. +The :py:data:`~typing.Any` type is used represent a value that has a +:ref:`dynamic type `. The ``--disallow-any`` family +of flags will disallow various uses of the ``Any`` type in a module -- +this lets us strategically disallow the use of dynamic typing in a controlled way. The following options are available: @@ -213,7 +214,7 @@ The following options are available: This flag disallows all expressions in the module that have type ``Any``. If an expression of type ``Any`` appears anywhere in the module mypy will output an error unless the expression is immediately - used as an argument to ``cast`` or assigned to a variable with an + used as an argument to :py:func:`~typing.cast` or assigned to a variable with an explicit type annotation. In addition, declaring a variable of type ``Any`` @@ -230,9 +231,10 @@ The following options are available: ``--disallow-any-generics`` This flag disallows usage of generic types that do not specify explicit - type parameters. Moreover, built-in collections (such as ``list`` and - ``dict``) become disallowed as you should use their aliases from the typing - module (such as ``List[int]`` and ``Dict[str, str]``). + type parameters. Moreover, built-in collections (such as :py:class:`list` and + :py:class:`dict`) become disallowed as you should use their aliases from the + :py:mod:`typing` module (such as :py:class:`List[int] ` and + :py:class:`Dict[str, str] `). ``--disallow-subclassing-any`` This flag reports an error whenever a class subclasses a value of @@ -285,14 +287,15 @@ definitions or calls. None and Optional handling ************************** -The following flags adjust how mypy handles values of type `None`. +The following flags adjust how mypy handles values of type ``None``. For more details, see :ref:`no_strict_optional`. .. _no-implicit-optional: ``--no-implicit-optional`` This flag causes mypy to stop treating arguments with a ``None`` - default value as having an implicit ``Optional[...]`` type. + default value as having an implicit :py:data:`Optional[...] + ` type. For example, by default mypy will assume that the ``x`` parameter is of type ``Optional[int]`` in the code snippet below since @@ -312,10 +315,11 @@ For more details, see :ref:`no_strict_optional`. print(x) ``--no-strict-optional`` - This flag disables strict checking of ``Optional[...]`` - types and ``None`` values. With this option, mypy doesn't - generally check the use of ``None`` values -- they are valid - everywhere. See :ref:`no_strict_optional` for more about this feature. + This flag disables strict checking of :py:data:`Optional[...] + ` types and ``None`` values. With this option, + mypy doesn't generally check the use of ``None`` values -- + they are valid everywhere. See :ref:`no_strict_optional` + for more about this feature. .. note:: Strict optional checking was enabled by default starting in @@ -362,7 +366,7 @@ potentially problematic or redundant in some way. ``--warn-return-any`` This flag causes mypy to generate a warning when returning a value - with type ``Any`` from a function declared with a non- ``Any`` return type. + with type ``Any`` from a function declared with a non-``Any`` return type. ``--warn-unreachable`` This flag will make mypy report an error whenever it encounters @@ -387,9 +391,10 @@ potentially problematic or redundant in some way. unreachable" warning will be silenced in exactly two cases: 1. When the unreachable statement is a ``raise`` statement, is an - ``assert False`` statement, or calls a function that has the ``NoReturn`` - return type hint. In other words, when the unreachable statement - throws an error or terminates the program in some way. + ``assert False`` statement, or calls a function that has the + :py:data:`~typing.NoReturn` return type hint. In other words, + when the unreachable statement throws an error or terminates + the program in some way. 2. When the unreachable statement was *intentionally* marked as unreachable using :ref:`version_and_platform_checks`. @@ -673,7 +678,7 @@ Miscellaneous This flag will give command line arguments that appear to be scripts (i.e. files whose name does not end in ``.py``) a module name derived from the script name rather than the fixed - name ``__main__``. + name :py:mod:`__main__`. This lets you check more than one script in a single mypy invocation. (The default ``__main__`` is technically more correct, but if you diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index 45f60b042871..c2ac0266cfed 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -50,7 +50,8 @@ flagged as an error. 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: + If you don't know what types to add, you can use :py:data:`~typing.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 @@ -69,7 +70,8 @@ flagged as an error. :ref:`reveal_type() ` might come in handy. Note that sometimes library stubs have imprecise type information, - e.g. the ``pow()`` builtin returns ``Any`` (see `typeshed issue 285 + e.g. the :py:func:`pow` builtin returns ``Any`` + (see `typeshed issue 285 `_ for the reason). - **Some imports may be silently ignored**. Another source of @@ -143,7 +145,7 @@ 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 ``__getattr__``: +such as :py:meth:`__getattr__ `: .. code-block:: python @@ -243,7 +245,7 @@ with the ``Any`` type. 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: +not support :py:meth:`~list.sort`) as a list and sort it in-place: .. code-block:: python @@ -326,9 +328,9 @@ above example: Complex type tests ------------------ -Mypy can usually infer the types correctly when using ``isinstance()`` -type tests, but for other kinds of checks you may need to add an -explicit type cast: +Mypy can usually infer the types correctly when using :py:func:`isinstance +` type tests, but for other kinds of checks you may need to add +an explicit type cast: .. code-block:: python @@ -342,17 +344,17 @@ explicit type cast: .. note:: - Note that the ``object`` type used in the above example is similar + 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 ``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``. -Mypy can't infer the type of ``o`` after the ``type()`` check -because it only knows about ``isinstance()`` (and the latter is better -style anyway). We can write the above code without a cast by using -``isinstance()``: +Mypy can't infer the type of ``o`` after the :py:class:`type() ` +check because it only knows about ``isinstance()`` (and the latter +is better style anyway). We can write the above code without a cast +by using ``isinstance()``: .. code-block:: python @@ -379,8 +381,8 @@ 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 ``sys.version_info`` and -``sys.platform`` checks within ``if/elif/else`` statements. For example: +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 @@ -417,15 +419,16 @@ Example: # The rest of this file doesn't apply to Windows. Some other expressions exhibit similar behavior; in particular, -``typing.TYPE_CHECKING``, variables named ``MYPY``, and any variable +:py:data:`typing.TYPE_CHECKING`, variables named ``MYPY``, and any variable whose name is passed to ``--always-true`` or ``--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 ``sys.version_info`` or ``sys.platform`` - check to a variable. This may change in future versions of mypy. + 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 ``sys.version_info`` and @@ -438,7 +441,7 @@ to have Python 2.7 installed to perform this check. To target a different operating system, use the ``--platform PLATFORM`` flag. For example, to verify your code typechecks if it were run in Windows, pass -in ``--platform win32``. See the documentation for :py:data:`sys.platform` +in ``--platform win32``. See the documentation for ``sys.platform`` for examples of valid platform parameters. .. _reveal-type: @@ -514,7 +517,7 @@ File ``bar.py``: .. note:: - The ``TYPE_CHECKING`` constant defined by the ``typing`` module + The :py:data:`~typing.TYPE_CHECKING` constant defined by the :py:mod:`typing` module is ``False`` at runtime but ``True`` while type checking. Python 3.5.1 doesn't have ``typing.TYPE_CHECKING``. An alternative is @@ -538,7 +541,7 @@ Using classes that are generic in stubs but not at runtime ---------------------------------------------------------- Some classes are declared as generic in stubs, but not at runtime. Examples -in the standard library include ``os.PathLike`` and ``queue.Queue``. +in the standard library include :py:class:`os.PathLike` and :py:class:`queue.Queue`. Subscripting such a class will result in a runtime error: .. code-block:: python @@ -551,7 +554,7 @@ Subscripting such a class will result in a runtime error: results: Queue[int] = Queue() # TypeError: 'type' object is not subscriptable To avoid these errors while still having precise types you can either use -string literal types or ``typing.TYPE_CHECKING``: +string literal types or :py:data:`~typing.TYPE_CHECKING`: .. code-block:: python @@ -600,7 +603,7 @@ Consider this example: .. code-block:: python - from typing_extensions import Protocol + from typing import Protocol class P(Protocol): x: float @@ -615,12 +618,12 @@ Consider this example: 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 ``@property`` in -the protocol definition: +of a protocol. If not, then one can use a :py:class:`@property ` +in the protocol definition: .. code-block:: python - from typing_extensions import Protocol + from typing import Protocol class P(Protocol): @property diff --git a/docs/source/conf.py b/docs/source/conf.py index d8f86a821d41..4f1815b77a41 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -268,7 +268,7 @@ rst_prolog = '.. |...| unicode:: U+2026 .. ellipsis\n' intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), + 'python': ('https://docs.python.org/3.8', None), 'six': ('https://six.readthedocs.io', None), 'attrs': ('http://www.attrs.org/en/stable', None), 'cython': ('http://docs.cython.org/en/latest', None), diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index cd8412408b4b..0eb832f9eb79 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -113,7 +113,7 @@ options will: (This is equivalent to using the ``--python-version 2.7`` or ``--2`` flag). 2. Report an error whenever a function returns a value that is inferred - to have type ``Any``. + to have type :py:data:`~typing.Any`. 3. Report any config options that are unused by mypy. (This will help us catch typos when making changes to our config file). @@ -189,7 +189,7 @@ See below for a list of import discovery options that may be used Used in conjunction with ``follow_imports=skip``, this can be used to suppress the import of a module from ``typeshed``, replacing it - with `Any`. + with ``Any``. Used in conjunction with ``follow_imports=error``, this can be used to make any use of a particular ``typeshed`` module an error. @@ -254,8 +254,8 @@ For more information, see the :ref:`None and optional handling ` definition must be a class type. It can't be a union type, ``Any``, or various other special types. You can also get this error if the target has been imported from a diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index 4cfd2f2613ab..203b1b987225 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -19,9 +19,10 @@ Check that type arguments exist [type-arg] ------------------------------------------ If you use ``--disallow-any-generics``, mypy requires that each generic -type has values for each type argument. For example, the types ``List`` or -``dict`` would be rejected. You should instead use types like ``List[int]`` or -``Dict[str, int]``. Any omitted generic type arguments get implicit ``Any`` +type has values for each type argument. For example, the types +:py:class:`~typing.List` or :py:class:`~typing.Dict` would be rejected. +You should instead use types like ``List[int]`` or ``Dict[str, int]``. +Any omitted generic type arguments get implicit :py:data:`~typing.Any` values. The type ``List`` is equivalent to ``List[Any]``, and so on. Example: @@ -135,8 +136,8 @@ Example: ... -Check that function does not return Any value [no-any-return] -------------------------------------------------------------- +Check that function does not return ``Any`` value [no-any-return] +----------------------------------------------------------------- If you use ``--warn-return-any``, mypy generates an error if you return a value with an ``Any`` type in a function that is annotated to return a @@ -155,8 +156,8 @@ Example: # Error: Returning Any from function declared to return "str" [no-any-return] return fields(x)[0] -Check that types have no Any components due to missing imports [no-any-unimported] ----------------------------------------------------------------------------------- +Check that types have no ``Any`` components due to missing imports [no-any-unimported] +-------------------------------------------------------------------------------------- If you use ``--disallow-any-unimported``, mypy generates an error if a component of a type becomes ``Any`` because mypy couldn't resolve an import. These "stealth" diff --git a/docs/source/extending_mypy.rst b/docs/source/extending_mypy.rst index 40e7ade5375e..8d7d0d3ee2da 100644 --- a/docs/source/extending_mypy.rst +++ b/docs/source/extending_mypy.rst @@ -9,14 +9,15 @@ Integrating mypy into another Python application ************************************************ It is possible to integrate mypy into another Python 3 application by -importing ``mypy.api`` and calling the ``run`` function with a parameter of type ``List[str]``, containing -what normally would have been the command line arguments to mypy. +importing ``mypy.api`` and calling the ``run`` function with a parameter +of type ``List[str]``, containing what normally would have been +the command line arguments to mypy. Function ``run`` returns a ``Tuple[str, str, int]``, namely ``(, , )``, in which ```` -is what mypy normally writes to ``sys.stdout``, ```` is what mypy -normally writes to ``sys.stderr`` and ``exit_status`` is the exit status mypy normally -returns to the operating system. +is what mypy normally writes to :py:data:`sys.stdout`, ```` is what mypy +normally writes to :py:data:`sys.stderr` and ``exit_status`` is the exit status mypy +normally returns to the operating system. A trivial example of using the api is the following @@ -98,7 +99,7 @@ High-level overview ******************* Every entry point function should accept a single string argument -that is a full mypy version and return a subclass of ``mypy.plugins.Plugin``: +that is a full mypy version and return a subclass of ``mypy.plugin.Plugin``: .. code-block:: python @@ -138,7 +139,7 @@ of plugin hook results. Current list of plugin hooks **************************** -**get_type_analyze_hook()** customizes behaviour of the type analyzer. +``get_type_analyze_hook()`` customizes behaviour of the type analyzer. For example, :pep:`484` doesn't support defining variadic generic types: .. code-block:: python @@ -151,10 +152,10 @@ For example, :pep:`484` doesn't support defining variadic generic types: When analyzing this code, mypy will call ``get_type_analyze_hook("lib.Vector")``, so the plugin can return some valid type for each variable. -**get_function_hook()** is used to adjust the return type of a function call. +``get_function_hook()`` is used to adjust the return type of a function call. This is a good choice if the return type of some function depends on *values* of some arguments that can't be expressed using literal types (for example -a function may return an ``int`` for positive arguments and a ``float`` for +a function may return an :py:class:`int` for positive arguments and a :py:class:`float` for negative arguments). This hook will be also called for instantiation of classes. For example: @@ -170,12 +171,12 @@ For example: ... yield timer() -**get_method_hook()** is the same as ``get_function_hook()`` but for methods +``get_method_hook()`` is the same as ``get_function_hook()`` but for methods instead of module level functions. -**get_method_signature_hook()** is used to adjust the signature of a method. -This includes special Python methods except ``__init__()`` and ``__new__()``. -For example in this code: +``get_method_signature_hook()`` is used to adjust the signature of a method. +This includes special Python methods except :py:meth:`~object.__init__` and +:py:meth:`~object.__new__`. For example in this code: .. code-block:: python @@ -185,15 +186,15 @@ For example in this code: x[0] = 42 mypy will call ``get_method_signature_hook("ctypes.Array.__setitem__")`` -so that the plugin can mimic the ``ctypes`` auto-convert behavior. +so that the plugin can mimic the :py:mod:`ctypes` auto-convert behavior. -**get_attribute_hook** overrides instance member field lookups and property +``get_attribute_hook()`` overrides instance member field lookups and property access (not assignments, and not method calls). This hook is only called for -fields which already exist on the class. *Exception:* if ``__getattr__`` or -``__getattribute__`` is a method on the class, the hook is called for all -fields which do not refer to methods. +fields which already exist on the class. *Exception:* if :py:meth:`__getattr__ +` or :py:meth:`__getattribute__ ` +is a method on the class, the hook is called for all fields which do not refer to methods. -**get_class_decorator_hook()** can be used to update class definition for +``get_class_decorator_hook()`` can be used to update class definition for given class decorators. For example, you can add some attributes to the class to match runtime behaviour: @@ -208,11 +209,11 @@ to match runtime behaviour: var = UserDefined var.customized # mypy can understand this using a plugin -**get_metaclass_hook()** is similar to above, but for metaclasses. +``get_metaclass_hook()`` is similar to above, but for metaclasses. -**get_base_class_hook()** is similar to above, but for base classes. +``get_base_class_hook()`` is similar to above, but for base classes. -**get_dynamic_class_hook()** can be used to allow dynamic class definitions +``get_dynamic_class_hook()`` can be used to allow dynamic class definitions in mypy. This plugin hook is called for every assignment to a simple name where right hand side is a function call: @@ -228,10 +229,10 @@ place it into a relevant symbol table. (Instances of this class represent classes in mypy and hold essential information such as qualified name, method resolution order, etc.) -**get_customize_class_mro_hook()** can be used to modify class MRO (for example +``get_customize_class_mro_hook()`` can be used to modify class MRO (for example insert some entries there) before the class body is analyzed. -**get_additional_deps()** can be used to add new dependencies for a +``get_additional_deps()`` can be used to add new dependencies for a module. It is called before semantic analysis. For example, this can be used if a library has dependencies that are dynamically loaded based on configuration information. diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 94ffc7f4ec75..eca7aa0d6af4 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -110,17 +110,16 @@ Structural subtyping can be thought of as "static duck typing". Some argue that structural subtyping is better suited for languages with duck typing such as Python. Mypy however primarily uses nominal subtyping, leaving structural subtyping mostly opt-in (except for built-in protocols -such as ``Iterable`` that always support structural subtyping). Here are some -reasons why: +such as :py:class:`~typing.Iterable` that always support structural subtyping). +Here are some reasons why: 1. It is easy to generate short and informative error messages when using a nominal type system. This is especially important when using type inference. -2. Python provides built-in support for nominal ``isinstance()`` tests and - they are widely used in programs. Only limited support for structural - ``isinstance()`` is available, and it's less type safe than - nominal type tests. +2. Python provides built-in support for nominal :py:func:`isinstance ` + tests and they are widely used in programs. Only limited support for structural + ``isinstance`` is available, and it's less type safe than nominal type tests. 3. Many programmers are already familiar with static, nominal subtyping and it has been successfully used in languages such as Java, C++ and @@ -164,7 +163,7 @@ monkey patching of methods. How is mypy different from Cython? ********************************** -`Cython :doc:` is a variant of Python that supports +:doc:`Cython ` is a variant of Python that supports compilation to CPython C modules. It can give major speedups to certain classes of programs compared to CPython, and it provides static typing (though this is different from mypy). Mypy differs in @@ -174,7 +173,8 @@ the following aspects, among others: about static type checking, and increasing performance is not a direct goal. -- The mypy syntax is arguably simpler and more "Pythonic" (no cdef/cpdef, etc.) for statically typed code. +- The mypy syntax is arguably simpler and more "Pythonic" (no cdef/cpdef, etc.) + for statically typed code. - The mypy syntax is compatible with Python. Mypy programs are normal Python programs that can be run using any Python diff --git a/docs/source/final_attrs.rst b/docs/source/final_attrs.rst index 009d792dc2ab..b8c01e40e1f4 100644 --- a/docs/source/final_attrs.rst +++ b/docs/source/final_attrs.rst @@ -15,14 +15,15 @@ They is no runtime enforcement by the Python runtime. .. note:: - These are experimental features. They might change in later - versions of mypy. The *final* qualifiers are available through the - ``typing_extensions`` package on PyPI. + The :py:data:`~typing.Final` qualifiers are available through the + ``typing_extensions`` package on PyPI for Python 2.7 and 3.4-3.7. + Starting with Python 3.8, they are included in the :py:mod:`typing` + module. Final names ----------- -You can use the ``typing_extensions.Final`` qualifier to indicate that +You can use the :py:data:`~typing.Final` qualifier to indicate that a name or attribute should not be reassigned, redefined, or overridden. This is often useful for module and class level constants as a way to prevent unintended modification. Mypy will prevent @@ -30,7 +31,7 @@ further assignments to final names in type-checked code: .. code-block:: python - from typing_extensions import Final + from typing import Final RATE: Final = 3000 @@ -45,7 +46,7 @@ from being overridden in a subclass: .. code-block:: python - from typing_extensions import Final + from typing import Final class Window: BORDER_WIDTH: Final = 2.5 @@ -54,14 +55,14 @@ from being overridden in a subclass: class ListView(Window): BORDER_WIDTH = 3 # Error: can't override a final attribute -You can use ``@property`` to make an attribute read-only, but unlike ``Final``, +You can use :py:class:`@property ` to make an attribute read-only, but unlike ``Final``, it doesn't work with module attributes, and it doesn't prevent overriding in subclasses. Syntax variants *************** -You can use ``Final`` in one of these forms: +You can use :py:data:`~typing.Final` in one of these forms: * You can provide an explicit type using the syntax ``Final[]``. Example: @@ -75,7 +76,7 @@ You can use ``Final`` in one of these forms: ID: Final = 1 - Here mypy will infer type ``int`` for ``ID``. Note that unlike for + Here mypy will infer type :py:class:`int` for ``ID``. Note that unlike for generic classes this is *not* the same as ``Final[Any]``. * In class bodies and stub files you can omit the right hand side and just write @@ -83,11 +84,11 @@ You can use ``Final`` in one of these forms: * Finally, you can write ``self.id: Final = 1`` (also optionally with a type in square brackets). This is allowed *only* in - ``__init__`` methods, so that the final instance attribute is - assigned only once when an instance is created. + :py:meth:`__init__ ` methods, so that the final instance + attribute is assigned only once when an instance is created. -Details of using Final -********************** +Details of using :py:data:`~typing.Final` +***************************************** These are the two main rules for defining a final name: @@ -98,8 +99,8 @@ These are the two main rules for defining a final name: * There must be *exactly one* assignment to a final name. A final attribute declared in a class body without an initializer must -be initialized in the ``__init__`` method (you can skip the -initializer in stub files): +be initialized in the :py:meth:`__init__ ` method +(you can skip the initializer in stub files): .. code-block:: python @@ -110,9 +111,10 @@ initializer in stub files): def __init__(self) -> None: self.x = 1 # Good -``Final`` can only be used as the outermost type in assignments or variable -annotations. Using it in any other position is an error. In particular, -``Final`` can't be used in annotations for function arguments: +:py:data:`~typing.Final` can only be used as the outermost type in +assignments or variable annotations. Using it in any other position +is an error. In particular, ``Final`` can't be used in annotations +for function arguments: .. code-block:: python @@ -121,7 +123,7 @@ annotations. Using it in any other position is an error. In particular, def fun(x: Final[List[int]]) -> None: # Error! ... -``Final`` and ``ClassVar`` should not be used together. Mypy will infer +``Final`` and :py:data:`~typing.ClassVar` should not be used together. Mypy will infer the scope of a final declaration automatically depending on whether it was initialized in the class body or in ``__init__``. @@ -155,12 +157,12 @@ Final methods ------------- Like with attributes, sometimes it is useful to protect a method from -overriding. You can use the ``typing_extensions.final`` -decorator for this purpose: +overriding. You can use the :py:func:`@final ` decorator +for this purpose: .. code-block:: python - from typing_extensions import final + from typing import final class Base: @final @@ -193,12 +195,12 @@ to make it final (or on the first overload in stubs): Final classes ------------- -You can apply the ``typing_extensions.final`` decorator to a class to indicate -to mypy that it should not be subclassed: +You can apply the :py:func:`@final ` decorator to a class +to indicate to mypy that it should not be subclassed: .. code-block:: python - from typing_extensions import final + from typing import final @final class Leaf: diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 0dfbe1c9f505..847ff5e02bd9 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -13,8 +13,9 @@ Defining generic classes The built-in collection classes are generic classes. Generic types have one or more type parameters, which can be arbitrary types. For -example, ``Dict[int, str]`` has the type parameters ``int`` and -``str``, and ``List[int]`` has a type parameter ``int``. +example, :py:class:`Dict[int, str] ` has the type parameters +:py:class:`int` and :py:class:`str`, and :py:class:`List[int] ` +has a type parameter ``int``. Programs can also define new generic classes. Here is a very simple generic class that represents a stack: @@ -88,9 +89,10 @@ __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 +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 @@ -111,7 +113,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 +150,14 @@ 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 - *structural subtyping* for these ABCs, unlike simpler protocols - like ``Iterable``, which use :ref:`structural subtyping `. + :py:class:`~typing.Sequence` for sequences, etc.). This is because + mypy doesn't use *structural subtyping* for these ABCs, unlike simpler + protocols 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 +279,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 @@ -306,7 +309,7 @@ In the latter case, you must implement this method in all future subclasses. Note also that mypy cannot always verify that the implementation of a copy or a deserialization method returns the actual type of self. Therefore you may need to silence mypy inside these methods (but not at the call site), -possibly by making use of the ``Any`` type. +possibly by making use of the :py:data:`~typing.Any` type. .. _variance-of-generics: @@ -328,13 +331,13 @@ 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 - of ``Union[Animal, int]``, +* :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 - covariant. -* ``Callable`` is an example of type that behaves contravariant in types of - arguments, namely ``Callable[[Employee], int]`` is a subtype of + Most immutable containers such as :py:class:`~typing.Sequence` and + :py:class:`~typing.FrozenSet` are also covariant. +* :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: .. code-block:: python @@ -345,7 +348,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,8 +367,8 @@ 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 - are invariant. + 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. To declare a given generic class as covariant or contravariant use @@ -398,7 +401,7 @@ Type variables with value restriction By default, a type variable can be replaced with any type. However, sometimes it's useful to have a type variable that can only have some specific types as its value. A typical example is a type variable that can only have values -``str`` and ``bytes``: +:py:class:`str` and :py:class:`bytes`: .. code-block:: python @@ -406,8 +409,8 @@ 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 two strings or bytes objects, but it can't be called with other @@ -462,9 +465,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 +478,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 +560,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,13 +568,13 @@ 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 -protocols mostly follow the normal rules for generic classes. Example: +: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 - from typing import TypeVar - from typing_extensions import Protocol + from typing import TypeVar, Protocol T = TypeVar('T') @@ -604,8 +607,7 @@ variable is invariant: .. code-block:: python - from typing import TypeVar - from typing_extensions import Protocol + from typing import TypeVar, Protocol T = TypeVar('T') @@ -616,8 +618,7 @@ This example correctly uses a covariant type variable: .. code-block:: python - from typing import TypeVar - from typing_extensions import Protocol + from typing import TypeVar, Protocol T_co = TypeVar('T_co', covariant=True) @@ -662,8 +663,8 @@ Type aliases can be generic. In this case they can be used in two ways: Subscripted aliases are equivalent to original types with substituted type variables, so the number of type arguments must match the number of free type variables in the generic type alias. Unsubscripted aliases are treated as original types with free -variables replaced with ``Any``. Examples (following :pep:`PEP 484: Type aliases -<484#type-aliases>`): +variables replaced with ``Any``. Examples (following :pep:`PEP 484: +Type aliases <484#type-aliases>`): .. code-block:: python diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 57cfcf9887cb..dc892ea98e2f 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -4,7 +4,7 @@ Getting started =============== This chapter introduces some core concepts of mypy, including function -annotations, the ``typing`` module, library stubs, and more. +annotations, the :py:mod:`typing` module, library stubs, and more. Be sure to read this chapter carefully, as the rest of the documentation may not make much sense otherwise. @@ -160,16 +160,16 @@ Arguments with default values can be annotated like so: for key, value in kwargs: print(key, value) -The typing module -***************** +The :py:mod:`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"? +:py:class:`str` and :py:class:`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 ``typing`` +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 ``List`` type from the ``typing`` module: +strings, use the :py:class:`~typing.List` type from the :py:mod:`typing` module: .. code-block:: python @@ -181,12 +181,12 @@ strings, use the ``List`` type from the ``typing`` module: names = ["Alice", "Bob", "Charlie"] ages = [10, 20, 30] - + greet_all(names) # Ok! greet_all(ages) # Error due to incompatible types -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`` +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 lists containing strings, and not lists containing ints or any other type. @@ -194,7 +194,8 @@ In this particular case, 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 ``Iterable`` type instead of ``List``: +You can express this idea using the :py:class:`~typing.Iterable` type instead of +:py:class:`~typing.List`: .. code-block:: python @@ -205,7 +206,7 @@ You can express this idea using the ``Iterable`` type instead of ``List``: print('Hello ' + name) 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 the ``Union`` type: +ints or strings, but no other types. You can express this using the :py:data:`~typing.Union` type: .. code-block:: python @@ -217,8 +218,8 @@ ints or strings, but no other types. You can express this using the ``Union`` ty else: return user_id -Similarly, suppose that you want the function to accept only strings or None. You can -again use ``Union`` and use ``Union[str, None]`` -- or alternatively, use the type +Similarly, suppose that you want the function to accept only strings or ``None``. You can +again use :py:data:`~typing.Union` and use ``Union[str, None]`` -- or alternatively, use the type ``Optional[str]``. These two types are identical and interchangeable: ``Optional[str]`` is just a shorthand or *alias* for ``Union[str, None]``. It exists mostly as a convenience to help function signatures look a little cleaner: @@ -233,18 +234,18 @@ to help function signatures look a little cleaner: name = 'stranger' return 'Hello, ' + name -The ``typing`` module contains many other useful types. You can find a -quick overview by looking through the :ref:`mypy cheatsheets ` +The :py:mod:`typing` module contains many other useful types. You can find a +quick overview by looking through the :ref:`mypy cheatsheets ` 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 +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 *``). -For brevity, we often omit these ``typing`` imports in code examples, but -mypy will give an error if you use types such as ``Iterable`` +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. Local type inference @@ -252,11 +253,11 @@ 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. +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 ``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. Similarly, mypy +basic :py:func:`isinstance` checks and so can infer that the ``user_id`` variable was of +type :py:class:`int` in the if-branch and of type ``str`` in the else-branch. Similarly, mypy was able to understand that ``name`` could not possibly be ``None`` in the ``greeting`` function above, based both on the ``name is None`` check and the variable assignment in that if statement. @@ -315,7 +316,7 @@ For example, consider this code: x = chr(4) Without a library stub, mypy would have no way of inferring the type of ``x`` -and checking that the argument to ``chr`` has a valid type. +and checking that the argument to :py:func:`chr` has a valid type. Mypy complains if it can't find a stub (or a real module) for a library module that you import. Some modules ship with stubs that mypy diff --git a/docs/source/installed_packages.rst b/docs/source/installed_packages.rst index 44debdd9b358..6c622ae6c00f 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 @@ -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/kinds_of_types.rst b/docs/source/kinds_of_types.rst index 76602d4c7ebc..c3d66243db4a 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -10,9 +10,10 @@ Class types Every class is also a valid type. Any instance of a subclass is also compatible with all superclasses -- it follows that every value is compatible -with the ``object`` type (and incidentally also the ``Any`` type, discussed -below). Mypy analyzes the bodies of classes to determine which methods and -attributes are available in instances. This example uses subclassing: +with the :py:class:`object` type (and incidentally also the +:py:data:`~typing.Any` type, discussed below). Mypy analyzes the bodies +of classes to determine which methods and attributes are available +in instances. This example uses subclassing: .. code-block:: python @@ -35,8 +36,8 @@ attributes are available in instances. This example uses subclassing: The Any type ************ -A value with the ``Any`` type is dynamically typed. Mypy doesn't know -anything about the possible runtime types of such value. Any +A value with the :py:data:`~typing.Any` type is dynamically typed. Mypy +doesn't know anything about the possible runtime types of such value. Any operations are permitted on the value, and the operations are only checked at runtime. You can use ``Any`` as an "escape hatch" when you can't use a more precise type for some reason. @@ -53,9 +54,9 @@ assign a value of type ``Any`` to a variable with a more precise type: Declared (and inferred) types are ignored (or *erased*) at runtime. They are basically treated as comments, and thus the above code does not -generate a runtime error, even though ``s`` gets an ``int`` value when +generate a runtime error, even though ``s`` gets an :py:class:`int` value when the program is run, while the declared type of ``s`` is actually -``str``! You need to be careful with ``Any`` types, since they let you +:py:class:`str`! You need to be careful with ``Any`` types, since they let you lie to mypy, and this could easily hide bugs. If you do not define a function return value or argument types, these @@ -108,7 +109,8 @@ The ``Any`` type is discussed in more detail in section :ref:`dynamic-typing`. Tuple types *********** -The type ``Tuple[T1, ..., Tn]`` represents a tuple with the item types ``T1``, ..., ``Tn``: +The type ``Tuple[T1, ..., Tn]`` represents a :py:data:`~typing.Tuple` +with the item types ``T1``, ..., ``Tn``: .. code-block:: python @@ -135,7 +137,7 @@ purpose. Example: .. note:: Usually it's a better idea to use ``Sequence[T]`` instead of ``Tuple[T, ...]``, as - ``Sequence`` is also compatible with lists and other non-tuple sequences. + :py:class:`~typing.Sequence` is also compatible with lists and other non-tuple sequences. .. note:: @@ -212,8 +214,8 @@ Use the ``Union[T1, ..., Tn]`` type constructor to construct a union type. For example, if an argument has type ``Union[int, str]``, both integers and strings are valid argument values. -You can use an ``isinstance()`` check to narrow down a union type to a -more specific type: +You can use an :py:func:`isinstance ` check to narrow down +a union type to a more specific type: .. code-block:: python @@ -235,10 +237,10 @@ more specific type: .. note:: Operations are valid for union types only if they are valid for *every* - union item. This is why it's often necessary to use an ``isinstance()`` - check to first narrow down a union type to a non-union type. This also - means that it's recommended to avoid union types as function return types, - since the caller may have to use ``isinstance()`` before doing anything + union item. This is why it's often necessary to use an :py:func:`isinstance + ` check to first narrow down a union type to a non-union type. + This also means that it's recommended to avoid union types as function return + types, since the caller may have to use ``isinstance`` before doing anything interesting with the value. .. _strict_optional: @@ -246,7 +248,7 @@ more specific type: Optional types and the None type ******************************** -You can use the ``Optional`` type modifier to define a type variant +You can use the :py:data:`~typing.Optional` type modifier to define a type variant that allows ``None``, such as ``Optional[int]`` (``Optional[X]`` is the preferred shorthand for ``Union[X, None]``): @@ -415,8 +417,8 @@ Disabling strict optional checking Mypy also has an option to treat ``None`` as a valid value for every type (in case you know Java, it's useful to think of it as similar to the Java ``null``). In this mode ``None`` is also valid for primitive -types such as ``int`` and ``float``, and ``Optional[...]`` types are -not required. +types such as ``int`` and :py:class:`float`, and :py:data:`Optional[...] +` types are not required. The mode is enabled through the ``--no-strict-optional`` command-line option. In mypy versions before 0.600 this was the default mode. You @@ -566,10 +568,10 @@ missing attribute: p = Point(x=1, y=2) print(p.z) # Error: Point has no attribute 'z' -If you use ``namedtuple`` to define your named tuple, all the items -are assumed to have ``Any`` types. That is, mypy doesn't know anything -about item types. You can use ``typing.NamedTuple`` to also define -item types: +If you use :py:func:`namedtuple ` to define +your named tuple, all the items are assumed to have ``Any`` types. +That is, mypy doesn't know anything about item types. You can use +:py:class:`~typing.NamedTuple` to also define item types: .. code-block:: python @@ -688,7 +690,7 @@ strings. This can be challenging to do in a codebase intended to run in both Python 2 and Python 3 since ``str`` means something different in both versions and ``unicode`` is not a keyword in Python 3. -To help solve this issue, use ``typing.Text`` which is aliased to +To help solve this issue, use :py:class:`~typing.Text` which is aliased to ``unicode`` in Python 2 and to ``str`` in Python 3. This allows you to indicate that a function should accept only unicode strings in a cross-compatible way: @@ -702,7 +704,7 @@ cross-compatible way: In other cases, you may want to write a function that will work with any kind of string but will not let you mix two different string types. To do -so use ``typing.AnyStr``: +so use :py:data:`~typing.AnyStr`: .. code-block:: python @@ -719,7 +721,7 @@ For more details, see :ref:`type-variable-value-restriction`. .. note:: - How ``bytes``, ``str``, and ``unicode`` are handled between Python 2 and + How :py:class:`bytes`, ``str``, and ``unicode`` are handled between Python 2 and Python 3 may change in future versions of mypy. .. _generators: @@ -749,7 +751,7 @@ a value, you should use the return 'Done' Note that unlike many other generics in the typing module, the ``SendType`` of -``Generator`` behaves contravariantly, not covariantly or invariantly. +:py:class:`~typing.Generator` behaves contravariantly, not covariantly or invariantly. If you do not plan on receiving or returning values, then set the ``SendType`` or ``ReturnType`` to ``None``, as appropriate. For example, we could have @@ -764,4 +766,5 @@ annotated the first example as the following: This is slightly different from using ``Iterable[int]`` or ``Iterator[int]``, since generators have ``close()``, ``send()``, and ``throw()`` methods that generic iterables don't. If you will call these methods on the returned -generator, use the ``Generator`` type instead of ``Iterable`` or ``Iterator``. +generator, use the :py:class:`~typing.Generator` type instead of +:py:class:`~typing.Iterable` or :py:class:`~typing.Iterator`. diff --git a/docs/source/literal_types.rst b/docs/source/literal_types.rst index da851fc8f03c..ad03e5f01390 100644 --- a/docs/source/literal_types.rst +++ b/docs/source/literal_types.rst @@ -5,10 +5,16 @@ Literal types .. note:: - 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. + :py:data:`~typing.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. + +.. note:: + + ``Literal`` type is provided in the ``typing_extensions`` package for + Python 2.7 and 3.4-3.7. Starting with Python 3.8, :py:data:`~typing.Literal` + is included in the :py:mod:`typing` module. Literal types let you indicate that an expression is equal to some specific primitive value. For example, if we annotate a variable with type ``Literal["foo"]``, @@ -17,14 +23,13 @@ equal to specifically the string ``"foo"``. This feature is primarily useful when annotating functions that behave differently based on the exact value the caller provides. For example, -suppose we have a function ``fetch_data(...)`` that returns ``bytes`` if the -first argument is ``True``, and ``str`` if it's ``False``. We can construct a +suppose we have a function ``fetch_data(...)`` that returns :py:class:`bytes` if the +first argument is ``True``, and :py:class:`str` if it's ``False``. We can construct a precise type signature for this function using ``Literal[...]`` and overloads: .. code-block:: python - from typing import overload, Union - from typing_extensions import Literal + from typing import overload, Literal, Union # The first two overloads use Literal[...] so we can # have precise return types: @@ -67,7 +72,7 @@ So, ``Literal[-3, b"foo", True]`` is equivalent to more complex types involving literals a little more convenient. Literal types may also contain ``None``. Mypy will treat ``Literal[None]`` as being -equivalent to just ``None``. This means that ``Literal[4, None]``, +equivalent to just ``None``. This means that ``Literal[4, None]``, ``Union[Literal[4], None]``, and ``Optional[Literal[4]]`` are all equivalent. Literals may also contain aliases to other literal types. For example, the @@ -85,7 +90,7 @@ following program is legal: paint("turquoise") # Does not type check Literals may not contain any other kind of type or expression. This means doing -``Literal[my_instance]``, ``Literal[Any]``, ``Literal[3.14]``, or +``Literal[my_instance]``, ``Literal[Any]``, ``Literal[3.14]``, or ``Literal[{"foo": 2, "bar": 5}]`` are all illegal. Future versions of mypy may relax some of these restrictions. For example, we @@ -111,11 +116,12 @@ 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 :py:data:`~typing.Final` (see +:ref:`final_attrs`): .. code-block:: python - from typing_extensions import Final, Literal + from typing import Final, Literal def expects_literal(x: Literal[19]) -> None: pass @@ -124,14 +130,14 @@ 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: .. code-block:: python - from typing_extensions import Final, Literal + from typing import Final, Literal def expects_literal(x: Literal[19]) -> None: pass @@ -139,9 +145,9 @@ the above program almost as if it were written like so: expects_literal(19) This is why ``expects_literal(19)`` type-checks despite the fact that ``reveal_type(c)`` -reports ``int``. +reports :py:class:`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 diff --git a/docs/source/metaclasses.rst b/docs/source/metaclasses.rst index d2b3b6a6c5f3..85cf506138b1 100644 --- a/docs/source/metaclasses.rst +++ b/docs/source/metaclasses.rst @@ -6,11 +6,11 @@ Metaclasses A :ref:`metaclass ` is a class that describes the construction and behavior of other classes, similarly to how classes describe the construction and behavior of objects. -The default metaclass is ``type``, but it's possible to use other metaclasses. -Metaclasses allows one to create "a different kind of class", such as Enums, -NamedTuples and singletons. +The default metaclass is :py:class:`type`, but it's possible to use other metaclasses. +Metaclasses allows one to create "a different kind of class", such as +:py:class:`~enum.Enum`\s, :py:class:`~typing.NamedTuple`\s and singletons. -Mypy has some special understanding of ``ABCMeta`` and ``EnumMeta``. +Mypy has some special understanding of :py:class:`~abc.ABCMeta` and ``EnumMeta``. .. _defining: @@ -32,8 +32,9 @@ In Python 2, the syntax for defining a metaclass is different: class A(object): __metaclass__ = M -Mypy also supports using :py:func:`six.with_metaclass` -to define metaclass in a portable way: +Mypy also supports using :py:func:`six.with_metaclass` and +:py:func:`@six.add_metaclass ` to define +metaclass in a portable way: .. code-block:: python @@ -103,4 +104,4 @@ so it's better not to combine metaclasses and class hierarchies: * Mypy does not understand dynamically-computed metaclasses, such as ``class A(metaclass=f()): ...`` * Mypy does not and cannot understand arbitrary metaclass code. -* Mypy only recognizes subclasses of ``type`` as potential metaclasses. +* Mypy only recognizes subclasses of :py:class:`type` as potential metaclasses. diff --git a/docs/source/more_types.rst b/docs/source/more_types.rst index 6160cba4d86e..7c649b93c600 100644 --- a/docs/source/more_types.rst +++ b/docs/source/more_types.rst @@ -1,34 +1,36 @@ More types ========== -This section introduces a few additional kinds of types, including ``NoReturn``, -``NewType``, ``TypedDict``, and types for async code. It also discusses +This section introduces a few additional kinds of types, including +:py:data:`~typing.NoReturn`, :py:func:`NewType `, +:py:class:`~typing.TypedDict`, and types for async code. It also discusses how to give functions more precise types using overloads. All of these are only situationally useful, so feel free to skip this section and come back when you have a need for some of them. Here's a quick summary of what's covered here: -* ``NoReturn`` lets you tell mypy that a function never returns normally. +* :py:data:`~typing.NoReturn` lets you tell mypy that a function never returns normally. -* ``NewType`` lets you define a variant of a type that is treated as a +* :py:func:`NewType ` lets you define a variant of a type that is treated as a separate type by mypy but is identical to the original type at runtime. - For example, you can have ``UserId`` as a variant of ``int`` that is + For example, you can have ``UserId`` as a variant of :py:class:`int` that is just an ``int`` at runtime. -* ``@overload`` lets you define a function that can accept multiple distinct - signatures. This is useful if you need to encode a relationship between the - arguments and the return type that would be difficult to express normally. +* :py:func:`@overload ` lets you define a function that can + accept multiple distinct signatures. This is useful if you need to encode + a relationship between the arguments and the return type that would be + difficult to express normally. -* ``TypedDict`` lets you give precise types for dictionaries that represent +* :py:class:`~typing.TypedDict` lets you give precise types for dictionaries that represent objects with a fixed schema, such as ``{'id': 1, 'items': ['x']}``. * Async types let you type check programs using ``async`` and ``await``. .. _noreturn: -The NoReturn type -***************** +The :py:data:`~typing.NoReturn` type +************************************ Mypy provides support for functions that never return. For example, a function that unconditionally raises an exception: @@ -40,7 +42,7 @@ example, a function that unconditionally raises an exception: def stop() -> NoReturn: raise Exception('no way') -Mypy will ensure that functions annotated as returning ``NoReturn`` +Mypy will ensure that functions annotated as returning :py:data:`~typing.NoReturn` truly never return, either implicitly or explicitly. Mypy will also recognize that the code after calls to such functions is unreachable and will behave accordingly: @@ -68,8 +70,8 @@ This works for Python 2: .. _newtypes: -NewTypes -******** +:py:func:`NewType `\s +************************************* There are situations where you may want to avoid programming errors by creating simple derived classes that are only used to distinguish @@ -84,8 +86,8 @@ certain values from base class instances. Example: ... However, this approach introduces some runtime overhead. To avoid this, the typing -module provides a helper function ``NewType`` that creates simple unique types with -almost zero runtime overhead. Mypy will treat the statement +module provides a helper function :py:func:`NewType ` that creates +simple unique types with almost zero runtime overhead. Mypy will treat the statement ``Derived = NewType('Derived', Base)`` as being roughly equivalent to the following definition: @@ -122,10 +124,10 @@ implicitly casting from ``UserId`` where ``int`` is expected. Examples: num = UserId(5) + 1 # type: int -``NewType`` accepts exactly two arguments. The first argument must be a string literal -containing the name of the new type and must equal the name of the variable to which the new -type is assigned. The second argument must be a properly subclassable class, i.e., -not a type construct like ``Union``, etc. +:py:func:`NewType ` accepts exactly two arguments. The first argument +must be a string literal containing the name of the new type and must equal the name +of the variable to which the new type is assigned. The second argument must be a properly +subclassable class, i.e., not a type construct like :py:data:`~typing.Union`, etc. The function returned by ``NewType`` accepts only one argument; this is equivalent to supporting only one constructor accepting an instance of the base class (see above). @@ -147,16 +149,16 @@ Example: tcp_packet = TcpPacketId(127, 0) # Fails in type checker and at runtime -You cannot use ``isinstance()`` or ``issubclass()`` on the object returned by -``NewType()``, because function objects don't support these operations. You cannot -create subclasses of these objects either. +You cannot use :py:func:`isinstance` or :py:func:`issubclass` on the object returned by +``NewType()``, because function objects don't support these operations. +You cannot create subclasses of these objects either. .. note:: - Unlike type aliases, ``NewType`` will create an entirely new and - unique type when used. The intended purpose of ``NewType`` is to help you - detect cases where you accidentally mixed together the old base type and the - new derived type. + Unlike type aliases, :py:func:`NewType ` will create + an entirely new and unique type when used. The intended purpose of + ``NewType`` is to help you detect cases where you accidentally mixed + together the old base type and the new derived type. For example, the following will successfully typecheck when using type aliases: @@ -189,10 +191,11 @@ Function overloading ******************** Sometimes the arguments and types in a function depend on each other -in ways that can't be captured with a ``Union``. For example, suppose -we want to write a function that can accept x-y coordinates. If we pass -in just a single x-y coordinate, we return a ``ClickEvent`` object. However, -if we pass in two x-y coordinates, we return a ``DragEvent`` object. +in ways that can't be captured with a :py:data:`~typing.Union`. +For example, suppose we want to write a function that can accept +x-y coordinates. If we pass in just a single x-y coordinate, we return +a ``ClickEvent`` object. However, if we pass in two x-y coordinates, +we return a ``DragEvent`` object. Our first attempt at writing this function might look like this: @@ -261,9 +264,9 @@ always have a return type of ``ClickEvent`` and will report errors for calls like ``mouse_event(5, 25, 2)``. As another example, suppose we want to write a custom container class that -implements the ``__getitem__`` method (``[]`` bracket indexing). If this -method receives an integer we return a single item. If it receives a -``slice``, we return a ``Sequence`` of items. +implements the :py:meth:`__getitem__ ` method +(``[]`` bracket indexing). If this method receives an integer we return +a single item. If it receives a ``slice``, we return a :py:class:`~typing.Sequence` of items. We can precisely encode this relationship between the argument and the return type by using overloads like so: @@ -310,7 +313,7 @@ ignored: they're overridden by the final implementation function. This means that an overloaded function is still an ordinary Python function! There is no automatic dispatch handling and you must manually handle the different types in the implementation (e.g. by using -``if`` statements and ``isinstance`` checks). +``if`` statements and :py:func:`isinstance ` checks). If you are adding an overload within a stub file, the implementation function should be omitted: stubs do not contain runtime logic. @@ -358,12 +361,12 @@ program: The ``summarize([])`` call matches both variants: an empty list could be either a ``List[int]`` or a ``List[str]``. In this case, mypy will break the tie by picking the first matching variant: ``output`` -will have an inferred type of ``float``. The implementor is responsible +will have an inferred type of :py:class:`float`. The implementor is responsible for making sure ``summarize`` breaks ties in the same way at runtime. However, there are two exceptions to the "pick the first match" rule. First, if multiple variants match due to an argument being of type -``Any``, mypy will make the inferred type also be ``Any``: +:py:data:`~typing.Any`, mypy will make the inferred type also be ``Any``: .. code-block:: python @@ -391,7 +394,8 @@ matching variant returns: To minimize potential issues, we recommend that you: 1. Make sure your overload variants are listed in the same order as - the runtime checks (e.g. ``isinstance`` checks) in your implementation. + the runtime checks (e.g. :py:func:`isinstance ` checks) + in your implementation. 2. Order your variants and runtime checks from most to least specific. (See the following section for an example). @@ -481,8 +485,8 @@ when we try using it like so: some_obj: object = 42 unsafe_func(some_obj) + " danger danger" # Type checks, yet crashes at runtime! -Since ``some_obj`` is of type ``object``, mypy will decide that ``unsafe_func`` -must return something of type ``str`` and concludes the above will type check. +Since ``some_obj`` is of type :py:class:`object`, mypy will decide that ``unsafe_func`` +must return something of type :py:class:`str` and concludes the above will type check. But in reality, ``unsafe_func`` will return an int, causing the code to crash at runtime! @@ -594,8 +598,8 @@ expect to get back when ``await``-ing the coroutine. loop.close() The result of calling an ``async def`` function *without awaiting* will be a -value of type ``typing.Coroutine[Any, Any, T]``, which is a subtype of -``Awaitable[T]``: +value of type :py:class:`Coroutine[Any, Any, T] `, which is +a subtype of :py:class:`Awaitable[T] `: .. code-block:: python @@ -608,13 +612,14 @@ value of type ``typing.Coroutine[Any, Any, T]``, which is a subtype of an expression. If you want to use coroutines in Python 3.4, which does not support -the ``async def`` syntax, you can instead use the ``@asyncio.coroutine`` -decorator to convert a generator into a coroutine. +the ``async def`` syntax, you can instead use the :py:func:`@asyncio.coroutine +` decorator to convert a generator into a coroutine. Note that we set the ``YieldType`` of the generator to be ``Any`` in the following example. This is because the exact yield type is an implementation -detail of the coroutine runner (e.g. the ``asyncio`` event loop) and your -coroutine shouldn't have to know or care about what precisely that type is. +detail of the coroutine runner (e.g. the :py:mod:`asyncio` :doc:`event loop +`) and your coroutine shouldn't have to know +or care about what precisely that type is. .. code-block:: python @@ -638,8 +643,8 @@ will be a value of type ``Awaitable[T]``. .. note:: - At runtime, you are allowed to add the ``@asyncio.coroutine`` decorator to - both functions and generators. This is useful when you want to mark a + At runtime, you are allowed to add the :py:func:`@asyncio.coroutine ` + decorator to both functions and generators. This is useful when you want to mark a work-in-progress function as a coroutine, but have not yet added ``yield`` or ``yield from`` statements: @@ -669,7 +674,7 @@ will be a value of type ``Awaitable[T]``. yield return "placeholder" -You may also choose to create a subclass of ``Awaitable`` instead: +You may also choose to create a subclass of :py:class:`~typing.Awaitable` instead: .. code-block:: python @@ -694,7 +699,7 @@ You may also choose to create a subclass of ``Awaitable`` instead: loop.run_until_complete(countdown_3("Heart of Gold", 5)) loop.close() -To create an iterable coroutine, subclass ``AsyncIterator``: +To create an iterable coroutine, subclass :py:class:`~typing.AsyncIterator`: .. code-block:: python @@ -736,8 +741,8 @@ and one .. _typeddict: -TypedDict -********* +``TypedDict`` +************* Python programs often use dictionaries with string keys to represent objects. Here is a typical example: @@ -752,32 +757,32 @@ for ``'name'`` and ``int`` for ``'year'`` above). We've previously seen the ``Dict[K, V]`` type, which lets you declare uniform dictionary types, where every value has the same type, and arbitrary keys are supported. This is clearly not a good fit for -``movie`` above. Instead, you can use a ``TypedDict`` to give a precise -type for objects like ``movie``, where the type of each +``movie`` above. Instead, you can use a :py:class:`~typing.TypedDict` +to give a precise type for objects like ``movie``, where the type of each dictionary value depends on the key: .. code-block:: python - from mypy_extensions import TypedDict + from typing import TypedDict Movie = TypedDict('Movie', {'name': str, 'year': int}) movie = {'name': 'Blade Runner', 'year': 1982} # type: Movie -``Movie`` is a TypedDict type with two items: ``'name'`` (with type ``str``) +``Movie`` is a ``TypedDict`` type with two items: ``'name'`` (with type ``str``) and ``'year'`` (with type ``int``). Note that we used an explicit type annotation for the ``movie`` variable. This type annotation is important -- without it, mypy will try to infer a regular, uniform -``Dict`` type for ``movie``, which is not what we want here. +:py:class:`~typing.Dict` type for ``movie``, which is not what we want here. .. note:: - If you pass a TypedDict object as an argument to a function, no + If you pass a :py:class:`~typing.TypedDict` object as an argument to a function, no type annotation is usually necessary since mypy can infer the desired type based on the declared argument type. Also, if an assignment target has been previously defined, and it has a - TypedDict type, mypy will treat the assigned value as a TypedDict, - not ``Dict``. + ``TypedDict`` type, mypy will treat the assigned value as a ``TypedDict``, + not :py:class:`~typing.Dict`. Now mypy will recognize these as valid: @@ -794,10 +799,10 @@ Mypy will detect an invalid key as an error: Mypy will also reject a runtime-computed expression as a key, as it can't verify that it's a valid key. You can only use string -literals as TypedDict keys. +literals as ``TypedDict`` keys. -The ``TypedDict`` type object can also act as a constructor. It -returns a normal ``dict`` object at runtime -- a ``TypedDict`` does +The :py:class:`~typing.TypedDict` type object can also act as a constructor. It +returns a normal :py:class:`dict` object at runtime -- a ``TypedDict`` does not define a new runtime type: .. code-block:: python @@ -809,20 +814,20 @@ This is equivalent to just constructing a dictionary directly using sometimes convenient, since it can be used without a type annotation, and it also makes the type of the object explicit. -Like all types, TypedDicts can be used as components to build +Like all types, ``TypedDict``\s can be used as components to build arbitrarily complex types. For example, you can define nested -TypedDicts and containers with TypedDict items. +``TypedDict``\s and containers with ``TypedDict`` items. Unlike most other types, mypy uses structural compatibility checking -(or structural subtyping) with TypedDicts. A TypedDict object with +(or structural subtyping) with ``TypedDict``\s. A ``TypedDict`` object with extra items is a compatible with (a subtype of) a narrower -TypedDict, assuming item types are compatible (*totality* also affects +``TypedDict``, assuming item types are compatible (*totality* also affects subtyping, as discussed below). -A TypedDict object is not a subtype of the regular ``Dict[...]`` -type (and vice versa), since ``Dict`` allows arbitrary keys to be -added and removed, unlike TypedDict. However, any TypedDict object is +A ``TypedDict`` object is not a subtype of the regular ``Dict[...]`` +type (and vice versa), since :py:class:`~typing.Dict` allows arbitrary keys to be +added and removed, unlike ``TypedDict``. However, any ``TypedDict`` object is a subtype of (that is, compatible with) ``Mapping[str, object]``, since -``typing.Mapping`` only provides read-only access to the dictionary items: +:py:class:`~typing.Mapping` only provides read-only access to the dictionary items: .. code-block:: python @@ -834,7 +839,10 @@ a subtype of (that is, compatible with) ``Mapping[str, object]``, since .. note:: - You need to install ``mypy_extensions`` using pip to use ``TypedDict``: + Starting with Python 3.8, :py:class:`~typing.TypedDict` + is included in the :py:mod:`typing` module. + To use ``TypedDict`` with Python 2.7 and 3.4-3.7, you need to install + ``mypy_extensions`` using pip: .. code-block:: text @@ -849,8 +857,8 @@ a subtype of (that is, compatible with) ``Mapping[str, object]``, since Totality -------- -By default mypy ensures that a TypedDict object has all the specified -keys. This will be flagged as an error: +By default mypy ensures that a :py:class:`~typing.TypedDict` object has +all the specified keys. This will be flagged as an error: .. code-block:: python @@ -858,7 +866,7 @@ keys. This will be flagged as an error: toy_story = {'name': 'Toy Story'} # type: Movie Sometimes you want to allow keys to be left out when creating a -TypedDict object. You can provide the ``total=False`` argument to +``TypedDict`` object. You can provide the ``total=False`` argument to ``TypedDict(...)`` to achieve this: .. code-block:: python @@ -869,11 +877,11 @@ TypedDict object. You can provide the ``total=False`` argument to options['language'] = 'en' You may need to use ``get()`` to access items of a partial (non-total) -TypedDict, since indexing using ``[]`` could fail at runtime. -However, mypy still lets use ``[]`` with a partial TypedDict -- you -just need to be careful with it, as it could result in a ``KeyError``. +``TypedDict``, since indexing using ``[]`` could fail at runtime. +However, mypy still lets use ``[]`` with a partial ``TypedDict`` -- you +just need to be careful with it, as it could result in a :py:exc:`KeyError`. Requiring ``get()`` everywhere would be too cumbersome. (Note that you -are free to use ``get()`` with total TypedDicts as well.) +are free to use ``get()`` with total ``TypedDict``\s as well.) Keys that aren't required are shown with a ``?`` in error messages: @@ -884,18 +892,18 @@ Keys that aren't required are shown with a ``?`` in error messages: reveal_type(options) Totality also affects structural compatibility. You can't use a partial -TypedDict when a total one is expected. Also, a total TypedDict is not +``TypedDict`` when a total one is expected. Also, a total ``TypedDict`` is not valid when a partial one is expected. Supported operations -------------------- -TypedDict objects support a subset of dictionary operations and methods. -You must use string literals as keys when calling most of the methods, -as otherwise mypy won't be able to check that the key is valid. List -of supported operations: +:py:class:`~typing.TypedDict` objects support a subset of dictionary operations +and methods. You must use string literals as keys when calling most of the methods, +as otherwise mypy won't be able to check that the key is valid. +List of supported operations: -* Anything included in ``typing.Mapping``: +* Anything included in :py:class:`~typing.Mapping`: * ``d[key]`` * ``key in d`` @@ -909,8 +917,8 @@ of supported operations: * ``d.copy()`` * ``d.setdefault(key, default)`` * ``d1.update(d2)`` -* ``d.pop(key[, default])`` (partial TypedDicts only) -* ``del d[key]`` (partial TypedDicts only) +* ``d.pop(key[, default])`` (partial ``TypedDict``\s only) +* ``del d[key]`` (partial ``TypedDict``\s only) In Python 2 code, these methods are also supported: @@ -922,18 +930,18 @@ In Python 2 code, these methods are also supported: .. note:: ``clear()`` and ``popitem()`` are not supported since they are unsafe - -- they could delete required TypedDict items that are not visible to + -- they could delete required ``TypedDict`` items that are not visible to mypy because of structural subtyping. Class-based syntax ------------------ -An alternative, class-based syntax to define a TypedDict is supported -in Python 3.6 and later: +An alternative, class-based syntax to define a :py:class:`~typing.TypedDict` +is supported in Python 3.6 and later: .. code-block:: python - from mypy_extensions import TypedDict + from typing import TypedDict class Movie(TypedDict): name: str @@ -943,7 +951,7 @@ The above definition is equivalent to the original ``Movie`` definition. It doesn't actually define a real class. This syntax also supports a form of inheritance -- subclasses can define additional items. However, this is primarily a notational shortcut. Since mypy -uses structural compatibility with TypedDicts, inheritance is not +uses structural compatibility with ``TypedDict``\s, inheritance is not required for compatibility. Here is an example of inheritance: .. code-block:: python @@ -960,9 +968,9 @@ Now ``BookBasedMovie`` has keys ``name``, ``year`` and ``based_on``. Mixing required and non-required items -------------------------------------- -In addition to allowing reuse across TypedDict types, inheritance also allows -you to mix required and non-required (using ``total=False``) items -in a single TypedDict. Example: +In addition to allowing reuse across :py:class:`~typing.TypedDict` types, +inheritance also allows you to mix required and non-required (using +``total=False``) items in a single ``TypedDict``. Example: .. code-block:: python @@ -974,8 +982,8 @@ in a single TypedDict. Example: based_on: str Now ``Movie`` has required keys ``name`` and ``year``, while ``based_on`` -can be left out when constructing an object. A TypedDict with a mix of required +can be left out when constructing an object. A ``TypedDict`` with a mix of required and non-required keys, such as ``Movie`` above, will only be compatible with -another TypedDict if all required keys in the other TypedDict are required keys in the -first TypedDict, and all non-required keys of the other TypedDict are also non-required keys -in the first TypedDict. +another ``TypedDict`` if all required keys in the other ``TypedDict`` are required keys in the +first ``TypedDict``, and all non-required keys of the other ``TypedDict`` are also non-required keys +in the first ``TypedDict``. diff --git a/docs/source/protocols.rst b/docs/source/protocols.rst index fb6eb2198397..abbfebc12854 100644 --- a/docs/source/protocols.rst +++ b/docs/source/protocols.rst @@ -10,10 +10,10 @@ inherits class ``C``, it's also a subtype of ``C``, and instances of ``D`` can be used when ``C`` instances are expected. This form of subtyping is used by default in mypy, since it's easy to understand and produces clear and concise error messages, and since it matches -how the native ``isinstance()`` check works -- based on class -hierarchy. *Structural* subtyping can also be useful. Class ``D`` is -a structural subtype of class ``C`` if the former has all attributes -and methods of the latter, and with compatible types. +how the native :py:func:`isinstance ` check works -- +based on class hierarchy. *Structural* subtyping can also be useful. +Class ``D`` is a structural subtype of class ``C`` if the former has +all attributes and methods of the latter, and with compatible types. Structural subtyping can be seen as a static equivalent of duck typing, which is well known to Python programmers. Mypy provides @@ -26,11 +26,14 @@ and structural subtyping in Python. Predefined protocols ******************** -The ``typing`` module defines various protocol classes that correspond -to common Python protocols, such as ``Iterable[T]``. If a class -defines a suitable ``__iter__`` method, mypy understands that it -implements the iterable protocol and is compatible with ``Iterable[T]``. -For example, ``IntList`` below is iterable, over ``int`` values: +The :py:mod:`typing` module defines various protocol classes that +correspond to common Python protocols, such as +:py:class:`Iterable[T] `. +If a class defines a suitable :py:meth:`__iter__ ` +method, mypy understands that it implements the iterable protocol +and is compatible with ``Iterable[T]``. +For example, ``IntList`` below is iterable, over :py:class:`int` +values: .. code-block:: python @@ -66,18 +69,18 @@ Iteration protocols The iteration protocols are useful in many contexts. For example, they allow iteration of objects in for loops. -``Iterable[T]`` ---------------- +:py:class:`Iterable[T] ` +----------------------------------------- The :ref:`example above ` has a simple implementation of an -``__iter__`` method. +:py:meth:`__iter__ ` method. .. code-block:: python def __iter__(self) -> Iterator[T] -``Iterator[T]`` ---------------- +:py:class:`Iterator[T] ` +----------------------------------------- .. code-block:: python @@ -88,20 +91,20 @@ Collection protocols .................... Many of these are implemented by built-in container types such as -``list`` and ``dict``, and these are also useful for user-defined -collection objects. +:py:class:`list` and :py:class:`dict`, and these are also useful +for user-defined collection objects. -``Sized`` ---------- +:py:class:`~typing.Sized` +------------------------- -This is a type for objects that support ``len(x)``. +This is a type for objects that support :py:func:`len(x) `. .. code-block:: python def __len__(self) -> int -``Container[T]`` ----------------- +:py:class:`Container[T] ` +------------------------------------------- This is a type for objects that support the ``in`` operator. @@ -109,8 +112,8 @@ This is a type for objects that support the ``in`` operator. def __contains__(self, x: object) -> bool -``Collection[T]`` ------------------ +:py:class:`Collection[T] ` +--------------------------------------------- .. code-block:: python @@ -124,29 +127,29 @@ One-off protocols These protocols are typically only useful with a single standard library function or class. -``Reversible[T]`` ------------------ +:py:class:`Reversible[T] ` +--------------------------------------------- -This is a type for objects that support ``reversed(x)``. +This is a type for objects that support :py:func:`reversed(x) `. .. code-block:: python def __reversed__(self) -> Iterator[T] -``SupportsAbs[T]`` ------------------- +:py:class:`SupportsAbs[T] ` +----------------------------------------------- -This is a type for objects that support ``abs(x)``. ``T`` is the type of -value returned by ``abs(x)``. +This is a type for objects that support :py:func:`abs(x) `. +``T`` is the type of value returned by ``abs(x)``. .. code-block:: python def __abs__(self) -> T -``SupportsBytes`` ------------------ +:py:class:`~typing.SupportsBytes` +--------------------------------- -This is a type for objects that support ``bytes(x)``. +This is a type for objects that support :py:class:`bytes(x) `. .. code-block:: python @@ -154,40 +157,40 @@ This is a type for objects that support ``bytes(x)``. .. _supports-int-etc: -``SupportsComplex`` -------------------- +:py:class:`~typing.SupportsComplex` +----------------------------------- -This is a type for objects that support ``complex(x)``. Note that no arithmetic operations -are supported. +This is a type for objects that support :py:class:`complex(x) `. +Note that no arithmetic operations are supported. .. code-block:: python def __complex__(self) -> complex -``SupportsFloat`` ------------------ +:py:class:`~typing.SupportsFloat` +--------------------------------- -This is a type for objects that support ``float(x)``. Note that no arithmetic operations -are supported. +This is a type for objects that support :py:class:`float(x) `. +Note that no arithmetic operations are supported. .. code-block:: python def __float__(self) -> float -``SupportsInt`` ---------------- +:py:class:`~typing.SupportsInt` +------------------------------- -This is a type for objects that support ``int(x)``. Note that no arithmetic operations -are supported. +This is a type for objects that support :py:class:`int(x) `. +Note that no arithmetic operations are supported. .. code-block:: python def __int__(self) -> int -``SupportsRound[T]`` --------------------- +:py:class:`SupportsRound[T] ` +--------------------------------------------------- -This is a type for objects that support ``round(x)``. +This is a type for objects that support :py:func:`round(x) `. .. code-block:: python @@ -199,22 +202,22 @@ Async protocols These protocols can be useful in async code. See :ref:`async-and-await` for more information. -``Awaitable[T]`` ----------------- +:py:class:`Awaitable[T] ` +------------------------------------------- .. code-block:: python def __await__(self) -> Generator[Any, None, T] -``AsyncIterable[T]`` --------------------- +:py:class:`AsyncIterable[T] ` +--------------------------------------------------- .. code-block:: python def __aiter__(self) -> AsyncIterator[T] -``AsyncIterator[T]`` --------------------- +:py:class:`AsyncIterator[T] ` +--------------------------------------------------- .. code-block:: python @@ -228,8 +231,8 @@ There are two protocols for context managers -- one for regular context managers and one for async ones. These allow defining objects that can be used in ``with`` and ``async with`` statements. -``ContextManager[T]`` ---------------------- +:py:class:`ContextManager[T] ` +----------------------------------------------------- .. code-block:: python @@ -239,8 +242,8 @@ be used in ``with`` and ``async with`` statements. exc_value: Optional[BaseException], traceback: Optional[TracebackType]) -> Optional[bool] -``AsyncContextManager[T]`` --------------------------- +:py:class:`AsyncContextManager[T] ` +--------------------------------------------------------------- .. code-block:: python @@ -253,13 +256,12 @@ be used in ``with`` and ``async with`` statements. Simple user-defined protocols ***************************** -You can define your own protocol class by inheriting the special ``Protocol`` -class: +You can define your own protocol class by inheriting the special +:py:class:`~typing.Protocol` class: .. code-block:: python - from typing import Iterable - from typing_extensions import Protocol + from typing import Iterable, Protocol class SupportsClose(Protocol): def close(self) -> None: @@ -278,14 +280,14 @@ class: close_all([Resource(), open('some/file')]) # Okay! ``Resource`` is a subtype of the ``SupportsClose`` protocol since it defines -a compatible ``close`` method. Regular file objects returned by ``open()`` are +a compatible ``close`` method. Regular file objects returned by :py:func:`open` are similarly compatible with the protocol, as they support ``close()``. .. note:: The ``Protocol`` base class is provided in the ``typing_extensions`` - package for Python 2.7 and 3.4-3.7. Starting with Python 3.8, ``Protocol`` - is included in the ``typing`` module. + package for Python 2.7 and 3.4-3.7. Starting with Python 3.8, + :py:class:`~typing.Protocol` is included in the :py:mod:`typing` module. Defining subprotocols and subclassing protocols *********************************************** @@ -317,8 +319,8 @@ and merged using multiple inheritance. Example: Note that inheriting from an existing protocol does not automatically turn the subclass into a protocol -- it just creates a regular (non-protocol) class or ABC that implements the given protocol (or -protocols). The ``Protocol`` base class must always be explicitly -present if you are defining a protocol: +protocols). The :py:class:`~typing.Protocol` base class must always +be explicitly present if you are defining a protocol: .. code-block:: python @@ -356,8 +358,7 @@ such as trees and linked lists: .. code-block:: python - from typing import TypeVar, Optional - from typing_extensions import Protocol + from typing import TypeVar, Optional, Protocol class TreeLike(Protocol): value: int @@ -376,16 +377,16 @@ such as trees and linked lists: root: TreeLike = SimpleTree(0) # OK -Using ``isinstance()`` with protocols -************************************* +Using :py:func:`isinstance` with protocols +****************************************** -You can use a protocol class with ``isinstance()`` if you decorate it -with the ``@runtime_checkable`` class decorator. The decorator adds -support for basic runtime structural checks: +You can use a protocol class with :py:func:`isinstance` if you decorate it +with the :py:func:`@runtime_checkable ` class +decorator. The decorator adds support for basic runtime structural checks: .. code-block:: python - from typing_extensions import Protocol, runtime_checkable + from typing import Protocol, runtime_checkable @runtime_checkable class Portable(Protocol): @@ -399,11 +400,11 @@ support for basic runtime structural checks: if isinstance(mug, Portable): use(mug.handles) # Works statically and at runtime -``isinstance()`` also works with the :ref:`predefined protocols ` -in ``typing`` such as ``Iterable``. +``isinstance`` also works with the :ref:`predefined protocols ` +in :py:mod:`typing` such as :py:class:`~typing.Iterable`. .. note:: - ``isinstance()`` with protocols is not completely safe at runtime. + :py:func:`isinstance` with protocols is not completely safe at runtime. For example, signatures of methods are not checked. The runtime implementation only checks that all protocol members are defined. @@ -413,14 +414,14 @@ Callback protocols ****************** Protocols can be used to define flexible callback types that are hard -(or even impossible) to express using the ``Callable[...]`` syntax, such as variadic, -overloaded, and complex generic callbacks. They are defined with a special ``__call__`` -member: +(or even impossible) to express using the :py:data:`Callable[...] +` syntax, such as variadic, overloaded, and complex +generic callbacks. They are defined with a special :py:meth:`__call__ +` member: .. code-block:: python - from typing import Optional, Iterable, List - from typing_extensions import Protocol + from typing import Optional, Iterable, List, Protocol class Combiner(Protocol): def __call__(self, *vals: bytes, maxlen: Optional[int] = None) -> List[bytes]: ... @@ -444,8 +445,7 @@ a double underscore prefix is used. For example: .. code-block:: python - from typing import Callable, TypeVar - from typing_extensions import Protocol + from typing import Callable, Protocol, TypeVar T = TypeVar('T') diff --git a/docs/source/python2.rst b/docs/source/python2.rst index abadf21f0d1c..de87a56a2a06 100644 --- a/docs/source/python2.rst +++ b/docs/source/python2.rst @@ -15,7 +15,7 @@ Run mypy in Python 2 mode by using the ``--py2`` option:: To run your program, you must have the ``typing`` module in your Python 2 module search path. Use ``pip install typing`` to install the module. This also works for Python 3 versions prior to 3.5 that don't -include ``typing`` in the standard library. +include :py:mod:`typing` in the standard library. The example below illustrates the Python 2 function type annotation syntax. This syntax is also valid in Python 3 mode: @@ -45,11 +45,11 @@ It's worth going through these details carefully to avoid surprises: annotation syntax described below). Again, the above example illustrates this. -- Things like ``Any`` must be imported from ``typing``, even if they +- Things like :py:data:`~typing.Any` must be imported from ``typing``, even if they are only used in comments. -- In Python 2 mode ``str`` is implicitly promoted to ``unicode``, similar - to how ``int`` is compatible with ``float``. This is unlike ``bytes`` and +- In Python 2 mode :py:class:`str` is implicitly promoted to ``unicode``, similar + to how :py:class:`int` is compatible with :py:class:`float`. This is unlike :py:class:`bytes` and ``str`` in Python 3, which are incompatible. ``bytes`` in Python 2 is equivalent to ``str``. (This might change in the future.) diff --git a/docs/source/python36.rst b/docs/source/python36.rst index d9a503c9a1ea..fa068665b516 100644 --- a/docs/source/python36.rst +++ b/docs/source/python36.rst @@ -23,8 +23,8 @@ syntax, with or without an initializer expression: .. _class-var: You can also mark names intended to be used as class variables with -``ClassVar``. In a pinch you can also use ClassVar in ``# type`` -comments. Example: +:py:data:`~typing.ClassVar`. In a pinch you can also use ``ClassVar`` +in ``# type`` comments. Example: .. code-block:: python @@ -49,8 +49,8 @@ Asynchronous generators (:pep:`525`) and comprehensions (:pep:`530`) Python 3.6 allows coroutines defined with ``async def`` (:pep:`492`) to be generators, i.e. contain ``yield`` expressions. It also introduced a syntax for -asynchronous comprehensions. This example uses the ``AsyncIterator`` type to -define an async generator: +asynchronous comprehensions. This example uses the :py:class:`~typing.AsyncIterator` +type to define an async generator: .. code-block:: python diff --git a/docs/source/running_mypy.rst b/docs/source/running_mypy.rst index 7fff6b410f6c..2c988023a79f 100644 --- a/docs/source/running_mypy.rst +++ b/docs/source/running_mypy.rst @@ -15,7 +15,7 @@ and recommendations on how to handle any issues you may encounter along the way. If you are interested in learning about how to configure the -actual way mypy type checks your code, see our +actual way mypy type checks your code, see our :ref:`command-line` guide. @@ -51,7 +51,7 @@ different ways. Mypy will use an algorithm very similar to the one Python uses to find where modules and imports are located on the file system. - For more details, see :ref:`finding-imports`. + For more details, see :ref:`finding-imports`. 3. Third, you can use the ``-p`` (long form: ``--package``) flag to specify a package to be (recursively) type checked. This flag @@ -97,7 +97,7 @@ you can use this instead:: This file can technically also contain any command line flag, not just file paths. However, if you want to configure many different -flags, the recommended approach is to use a +flags, the recommended approach is to use a :ref:`configuration file ` instead. @@ -105,8 +105,8 @@ flags, the recommended approach is to use a How mypy handles imports ************************ -When mypy encounters an ``import`` statement, it will first -:ref:`attempt to locate ` that module +When mypy encounters an ``import`` statement, it will first +:ref:`attempt to locate ` that module or type stubs for that module in the file system. Mypy will then type check the imported module. There are three different outcomes of this process: @@ -173,9 +173,9 @@ are trying to use has done neither of these things. In that case, you can try: 2. :ref:`Writing your own stub files ` containing type hints for the library. You can point mypy at your type hints either by passing - them in via the command line, by adding the location to the - `MYPYPATH` environment variable, or by using the ``mypy_path`` - :ref:`config file option `. + them in via the command line, by adding the location to the + ``MYPYPATH`` environment variable, or by using the ``mypy_path`` + :ref:`config file option `. Note that if you decide to write your own stub files, they don't need to be complete! A good strategy is to add stubs for just the parts @@ -188,7 +188,7 @@ are trying to use has done neither of these things. In that case, you can try: If the module is a third party library, but you cannot find any existing type hints nor have time to write your own, you can *silence* the errors: -1. To silence a *single* missing import error, add a `# type: ignore` at the end of the +1. To silence a *single* missing import error, add a ``# type: ignore`` at the end of the line containing the import. 2. To silence *all* missing import imports errors from a single library, add @@ -233,7 +233,7 @@ If the module is a part of the standard library, try: errors. After upgrading, we recommend running mypy using the ``--warn-unused-ignores`` flag to help you find any ``# type: ignore`` annotations you no longer need. - + .. _follow-imports: Following imports @@ -243,7 +243,7 @@ Mypy is designed to :ref:`doggedly follow all imports `, even if the imported module is not a file you explicitly wanted mypy to check. For example, suppose we have two modules ``mycode.foo`` and ``mycode.bar``: -the former has type hints and the latter does not. We run +the former has type hints and the latter does not. We run ``mypy -m mycode.foo`` and mypy discovers that ``mycode.foo`` imports ``mycode.bar``. @@ -251,7 +251,7 @@ How do we want mypy to type check ``mycode.bar``? We can configure the desired behavior by using the ``--follow-imports`` flag. This flag accepts one of four string values: -- ``normal`` (the default) follows all imports normally and +- ``normal`` (the default) follows all imports normally and type checks all top level code (as well as the bodies of all functions and methods with at least one type annotation in the signature). @@ -261,7 +261,7 @@ accepts one of four string values: - ``skip`` will *not* follow imports and instead will silently replace the module (and *anything imported from it*) with an - object of type ``Any``. + object of type :py:data:`~typing.Any`. - ``error`` behaves in the same way as ``skip`` but is not quite as silent -- it will flag the import as an error, like this:: @@ -330,12 +330,12 @@ to modules to type check. One more thing about checking modules and packages: if the directory *containing* a module or package specified on the command line has an ``__init__.py[i]`` file, mypy assigns these an absolute module name by -crawling up the path until no ``__init__.py[i]`` file is found. +crawling up the path until no ``__init__.py[i]`` file is found. For example, suppose we run the command ``mypy foo/bar/baz.py`` where ``foo/bar/__init__.py`` exists but ``foo/__init__.py`` does not. Then the module name assumed is ``bar.baz`` and the directory ``foo`` is -added to mypy's module search path. +added to mypy's module search path. On the other hand, if ``foo/bar/__init__.py`` did not exist, ``foo/bar`` would be added to the module search path instead, and the module name @@ -371,7 +371,7 @@ This is computed from the following items: .. note:: - You cannot point to a PEP 561 package via the MYPYPATH, it must be + You cannot point to a :pep:`561` package via the ``MYPYPATH``, it must be installed (see :ref:`PEP 561 support `) For sources given on the command line, the path is adjusted by crawling diff --git a/docs/source/stubgen.rst b/docs/source/stubgen.rst index 303823130981..178a0d1b5995 100644 --- a/docs/source/stubgen.rst +++ b/docs/source/stubgen.rst @@ -46,7 +46,7 @@ Stubgen can generate this stub file based on the above file: def create_empty() -> Window: ... Stubgen generates *draft* stubs. The auto-generated stub files often -require some manual updates, and most types will default to ``Any``. +require some manual updates, and most types will default to :py:data:`~typing.Any`. The stubs will be much more useful if you add more precise type annotations, at least for the most commonly used functionality. @@ -125,7 +125,7 @@ alter the default behavior: useful if semantic analysis causes a critical mypy error. ``--doc-dir PATH`` - Try to infer better signatures by parsing .rst documentation in ``PATH``. + Try to infer better signatures by parsing ``.rst`` documentation in ``PATH``. This may result in better stubs, but currently it only works for C extension modules. diff --git a/docs/source/stubs.rst b/docs/source/stubs.rst index d051e03fd007..fdfad5acfa8e 100644 --- a/docs/source/stubs.rst +++ b/docs/source/stubs.rst @@ -103,7 +103,7 @@ Python code -- for example, when writing methods in The recommended style is to use ellipses to do so, just like in stub files. It is also considered stylistically acceptable to -throw a ``NotImplementedError`` in cases where the user of the +throw a :py:exc:`NotImplementedError` in cases where the user of the code may accidentally call functions with no actual logic. You can also elide default arguments as long as the function body @@ -114,8 +114,7 @@ For example: .. code-block:: python - from typing import List - from typing_extensions import Protocol + from typing import List, Protocol class Resource(Protocol): def ok_1(self, foo: List[str] = ...) -> None: ... @@ -138,4 +137,3 @@ For example: it is not possible to elide default arguments in Python 2 code. You can still elide function bodies in Python 2 by using either the ``pass`` statement or by throwing a ``NotImplementedError``. - diff --git a/docs/source/supported_python_features.rst b/docs/source/supported_python_features.rst index 20e01f096da7..009d8386e002 100644 --- a/docs/source/supported_python_features.rst +++ b/docs/source/supported_python_features.rst @@ -13,8 +13,8 @@ or module outside its definition -- but only if this is visible to the type checker. This only affects static checking, as mypy performs no additional type checking at runtime. You can easily work around this. For example, you can use dynamically typed code or values with -``Any`` types, or you can use ``setattr`` or other introspection -features. However, you need to be careful if you decide to do this. If -used indiscriminately, you may have difficulty using static typing -effectively, since the type checker cannot see functions defined at -runtime. +:py:data:`~typing.Any` types, or you can use :py:func:`setattr` +or other introspection features. However, you need to be careful +if you decide to do this. If used indiscriminately, you may have +difficulty using static typing effectively, since the type checker +cannot see functions defined at runtime. diff --git a/docs/source/type_inference_and_annotations.rst b/docs/source/type_inference_and_annotations.rst index 25dca43be3ee..354bc124cd10 100644 --- a/docs/source/type_inference_and_annotations.rst +++ b/docs/source/type_inference_and_annotations.rst @@ -16,7 +16,8 @@ static type of the value expression: Type inference is not used in dynamically typed functions (those without a function type annotation) — every local variable type defaults -to ``Any`` in such functions. ``Any`` is discussed later in more detail. +to :py:data:`~typing.Any` in such functions. ``Any`` +is discussed later in more detail. .. _explicit-var-types: @@ -32,9 +33,9 @@ variable type annotation: x: Union[int, str] = 1 -Without the type annotation, the type of ``x`` would be just ``int``. We +Without the type annotation, the type of ``x`` would be just :py:class:`int`. We use an annotation to give it a more general type ``Union[int, str]`` (this -type means that the value can be either an ``int`` or a ``str``). +type means that the value can be either an ``int`` or a :py:class:`str`). Mypy checks that the type of the initializer is compatible with the declared type. The following example is not valid, since the initializer is a floating point number, and this is incompatible with the declared @@ -65,7 +66,8 @@ possible with the comment syntax: The best way to think about this is that the type annotation sets the type of the variable, not the type of the expression. To force the - type of an expression you can use ``cast(, )``. + type of an expression you can use :py:func:`cast(\, \) + `. Explicit types for collections ****************************** @@ -114,8 +116,9 @@ assignment could result in non-int values stored in a list of ``int``: l.append('x') print(k[-1]) # Ouch; a string in List[int] -Other container types like ``Dict`` and ``Set`` behave similarly. We -will discuss how you can work around this in :ref:`variance`. +Other container types like :py:class:`~typing.Dict` and +:py:class:`~typing.Set` behave similarly. We will discuss how you can +work around this in :ref:`variance`. You can still run the above program; it prints ``x``. This illustrates the fact that static types are used during type checking, but they do From 15da89b23682ee4dbca57fcb469dfa87c37e63da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oleg=20H=C3=B6fling?= Date: Sun, 6 Oct 2019 16:07:31 +0200 Subject: [PATCH 2/2] scanned code examples with tokenize for syntax errors, corrected syntax in failing examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oleg Höfling --- docs/source/generics.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 847ff5e02bd9..2d2f5dd5b26f 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -124,7 +124,7 @@ non-generic. For example: KT = TypeVar('KT') VT = TypeVar('VT') - class MyMap(Mapping[KT, VT]]): # This is a generic subclass of Mapping + class MyMap(Mapping[KT, VT]): # This is a generic subclass of Mapping def __getitem__(self, k: KT) -> VT: ... # Implementations omitted def __iter__(self) -> Iterator[KT]: @@ -450,7 +450,7 @@ subtype of ``str``: class S(str): pass - ss = concat(S('foo'), S('bar'))) + ss = concat(S('foo'), S('bar')) You may expect that the type of ``ss`` is ``S``, but the type is actually ``str``: a subtype gets promoted to one of the valid values pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy