Skip to content

Commit a6eeccf

Browse files
carljmJelleZijlstraAlexWaygood
authored
new "type system concepts" section (#1743)
Co-authored-by: Jelle Zijlstra <[email protected]> Co-authored-by: Alex Waygood <[email protected]>
1 parent b2558aa commit a6eeccf

17 files changed

+835
-340
lines changed

docs/spec/annotations.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@ hinting is used by filling function annotation slots with classes::
1616
This states that the expected type of the ``name`` argument is
1717
``str``. Analogically, the expected return type is ``str``.
1818

19-
Expressions whose type is a subtype of a specific argument type are
20-
also accepted for that argument.
19+
Expressions whose type is :term:`assignable` to a specific argument type are
20+
also accepted for that argument. Similarly, an expression whose type is
21+
assignable to the annotated return type can be returned from the function.
2122

2223
.. _`missing-annotations`:
2324

24-
Any function without annotations should be treated as having the most
25-
general type possible, or ignored, by any type checker.
25+
Any function without annotations can be treated as having :ref:`Any`
26+
annotations on all arguments and the return type. Type checkers may also
27+
optionally infer more precise types for missing annotations.
28+
29+
Type checkers may choose to entirely ignore (not type check) the bodies of
30+
functions with no annotations, but this behavior is not required.
2631

2732
It is recommended but not required that checked functions have
2833
annotations for all arguments and the return type. For a checked

docs/spec/callables.rst

Lines changed: 81 additions & 81 deletions
Large diffs are not rendered by default.

docs/spec/class-compat.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.. _`class-compat`:
22

3-
Class type compatibility
3+
Class type assignability
44
========================
55

66
.. _`classvar`:
@@ -97,8 +97,9 @@ annotated in ``__init__`` or other methods, rather than in the class::
9797
(Originally specified by :pep:`698`.)
9898

9999
When type checkers encounter a method decorated with ``@typing.override`` they
100-
should treat it as a type error unless that method is overriding a compatible
101-
method or attribute in some ancestor class.
100+
should treat it as a type error unless that method is overriding a method or
101+
attribute in some ancestor class, and the type of the overriding method is
102+
:term:`assignable` to the type of the overridden method.
102103

103104

104105
.. code-block:: python

docs/spec/concepts.rst

Lines changed: 377 additions & 8 deletions
Large diffs are not rendered by default.

docs/spec/constructors.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ unrelated class.
105105

106106
If the evaluated return type of ``__new__`` is not the class being constructed
107107
(or a subclass thereof), a type checker should assume that the ``__init__``
108-
method will not be called. This is consistent with the runtime behavior of
109-
the ``type.__call__`` method. If the ``__new__`` method return type is
110-
a union with one or more subtypes that are not instances of the class being
111-
constructed (or a subclass thereof), a type checker should likewise assume that
112-
the ``__init__`` method will not be called.
108+
method will not be called. This is consistent with the runtime behavior of the
109+
``type.__call__`` method. If the ``__new__`` method return type is a union with
110+
one or more members that are not the class being constructed (or a subclass
111+
thereof), a type checker should likewise assume that the ``__init__`` method
112+
will not be called.
113113

114114
::
115115

@@ -337,7 +337,7 @@ Consistency of ``__new__`` and ``__init__``
337337
-------------------------------------------
338338

339339
Type checkers may optionally validate that the ``__new__`` and ``__init__``
340-
methods for a class have consistent signatures.
340+
methods for a class have :term:`consistent` signatures.
341341

342342
::
343343

@@ -353,7 +353,8 @@ methods for a class have consistent signatures.
353353
Converting a Constructor to Callable
354354
------------------------------------
355355

356-
Class objects are callable, which means they are compatible with callable types.
356+
Class objects are callable, which means the type of a class object can be
357+
:term:`assignable` to a callable type.
357358

358359
::
359360

docs/spec/directives.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ At runtime a cast always returns the
8686
expression unchanged -- it does not check the type, and it does not
8787
convert or coerce the value.
8888

89-
Casts differ from type comments (see the previous section). When using
90-
a type comment, the type checker should still verify that the inferred
91-
type is consistent with the stated type. When using a cast, the type
92-
checker should blindly believe the programmer. Also, casts can be used
93-
in expressions, while type comments only apply to assignments.
94-
9589
.. _`if-type-checking`:
9690

9791
``TYPE_CHECKING``

docs/spec/enums.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ literal values during type narrowing and exhaustion detection::
350350

351351

352352
Likewise, a type checker should treat a complete union of all literal members
353-
as compatible with the enum type::
353+
as :term:`equivalent` to the enum type::
354354

355355
class Answer(Enum):
356356
Yes = 1

docs/spec/generics.rst

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -474,12 +474,12 @@ classes without a metaclass conflict.
474474
Type variables with an upper bound
475475
----------------------------------
476476

477-
A type variable may specify an upper bound using ``bound=<type>`` (when
478-
using the ``TypeVar`` constructor) or using ``: <type>`` (when using the native
479-
syntax for generics). The bound itself cannot be parameterized by type variables.
480-
This means that an
481-
actual type substituted (explicitly or implicitly) for the type variable must
482-
be a subtype of the boundary type. Example::
477+
A type variable may specify an upper bound using ``bound=<type>`` (when using
478+
the ``TypeVar`` constructor) or using ``: <type>`` (when using the native
479+
syntax for generics). The bound itself cannot be parameterized by type
480+
variables. This means that an actual type substituted (explicitly or
481+
implicitly) for the type variable must be :term:`assignable` to the bound.
482+
Example::
483483

484484
from typing import TypeVar
485485
from collections.abc import Sized
@@ -496,11 +496,10 @@ be a subtype of the boundary type. Example::
496496
longer({1}, {1, 2}) # ok, return type set[int]
497497
longer([1], {1, 2}) # ok, return type a supertype of list[int] and set[int]
498498

499-
An upper bound cannot be combined with type constraints (as used in
500-
``AnyStr``, see the example earlier); type constraints cause the
501-
inferred type to be *exactly* one of the constraint types, while an
502-
upper bound just requires that the actual type is a subtype of the
503-
boundary type.
499+
An upper bound cannot be combined with type constraints (as used in ``AnyStr``,
500+
see the example earlier); type constraints cause the inferred type to be
501+
*exactly* one of the constraint types, while an upper bound just requires that
502+
the actual type is :term:`assignable` to the bound.
504503

505504
.. _`variance`:
506505

@@ -523,13 +522,12 @@ introduction to these concepts can be found on `Wikipedia
523522
<https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29>`_ and in :pep:`483`; here we just show how to control
524523
a type checker's behavior.
525524

526-
By default generic types declared using the old ``TypeVar`` syntax
527-
are considered *invariant* in all type variables,
528-
which means that values for variables annotated with types like
529-
``list[Employee]`` must exactly match the type annotation -- no subclasses or
530-
superclasses of the type parameter (in this example ``Employee``) are
531-
allowed. See below for the behavior when using the built-in generic syntax
532-
in Python 3.12 and higher.
525+
By default generic types declared using the old ``TypeVar`` syntax are
526+
considered *invariant* in all type variables, which means that e.g.
527+
``list[Manager]`` is neither a supertype nor a subtype of ``list[Employee]``.
528+
529+
See below for the behavior when using the built-in generic syntax in Python
530+
3.12 and higher.
533531

534532
To facilitate the declaration of container types where covariant or
535533
contravariant type checking is acceptable, type variables accept keyword
@@ -1926,7 +1924,7 @@ Using a type parameter from an outer scope as a default is not supported.
19261924
Bound Rules
19271925
^^^^^^^^^^^
19281926

1929-
``T1``'s bound must be a subtype of ``T2``'s bound.
1927+
``T1``'s bound must be :term:`assignable` to ``T2``'s bound.
19301928

19311929
::
19321930

@@ -2022,8 +2020,8 @@ normal subscription rules, non-overridden defaults should be substituted.
20222020
Using ``bound`` and ``default``
20232021
"""""""""""""""""""""""""""""""
20242022

2025-
If both ``bound`` and ``default`` are passed, ``default`` must be a
2026-
subtype of ``bound``. If not, the type checker should generate an
2023+
If both ``bound`` and ``default`` are passed, ``default`` must be
2024+
:term:`assignable` to ``bound``. If not, the type checker should generate an
20272025
error.
20282026

20292027
::
@@ -2268,7 +2266,8 @@ Use in Attribute Annotations
22682266
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22692267

22702268
Another use for ``Self`` is to annotate attributes. One example is where we
2271-
have a ``LinkedList`` whose elements must be subclasses of the current class.
2269+
have a ``LinkedList`` whose elements must be :term:`assignable` to the current
2270+
class.
22722271

22732272
::
22742273

@@ -2298,8 +2297,8 @@ constructions with subclasses:
22982297
def ordinal_value(self) -> str:
22992298
return as_ordinal(self.value)
23002299

2301-
# Should not be OK because LinkedList[int] is not a subclass of
2302-
# OrdinalLinkedList, # but the type checker allows it.
2300+
# Should not be OK because LinkedList[int] is not assignable to
2301+
# OrdinalLinkedList, but the type checker allows it.
23032302
xs = OrdinalLinkedList(value=1, next=LinkedList[int](value=2))
23042303

23052304
if xs.next:
@@ -2469,11 +2468,11 @@ See :pep:`PEP 544
24692468
<544#self-types-in-protocols>` for
24702469
details on the behavior of TypeVars bound to protocols.
24712470

2472-
Checking a class for compatibility with a protocol: If a protocol uses
2473-
``Self`` in methods or attribute annotations, then a class ``Foo`` is
2474-
considered compatible with the protocol if its corresponding methods and
2475-
attribute annotations use either ``Self`` or ``Foo`` or any of ``Foo``’s
2476-
subclasses. See the examples below:
2471+
Checking a class for assignability to a protocol: If a protocol uses ``Self``
2472+
in methods or attribute annotations, then a class ``Foo`` is :term:`assignable`
2473+
to the protocol if its corresponding methods and attribute annotations use
2474+
either ``Self`` or ``Foo`` or any of ``Foo``’s subclasses. See the examples
2475+
below:
24772476

24782477
::
24792478

@@ -2705,16 +2704,15 @@ by the ``TypeVar`` constructor call. No further inference is needed.
27052704
3. Create two specialized versions of the class. We'll refer to these as
27062705
``upper`` and ``lower`` specializations. In both of these specializations,
27072706
replace all type parameters other than the one being inferred by a dummy type
2708-
instance (a concrete anonymous class that is type compatible with itself and
2709-
assumed to meet the bounds or constraints of the type parameter). In
2710-
the ``upper`` specialized class, specialize the target type parameter with
2711-
an ``object`` instance. This specialization ignores the type parameter's
2712-
upper bound or constraints. In the ``lower`` specialized class, specialize
2713-
the target type parameter with itself (i.e. the corresponding type argument
2714-
is the type parameter itself).
2715-
2716-
4. Determine whether ``lower`` can be assigned to ``upper`` using normal type
2717-
compatibility rules. If so, the target type parameter is covariant. If not,
2707+
instance (a concrete anonymous class that is assumed to meet the bounds or
2708+
constraints of the type parameter). In the ``upper`` specialized class,
2709+
specialize the target type parameter with an ``object`` instance. This
2710+
specialization ignores the type parameter's upper bound or constraints. In the
2711+
``lower`` specialized class, specialize the target type parameter with itself
2712+
(i.e. the corresponding type argument is the type parameter itself).
2713+
2714+
4. Determine whether ``lower`` can be assigned to ``upper`` using normal
2715+
assignability rules. If so, the target type parameter is covariant. If not,
27182716
determine whether ``upper`` can be assigned to ``lower``. If so, the target
27192717
type parameter is contravariant. If neither of these combinations are
27202718
assignable, the target type parameter is invariant.
@@ -2737,9 +2735,8 @@ To determine the variance of ``T1``, we specialize ``ClassA`` as follows:
27372735
upper = ClassA[object, Dummy, Dummy]
27382736
lower = ClassA[T1, Dummy, Dummy]
27392737

2740-
We find that ``upper`` is not assignable to ``lower`` using normal type
2741-
compatibility rules defined in :pep:`484`. Likewise, ``lower`` is not assignable
2742-
to ``upper``, so we conclude that ``T1`` is invariant.
2738+
We find that ``upper`` is not assignable to ``lower``. Likewise, ``lower`` is
2739+
not assignable to ``upper``, so we conclude that ``T1`` is invariant.
27432740

27442741
To determine the variance of ``T2``, we specialize ``ClassA`` as follows:
27452742

0 commit comments

Comments
 (0)