Skip to content

Commit 81b425d

Browse files
bpo-46769: Improve documentation for typing.TypeVar (pythonGH-31712)
Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent d56a237 commit 81b425d

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

Doc/library/typing.rst

+55-21
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ subscription to denote expected types for container elements.
249249
def notify_by_email(employees: Sequence[Employee],
250250
overrides: Mapping[str, str]) -> None: ...
251251

252-
Generics can be parameterized by using a new factory available in typing
252+
Generics can be parameterized by using a factory available in typing
253253
called :class:`TypeVar`.
254254

255255
::
@@ -306,16 +306,16 @@ that ``LoggedVar[t]`` is valid as a type::
306306
for var in vars:
307307
var.set(0)
308308

309-
A generic type can have any number of type variables, and type variables may
310-
be constrained::
309+
A generic type can have any number of type variables. All varieties of
310+
:class:`TypeVar` are permissible as parameters for a generic type::
311311

312-
from typing import TypeVar, Generic
313-
...
312+
from typing import TypeVar, Generic, Sequence
314313

315-
T = TypeVar('T')
314+
T = TypeVar('T', contravariant=True)
315+
B = TypeVar('B', bound=Sequence[bytes], covariant=True)
316316
S = TypeVar('S', int, str)
317317

318-
class StrangePair(Generic[T, S]):
318+
class WeirdTrio(Generic[T, B, S]):
319319
...
320320

321321
Each type variable argument to :class:`Generic` must be distinct.
@@ -1165,7 +1165,8 @@ These are not used in annotations. They are building blocks for creating generic
11651165
Usage::
11661166

11671167
T = TypeVar('T') # Can be anything
1168-
A = TypeVar('A', str, bytes) # Must be str or bytes
1168+
S = TypeVar('S', bound=str) # Can be any subtype of str
1169+
A = TypeVar('A', str, bytes) # Must be exactly str or bytes
11691170

11701171
Type variables exist primarily for the benefit of static type
11711172
checkers. They serve as the parameters for generic types as well
@@ -1176,25 +1177,58 @@ These are not used in annotations. They are building blocks for creating generic
11761177
"""Return a list containing n references to x."""
11771178
return [x]*n
11781179

1179-
def longest(x: A, y: A) -> A:
1180-
"""Return the longest of two strings."""
1181-
return x if len(x) >= len(y) else y
11821180

1183-
The latter example's signature is essentially the overloading
1184-
of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note
1185-
that if the arguments are instances of some subclass of :class:`str`,
1186-
the return type is still plain :class:`str`.
1181+
def print_capitalized(x: S) -> S:
1182+
"""Print x capitalized, and return x."""
1183+
print(x.capitalize())
1184+
return x
1185+
1186+
1187+
def concatenate(x: A, y: A) -> A:
1188+
"""Add two strings or bytes objects together."""
1189+
return x + y
1190+
1191+
Note that type variables can be *bound*, *constrained*, or neither, but
1192+
cannot be both bound *and* constrained.
1193+
1194+
Bound type variables and constrained type variables have different
1195+
semantics in several important ways. Using a *bound* type variable means
1196+
that the ``TypeVar`` will be solved using the most specific type possible::
1197+
1198+
x = print_capitalized('a string')
1199+
reveal_type(x) # revealed type is str
1200+
1201+
class StringSubclass(str):
1202+
pass
1203+
1204+
y = print_capitalized(StringSubclass('another string'))
1205+
reveal_type(y) # revealed type is StringSubclass
1206+
1207+
z = print_capitalized(45) # error: int is not a subtype of str
1208+
1209+
Type variables can be bound to concrete types, abstract types (ABCs or
1210+
protocols), and even unions of types::
1211+
1212+
U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes
1213+
V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
1214+
1215+
Using a *constrained* type variable, however, means that the ``TypeVar``
1216+
can only ever be solved as being exactly one of the constraints given::
1217+
1218+
a = concatenate('one', 'two')
1219+
reveal_type(a) # revealed type is str
1220+
1221+
b = concatenate(StringSubclass('one'), StringSubclass('two'))
1222+
reveal_type(b) # revealed type is str, despite StringSubclass being passed in
1223+
1224+
c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both
11871225

11881226
At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general,
11891227
:func:`isinstance` and :func:`issubclass` should not be used with types.
11901228

11911229
Type variables may be marked covariant or contravariant by passing
11921230
``covariant=True`` or ``contravariant=True``. See :pep:`484` for more
1193-
details. By default type variables are invariant. Alternatively,
1194-
a type variable may specify an upper bound using ``bound=<type>``.
1195-
This means that an actual type substituted (explicitly or implicitly)
1196-
for the type variable must be a subclass of the boundary type,
1197-
see :pep:`484`.
1231+
details. By default, type variables are invariant.
11981232

11991233
.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
12001234

@@ -1296,7 +1330,7 @@ These are not used in annotations. They are building blocks for creating generic
12961330

12971331
.. data:: AnyStr
12981332

1299-
``AnyStr`` is a type variable defined as
1333+
``AnyStr`` is a :class:`constrained type variable <TypeVar>` defined as
13001334
``AnyStr = TypeVar('AnyStr', str, bytes)``.
13011335

13021336
It is meant to be used for functions that may accept any kind of string

0 commit comments

Comments
 (0)