@@ -23,8 +23,8 @@ Abstract
23
23
========
24
24
25
25
This PEP proposes the addition of intersection types.
26
- They are denoted as `A & B ` or `Intersection[A, B] ` and they describe values that have both types A
27
- and B.
26
+ They are denoted as `` A & B `` or `` Intersection[A, B] `` and they describe values that have both
27
+ types A and B.
28
28
Intersection types are a complementary concept to union types introduced in PEP-484.
29
29
30
30
The primary use cases for intersection types include:
@@ -107,8 +107,8 @@ For example,
107
107
# ^^^^^^^^ Cannot access member "dispatch" for type "AccessMixin"
108
108
# Member "dispatch" is unknown
109
109
110
- The `LoginRequiredMixin ` is designed to be used with the `View ` base class which defines the
111
- `dispatch ` method.
110
+ The `` LoginRequiredMixin `` is designed to be used with the `` View ` ` base class which defines the
111
+ `` dispatch ` ` method.
112
112
Intersection types allow expressing that directly via
113
113
114
114
::
@@ -171,28 +171,28 @@ For example, instead of
171
171
from collections.abc import Container, Iterable
172
172
from typing import Protocol, TypeVar
173
173
174
- T = TypeVar(“T” )
174
+ T = TypeVar("T" )
175
175
176
176
class IterableContainer(Iterable[T], Container[T], Protocol):
177
177
...
178
178
179
179
def assert_in(target: T, it: IterableContainer[T]) -> bool:
180
180
if item not in it:
181
- raise AssertionError(f“ {target} does not occur in {‘, ‘ .join(map(str, it))}” )
181
+ raise AssertionError(f" {target} does not occur in {', ' .join(map(str, it))}" )
182
182
183
- users could drop the `IterableContainer ` class and instead annotate `it ` as
184
- `Iterable[T] & Container[T] `.
183
+ users could drop the `` IterableContainer `` class and instead annotate `` it ` ` as
184
+ `` Iterable[T] & Container[T] ` `.
185
185
186
186
Source: https://github.com/python/typing/issues/18
187
187
188
188
189
189
Self
190
190
----
191
191
192
- PEP-673 introduced `Self `, a simple and intuitive way to annotate methods that return an instance
192
+ PEP-673 introduced `` Self ` `, a simple and intuitive way to annotate methods that return an instance
193
193
of their class.
194
- If methods or attributes of intersection types return `Self `-typed values, they should be inferred
195
- as intersection types.
194
+ If methods or attributes of intersection types return `` Self `` -typed values, they should be
195
+ inferred as intersection types.
196
196
For example,
197
197
198
198
::
@@ -212,9 +212,9 @@ For example,
212
212
TypedDict
213
213
---------
214
214
215
- PEP-589 introduced `TypedDict `, a way to define precise types for dictionaries with a fixed set of
216
- keys.
217
- Multiple `TypedDict ` types could be merged into a single `TypedDict ` type through subclassing.
215
+ PEP-589 introduced `` TypedDict `` , a way to define precise types for dictionaries with a fixed set
216
+ of keys.
217
+ Multiple `` TypedDict `` types could be merged into a single `` TypedDict ` ` type through subclassing.
218
218
For example,
219
219
220
220
::
@@ -228,7 +228,7 @@ For example,
228
228
class BookBasedMovie(Movie):
229
229
based_on: str
230
230
231
- With intersection types, `TypedDict ` types no longer need to be inherited, and can be combined in
231
+ With intersection types, `` TypedDict ` ` types no longer need to be inherited, and can be combined in
232
232
ad-hoc way::
233
233
234
234
class BookBased(TypedDict):
@@ -241,29 +241,29 @@ Type narrowing in control flow
241
241
------------------------------
242
242
243
243
Type checkers employ type narrowing for certain conditionally executed code as described in PEP-647.
244
- An `isinstance ` check, for example, can be used to narrow the static type of its first argument
244
+ An `` isinstance ` ` check, for example, can be used to narrow the static type of its first argument
245
245
246
246
::
247
247
248
248
x: A
249
249
if isinstance(x, B):
250
250
f(x)
251
251
252
- In the call to `f ` , `x ` is known to have both static types `A ` and `B `.
253
- If `B ` is a subtype of `A `
254
- then that static type is the same as `B `.
255
- But of course, `A ` and `B ` do not necessarily have any
252
+ In the call to `` f `` , `` x `` is known to have both static types `` A `` and `` B ` `.
253
+ If `` B `` is a subtype of `` A ` `
254
+ then that static type is the same as `` B ` `.
255
+ But of course, `` A `` and `` B ` ` do not necessarily have any
256
256
subtype relationship.
257
- With intersection types the static type of `x ` can be exactly represented as `A & B ` and the
258
- programmer can write the type annotation for `f ` accordingly:
257
+ With intersection types the static type of `` x `` can be exactly represented as `` A & B ` ` and the
258
+ programmer can write the type annotation for `` f ` ` accordingly:
259
259
260
260
::
261
261
262
262
def f(x: A & B): ...
263
263
264
264
Type checkers actually do implement some form of intersection types internally to support type
265
265
narrowing.
266
- This can be observed using a facility like `reveal_type ` in place of the call to `f `
266
+ This can be observed using a facility like `` reveal_type `` in place of the call to `` f ` `
267
267
above.
268
268
For instance, mypy will display `<subclass of "A" and "B"> ` and pyright will display
269
269
`<subclass of A and B> `.
@@ -276,7 +276,7 @@ including more complicated cases such as:
276
276
if isinstance(y, C):
277
277
g(y)
278
278
279
- At the call to `g ` , `y ` has the static type `Union[A, B] & C `.
279
+ At the call to `` g `` , `` y `` has the static type `` Union[A, B] & C ` `.
280
280
(Both mypy and pyright
281
281
"distribute" the union over the intersection, displaying `Union[<subclass of "A" and "C">, <subclass
282
282
of "B" and "C">] ` and `<subclass of A and C> | <subclass of B and C> ` respectively.)
@@ -312,39 +312,39 @@ Intuition based on sets
312
312
313
313
A simple way to understand Python static types is to think of them as describing sets of runtime
314
314
objects.
315
- The type `str ` describes the set of all Python strings.
316
- Likewise if `C ` is a class then the type `C ` describes the set of all instances of `C ` including
317
- instances of its subclasses.
315
+ The type `` str ` ` describes the set of all Python strings.
316
+ Likewise if `` C `` is a class then the type `` C `` describes the set of all instances of `` C ``
317
+ including instances of its subclasses.
318
318
A type annotation on a variable declares that at runtime the value of the variable will be an
319
319
element of the set that the annotation describes.
320
320
(Which is not necessarily true because the type system allows conversions both to and from the type
321
- `Any ` without any runtime checks.)
321
+ `` Any ` ` without any runtime checks.)
322
322
323
- The rules for subtyping sketched in PEP-483 are intended to ensure that if a type `B ` is a subtype
324
- of a type `A ` , then the set of values described by `B ` is always a subset of the set of values
325
- described by `A `.
323
+ The rules for subtyping sketched in PEP-483 are intended to ensure that if a type `` B ` ` is a subtype
324
+ of a type `` A `` , then the set of values described by `` B ` ` is always a subset of the set of values
325
+ described by `` A ` `.
326
326
327
327
Union types describe the union of the sets of values of their components.
328
- For example, `Union[str,C] ` describes the set containing all Python strings and all instances of ` C `
329
- including instances of its subclasses.
330
- A type annotation `Union[str,C] ` on a variable declares that at runtime the value of the variable
331
- will either be a string or an instance of `C ` (or possibly both).
328
+ For example, `` Union[str,C] `` describes the set containing all Python strings and all instances of
329
+ `` C `` including instances of its subclasses.
330
+ A type annotation `` Union[str,C] ` ` on a variable declares that at runtime the value of the variable
331
+ will either be a string or an instance of `` C ` ` (or possibly both).
332
332
This is why the operations that a typechecker allows on such a value are only the operations that
333
- are allowed on both strings and instances of `C `.
333
+ are allowed on both strings and instances of `` C ` `.
334
334
The only safe things to do with such a value are the things that are allowed for all components of
335
335
the union, that is the _intersection_ of those things to do.
336
336
337
337
Similarly, intersection types describe the intersection of the sets of values of their components.
338
- For example, `str & C ` describes the set containing all Python objects that are both
339
- elements of the set of strings and elements of the set of instances of `C ` including instances of
338
+ For example, `` str & C `` describes the set containing all Python objects that are both elements
339
+ of the set of strings and elements of the set of instances of `` C ` ` including instances of
340
340
its subclasses.
341
- Notice that this does not require that `C ` is a subclass of `str ` or vice versa.
342
- There may be classes that are themselves subclasses of both `str ` and `C ` and so their instances
343
- will be in the intersection.
344
- There may even be several such subclasses of `str ` and `C ` that are not necessarily subclass-related
345
- to each other.
341
+ Notice that this does not require that `` C `` is a subclass of `` str ` ` or vice versa.
342
+ There may be classes that are themselves subclasses of both `` str `` and `` C `` and so their
343
+ instances will be in the intersection.
344
+ There may even be several such subclasses of `` str `` and `` C `` that are not necessarily
345
+ subclass-related to each other.
346
346
And the intersection may be empty if there are no Python objects that are both in the set of strings
347
- and the set of instances of `C `.
347
+ and the set of instances of `` C ` `.
348
348
349
349
The operations that a typechecker allows on an intersection type are the operations that are allowed
350
ADA8
td>350
on any component.
@@ -358,13 +358,13 @@ An intersection type itself is a subtype of each of its components, because it d
358
358
the sets described by each component.
359
359
360
360
This set-based intuition extends to other types besides class instances.
361
- For example, we can form an intersection of a union type like `(A | B) & C `.
362
- The first component of the intersection is the set containing all instances of `A ` and all instances
363
- of `B `.
364
- The intersection with the set containing all instances of `C ` describes all the Python objects that
365
- are both instances of the union (either `A ` or `B ` ) and also instances of `C `.
361
+ For example, we can form an intersection of a union type like `` (A | B) & C ` `.
362
+ The first component of the intersection is the set containing all instances of `` A ` ` and all instances
363
+ of `` B ` `.
364
+ The intersection with the set containing all instances of `` C ` ` describes all the Python objects that
365
+ are both instances of the union (either `` A `` or `` B `` ) and also instances of `` C ` `.
366
366
This set-based intuition justifies distributing the union over the intersection (as shown by mypy
367
- and pyright above) and recognizing that it describes the same set of objects as `A & C | B & C `.
367
+ and pyright above) and recognizing that it describes the same set of objects as `` A & C | B & C ` `.
368
368
369
369
370
370
Specification
0 commit comments