From 19980beee8cfb9cc8dc440f26140512aa04de822 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Mon, 18 May 2026 16:02:27 -0700 Subject: [PATCH] PEP 827: Minor fixes and cleanups * Fix description of ``Bool[T]`` to match the definition * Update commentary about ``GetArg`` special forms to match change from #4866 * Update lifting example to use an operator that is still in the spec * Make the ``GenericCallable`` rationale example more self-consistent * Have an example of ``GenericCallable`` --- peps/pep-0827.rst | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/peps/pep-0827.rst b/peps/pep-0827.rst index dcea0d4b8ec..60706edc894 100644 --- a/peps/pep-0827.rst +++ b/peps/pep-0827.rst @@ -613,8 +613,7 @@ Boolean operators Technically this relation is "consistency" in the typing spec, not equivalence. -* ``Bool[T]``: Returns ``Literal[True]`` if ``T`` is also - ``Literal[True]`` or a union containing it. +* ``Bool[T]``: Returns ``Literal[True]`` if ``T`` is also ``Literal[True]``. Equivalent to ``IsAssignable[T, Literal[True]] and not IsAssignable[T, Never]``. This is useful for invoking "helper aliases" that return a boolean @@ -640,7 +639,7 @@ Basic operators fail in a runtime evaluator of types.) Special forms require special handling: the arguments list of a - ``Callable`` will be packed in a tuple and a ``...`` will be treated + ``Callable`` will be packed in a ``Params`` and a ``...`` will be treated as ``*args: Any`` and ``**kwargs: Any``, represented with the new ``Param`` types. @@ -855,8 +854,11 @@ Many of the builtin operations are "lifted" over ``Union``. For example:: - Concat[Literal['a'] | Literal['b'], Literal['c'] | Literal['d']] = ( - Literal['ac'] | Literal['ad'] | Literal['bc'] | Literal['bd'] + Slice[tuple[A, B, C], Literal[0] | Literal[1], Literal[2] | Literal[3]] = ( + tuple[A, B] + | tuple[A, B, C] + | tuple[B] + | tuple[B, C] ) @@ -1326,7 +1328,7 @@ unbound type variables and let them be generalized:: type Foo = NewProtocol[ Member[ Literal["process"], - Callable[[T], set[T] if IsAssignable[T, int] else T] + Callable[[T], T if IsAssignable[T, list] else list[T]] ] ] @@ -1341,6 +1343,18 @@ functions with explicit generic annotations. For old-style generics, we'll probably have to try to evaluate it and then raise an error when we encounter a variable.) +With our real syntax, this look likes:: + + type Foo = NewProtocol[ + Member[ + Literal["process"], + GenericCallable[ + tuple[T], + lambda T: Callable[[T], T if IsAssignable[T, list] else list[T]], + ], + ] + ] + The reason we suggest restricting the use of ``GenericCallable`` to the type argument of ``Member`` is because impredicative polymorphism (where you can instantiate type variables with other