File: features.rst

package info (click to toggle)
python-typeguard 4.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 544 kB
  • sloc: python: 6,271; makefile: 5
file content (225 lines) | stat: -rw-r--r-- 8,514 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
Features
=========

.. py:currentmodule:: typeguard

What does Typeguard check?
--------------------------

The following type checks are implemented in Typeguard:

* Types of arguments passed to instrumented functions
* Types of values returned from instrumented functions
* Types of values yielded from instrumented generator functions
* Types of values sent to instrumented generator functions
* Types of values assigned to local variables within instrumented functions

What does Typeguard NOT check?
------------------------------

The following type checks are not yet supported in Typeguard:

* Types of values assigned to class or instance variables
* Types of values assigned to global or nonlocal variables
* Stubs defined with :func:`@overload <typing.overload>` (the implementation is checked
  if instrumented)
* ``yield from`` statements in generator functions
* ``ParamSpec`` and ``Concatenate`` are currently ignored
* Types where they are shadowed by arguments with the same name (e.g.
  ``def foo(x: type, type: str): ...``)

Other limitations
-----------------

Local references to nested classes
++++++++++++++++++++++++++++++++++

Forward references from methods pointing to non-local nested classes cannot currently be
resolved::

    class Outer:
        class Inner:
            pass

        # Cannot be resolved as the name is no longer available
        def method(self) -> "Inner":
            return Outer.Inner()

This shortcoming may be resolved in a future release.

Using :func:`@typechecked <typechecked>` on top of other decorators
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

As :func:`@typechecked <typechecked>` works by recompiling the target function with
instrumentation added, it needs to replace all the references to the original function
with the new one. This could be impossible when it's placed on top of another decorator
that wraps the original function. It has no way of telling that other decorator that the
target function should be switched to a new one. To work around this limitation, either
place :func:`@typechecked <typechecked>` at the bottom of the decorator stack, or use
the import hook instead.

Protocol checking
+++++++++++++++++

As of version 4.3.0, Typeguard can check instances and classes against Protocols,
regardless of whether they were annotated with
:func:`@runtime_checkable <typing.runtime_checkable>`.

The only current limitation is that argument annotations are not checked for
compatibility, however this should be covered by static type checkers pretty well.

Special considerations for ``if TYPE_CHECKING:``
------------------------------------------------

Both the import hook and :func:`@typechecked <typechecked>` avoid checking against
anything imported in a module-level ``if TYPE_CHECKING:`` (or
``if typing.TYPE_CHECKING:``) block, since those types will not be available at run
time. Therefore, no errors or warnings are emitted for such annotations, even when they
would normally not be found.

Support for generator functions
-------------------------------

For generator functions, the checks applied depend on the function's return annotation.
For example, the following function gets its yield, send and return values type
checked::

    from collections.abc import Generator

    def my_generator() -> Generator[int, str, bool]:
        a = yield 6
        return True

In contrast, the following generator function only gets its yield value checked::

    from collections.abc import Iterator

    def my_generator() -> Iterator[int]:
        a = yield 6
        return True

Asynchronous generators work just the same way, except they don't support returning
values other than ``None``, so the annotation only has two items::

    from collections.abc import AsyncGenerator

    async def my_generator() -> AsyncGenerator[int, str]:
        a = yield 6

Overall, the following type annotations will work for generator function type checking:

* :class:`typing.Generator`
* :class:`collections.abc.Generator`
* :class:`typing.Iterator`
* :class:`collections.abc.Iterator`
* :class:`typing.Iterable`
* :class:`collections.abc.Iterable`
* :class:`typing.AsyncIterator`
* :class:`collections.abc.AsyncIterator`
* :class:`typing.AsyncIterable`
* :class:`collections.abc.AsyncIterable`
* :class:`typing.AsyncGenerator`
* :class:`collections.abc.AsyncGenerator`

