From e7cba09bf9756336668e8d644c8df997cfcd072d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 24 May 2025 15:27:24 -0700 Subject: [PATCH 1/2] spec: various minor changes - Replace an incorrect use of "subtype" with "assignable" - Remove discussion of str/bytes Literal types that seems geared towards Python 2. Instead, say straightforwardly that strings (str objects) and bytes objects are supported. - Rewrite an example that relies on the int/float/complex special case. The example was correct but I think it's confusing to readers if we have examples unnecessarily rely on the special case. Instead, use example types with more straightforward behavior. --- docs/spec/generics.rst | 2 +- docs/spec/literal.rst | 15 ++------------- docs/spec/tuples.rst | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/docs/spec/generics.rst b/docs/spec/generics.rst index 942abb66c..4f4150c44 100644 --- a/docs/spec/generics.rst +++ b/docs/spec/generics.rst @@ -2000,7 +2000,7 @@ Bound Rules T1 = TypeVar("T1", bound=int) TypeVar("Ok", default=T1, bound=float) # Valid TypeVar("AlsoOk", default=T1, bound=int) # Valid - TypeVar("Invalid", default=T1, bound=str) # Invalid: int is not a subtype of str + TypeVar("Invalid", default=T1, bound=str) # Invalid: int is not assignable to str Constraint Rules ^^^^^^^^^^^^^^^^ diff --git a/docs/spec/literal.rst b/docs/spec/literal.rst index 564ddaa44..3bc508036 100644 --- a/docs/spec/literal.rst +++ b/docs/spec/literal.rst @@ -98,7 +98,7 @@ expressions, and nothing else. Legal parameters for ``Literal`` at type check time """"""""""""""""""""""""""""""""""""""""""""""""""" -``Literal`` may be parameterized with literal ints, byte and unicode strings, +``Literal`` may be parameterized with literal ints, strings, `bytes` objects, bools, Enum values and ``None``. So for example, all of the following would be legal:: @@ -106,8 +106,8 @@ the following would be legal:: Literal[0x1A] # Exactly equivalent to Literal[26] Literal[-4] Literal["hello world"] + Literal[u"hello world"] # Exactly equivalent to Literal["hello world"] Literal[b"hello world"] - Literal[u"hello world"] Literal[True] Literal[Color.RED] # Assuming Color is some enum Literal[None] @@ -143,17 +143,6 @@ This should be exactly equivalent to the following type:: Literal[1, 2, 3, "foo", 5] | None -**Note:** String literal types like ``Literal["foo"]`` should subtype either -bytes or unicode in the same way regular string literals do at runtime. - -For example, in Python 3, the type ``Literal["foo"]`` is equivalent to -``Literal[u"foo"]``, since ``"foo"`` is equivalent to ``u"foo"`` in Python 3. - -Similarly, in Python 2, the type ``Literal["foo"]`` is equivalent to -``Literal[b"foo"]`` -- unless the file includes a -``from __future__ import unicode_literals`` import, in which case it would be -equivalent to ``Literal[u"foo"]``. - Illegal parameters for ``Literal`` at type check time """"""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/docs/spec/tuples.rst b/docs/spec/tuples.rst index 1209cc027..40afc732b 100644 --- a/docs/spec/tuples.rst +++ b/docs/spec/tuples.rst @@ -91,7 +91,7 @@ Type Compatibility Rules ------------------------ Because tuple contents are immutable, the element types of a tuple are covariant. -For example, ``tuple[int, int]`` is a subtype of ``tuple[float, complex]``. +For example, ``tuple[bool, int]`` is a subtype of ``tuple[int, object]``. As discussed above, a homogeneous tuple of arbitrary length is equivalent to a union of tuples of different lengths. That means ``tuple[()]``, From 39dd3c5e3a033a98d98324872c3a1a0c84e951a1 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 24 May 2025 21:59:35 -0700 Subject: [PATCH 2/2] reword more --- docs/spec/literal.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/spec/literal.rst b/docs/spec/literal.rst index 3bc508036..1e820a63f 100644 --- a/docs/spec/literal.rst +++ b/docs/spec/literal.rst @@ -98,18 +98,23 @@ expressions, and nothing else. Legal parameters for ``Literal`` at type check time """"""""""""""""""""""""""""""""""""""""""""""""""" -``Literal`` may be parameterized with literal ints, strings, `bytes` objects, -bools, Enum values and ``None``. So for example, all of +``Literal`` may be parameterized with literal ``int``, ``str``, ``bytes``, +and ``bool`` objects, instances of ``enum.Enum`` subclasses, and ``None``. So for example, all of the following would be legal:: Literal[26] - Literal[0x1A] # Exactly equivalent to Literal[26] + Literal[0x1A] # Equivalent to Literal[26] Literal[-4] Literal["hello world"] - Literal[u"hello world"] # Exactly equivalent to Literal["hello world"] + Literal[u"hello world"] # Equivalent to Literal["hello world"] Literal[b"hello world"] Literal[True] - Literal[Color.RED] # Assuming Color is some enum + + class Color(enum.Enum): + RED = 1 + GREEN = 2 + + Literal[Color.RED] Literal[None] **Note:** Since the type ``None`` is inhabited by just a single