@@ -247,7 +247,7 @@ subscription to denote expected types for container elements.
247
247
def notify_by_email(employees: Sequence[Employee],
248
248
overrides: Mapping[str, str]) -> None: ...
249
249
250
- Generics can be parameterized by using a new factory available in typing
250
+ Generics can be parameterized by using a factory available in typing
251
251
called :class: `TypeVar `.
252
252
253
253
::
@@ -304,16 +304,16 @@ that ``LoggedVar[t]`` is valid as a type::
304
304
for var in vars:
305
305
var.set(0)
306
306
307
- A generic type can have any number of type variables, and type variables may
308
- be constrained ::
307
+ A generic type can have any number of type variables. All varieties of
308
+ :class: ` TypeVar ` are permissible as parameters for a generic type ::
309
309
310
- from typing import TypeVar, Generic
311
- ...
310
+ from typing import TypeVar, Generic, Sequence
312
311
313
- T = TypeVar('T')
312
+ T = TypeVar('T', contravariant=True)
313
+ B = TypeVar('B', bound=Sequence[bytes], covariant=True)
314
314
S = TypeVar('S', int, str)
315
315
316
- class StrangePair (Generic[T, S]):
316
+ class WeirdTrio (Generic[T, B , S]):
317
317
...
318
318
319
319
Each type variable argument to :class: `Generic ` must be distinct.
@@ -1084,7 +1084,8 @@ These are not used in annotations. They are building blocks for creating generic
1084
1084
Usage::
1085
1085
1086
1086
T = TypeVar('T') # Can be anything
1087
- A = TypeVar('A', str, bytes) # Must be str or bytes
1087
+ S = TypeVar('S', bound=str) # Can be any subtype of str
1088
+ A = TypeVar('A', str, bytes) # Must be exactly str or bytes
1088
1089
1089
1090
Type variables exist primarily for the benefit of static type
1090
1091
checkers. They serve as the parameters for generic types as well
@@ -1095,25 +1096,91 @@ These are not used in annotations. They are building blocks for creating generic
1095
1096
"""Return a list containing n references to x."""
1096
1097
return [x]*n
1097
1098
1098
- def longest(x: A, y: A) -> A:
1099
- """Return the longest of two strings."""
1100
- return x if len(x) >= len(y) else y
1101
1099
1102
- The latter example's signature is essentially the overloading
1103
- of ``(str, str) -> str `` and ``(bytes, bytes) -> bytes ``. Also note
1104
- that if the arguments are instances of some subclass of :class: `str `,
1105
- the return type is still plain :class: `str `.
1100
+ def print_capitalized(x: S) -> S:
1101
+ """Print x capitalized, and return x."""
1102
+ print(x.capitalize())
1103
+ return x
1104
+
1105
+
1106
+ def concatenate(x: A, y: A) -> A:
1107
+ """Add two strings or bytes objects together."""
1108
+ return x + y
1109
+
1110
+ Note that type variables can be *bound *, *constrained *, or neither, but
1111
+ cannot be both bound *and * constrained.
1112
+
1113
+ Constrained type variables and bound type variables have different
1114
+ semantics in several important ways. Using a *constrained * type variable
1115
+ means that the ``TypeVar `` can only ever be solved as being exactly one of
1116
+ the constraints given::
1117
+
1118
+ a = concatenate('one', 'two') # Ok, variable 'a' has type 'str'
1119
+ b = concatenate(StringSubclass('one'), StringSubclass('two')) # Inferred type of variable 'b' is 'str',
1120
+ # despite 'StringSubclass' being passed in
1121
+ c = concatenate('one', b'two') # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both
1122
+
1123
+ Using a *bound * type variable, however, means that the ``TypeVar `` will be
1124
+ solved using the most specific type possible::
1125
+
1126
+ print_capitalized('a string') # Ok, output has type 'str'
1127
+
1128
+ class StringSubclass(str):
1129
+ pass
1130
+
1131
+ print_capitalized(StringSubclass('another string')) # Ok, output has type 'StringSubclass'
1132
+ print_capitalized(45) # error: int is not a subtype of str
1133
+
1134
+ Type variables can be bound to concrete types, abstract types (ABCs or
1135
+ protocols), and even unions of types::
1136
+
1137
+ U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes
1138
+ V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
1139
+
1140
+ Bound type variables are particularly useful for annotating
1141
+ :func: `classmethods <classmethod> ` that serve as alternative constructors.
1142
+ In the following example (©
1143
+ `Raymond Hettinger <https://www.youtube.com/watch?v=HTLu2DFOdTg >`_), the
1144
+ type variable ``C `` is bound to the ``Circle `` class through the use of a
1145
+ forward reference. Using this type variable to annotate the
1146
+ ``with_circumference `` classmethod, rather than hardcoding the return type
1147
+ as ``Circle ``, means that a type checker can correctly infer the return
1148
+ type even if the method is called on a subclass::
1149
+
1150
+ import math
1151
+
1152
+ C = TypeVar('C', bound='Circle')
1153
+
1154
+ class Circle:
1155
+ """An abstract circle"""
1156
+
1157
+ def __init__(self, radius: float) -> None:
1158
+ self.radius = radius
1159
+
1160
+ # Use a type variable to show that the return type
1161
+ # will always be an instance of whatever `cls` is
1162
+ @classmethod
1163
+ def with_circumference(cls: type[C], circumference: float) -> C:
1164
+ """Create a circle with the specified circumference"""
1165
+ radius = circumference / (math.pi * 2)
1166
+ return cls(radius)
1167
+
1168
+
1169
+ class Tire(Circle):
1170
+ """A specialised circle (made out of rubber)"""
1171
+
1172
+ MATERIAL = 'rubber'
1173
+
1174
+
1175
+ c = Circle.with_circumference(3) # Ok, variable 'c' has type 'Circle'
1176
+ t = Tire.with_circumference(4) # Ok, variable 't' has type 'Tire' (not 'Circle')
1106
1177
1107
1178
At runtime, ``isinstance(x, T) `` will raise :exc: `TypeError `. In general,
1108
1179
:func: `isinstance ` and :func: `issubclass ` should not be used with types.
1109
1180
1110
1181
Type variables may be marked covariant or contravariant by passing
1111
1182
``covariant=True `` or ``contravariant=True ``. See :pep: `484 ` for more
1112
- details. By default type variables are invariant. Alternatively,
1113
- a type variable may specify an upper bound using ``bound=<type> ``.
1114
- This means that an actual type substituted (explicitly or implicitly)
1115
- for the type variable must be a subclass of the boundary type,
1116
- see :pep: `484 `.
1183
+ details. By default, type variables are invariant.
1117
1184
1118
1185
.. class :: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
1119
1186
@@ -1215,7 +1282,7 @@ These are not used in annotations. They are building blocks for creating generic
1215
1282
1216
1283
.. data :: AnyStr
1217
1284
1218
- ``AnyStr `` is a type variable defined as
1285
+ ``AnyStr `` is a :class: ` constrained type variable <TypeVar> ` defined as
1219
1286
``AnyStr = TypeVar('AnyStr', str, bytes) ``.
1220
1287
1221
1288
It is meant to be used for functions that may accept any kind of string
0 commit comments