Support for PEP 604 unions on Pythons older than 3.10
-----------------------------------------------------

The :pep:`604` ``X | Y`` notation was introduced in Python 3.10, but it can be used with
older Python versions in modules where ``from __future__ import annotations`` is
present. Typeguard contains a special parser that lets it convert these to older
:class:`~typing.Union` annotations internally.

Support for generic built-in collection types on Pythons older than 3.9
-----------------------------------------------------------------------

The built-in collection types (:class:`list`, :class:`tuple`, :class:`dict`,
:class:`set` and :class:`frozenset`) gained support for generics in Python 3.9.
For earlier Python versions, Typeguard provides a way to work with such annotations by
substituting them with the equivalent :mod:`typing` types. The only requirement for this
to work is the use of ``from __future__ import annotations`` in all such modules.

Support for mock objects
------------------------

Typeguard handles the :class:`unittest.mock.Mock` class (and its subclasses) specially,
bypassing any type checks when encountering instances of these classes. Note that any
"spec" class passed to the mock object is currently not respected.

Supported standard library annotations
--------------------------------------

The following types from the standard library have specialized support:

.. list-table::
   :header-rows: 1

   * - Type(s)
     - Notes
   * - :class:`typing.Any`
     - Any type passes type checks against this annotation. Inheriting from ``Any``
       (:class:`typing.Any` on Python 3.11+, or ``typing.extensions.Any``) will pass any
       type check
   * - :class:`typing.Annotated`
     - Original annotation is unwrapped and typechecked normally
   * - :class:`BinaryIO`
     - Specialized instance checks are performed
   * - | :class:`typing.Callable`
       | :class:`collections.abc.Callable`
     - Argument count is checked but types are not (yet)
   * - | :class:`dict`
       | :class:`typing.Dict`
     - Keys and values are typechecked
   * - :class:`typing.IO`
     - Specialized instance checks are performed
   * - | :class:`list`
       | :class:`typing.List`
     - Contents are typechecked
   * - :class:`typing.Literal`
     -
   * - :class:`typing.LiteralString`
     - Checked as :class:`str`
   * - | :class:`typing.Mapping`
       | :class:`typing.MutableMapping`
       | :class:`collections.abc.Mapping`
       | :class:`collections.abc.MutableMapping`
     - Keys and values are typechecked
   * - :class:`typing.NamedTuple`
     - Field values are typechecked
   * - | :class:`typing.Never`
       | :class:`typing.NoReturn`
     - Supported in argument and return type annotations
   * - :class:`typing.Protocol`
     - Run-time protocols are checked with :func:`isinstance`, others are ignored
   * - :class:`typing.Self`
     -
   * - | :class:`set`
       | :class:`frozenset`
       | :class:`typing.Set`
       | :class:`typing.AbstractSet`
     - Contents are typechecked
   * - | :class:`typing.Sequence`
       | :class:`collections.abc.Sequence`
     - Contents are typechecked
   * - :class:`typing.TextIO`
     - Specialized instance checks are performed
   * - | :class:`tuple`
       | :class:`typing.Tuple`
     - Contents are typechecked
   * - | :class:`type`
       | :class:`typing.Type`
     -
   * - :class:`typing.TypeGuard`
     - Checked as :class:`bool`
   * - :class:`typing.TypedDict`
     - Contents are typechecked; On Python 3.8 and earlier, ``total`` from superclasses
       is not respected (see `#101`_ for more information); On Python 3.9.0, false
       positives can happen when constructing :class:`typing.TypedDict` classes using
       old-style syntax (see `issue 42059`_)
   * - :class:`typing.TypeVar`
     - Constraints and bound types are typechecked
   * - :class:`typing.Union`
     - :pep:`604` unions are supported on all Python versions when
       ``from __future__ import annotations`` is used

.. _#101: https://github.com/agronholm/typeguard/issues/101
.. _issue 42059: https://bugs.python.org/issue42059