From 536a34fbc35264a7b7c8feee7e15549ce2deaff8 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Fri, 30 Jan 2026 13:26:14 -0800 Subject: [PATCH 1/2] Update with our new plans for `IsSub` --- design-qs.rst | 2 +- pep.rst | 50 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/design-qs.rst b/design-qs.rst index 7633248..4d4e50b 100644 --- a/design-qs.rst +++ b/design-qs.rst @@ -3,7 +3,7 @@ Big (open?) questions 1. Can we actually implement IsSubtype at runtime in a satisfactory way? -(PROBABLE DECISION: external library *and* restricted checking.) +(PROBABLE DECISION: external library *and* "full" best effort checking.) - There is a lot that needs to happen, like protocols and variance inference and callable subtyping (which might require matching diff --git a/pep.rst b/pep.rst index 356c74e..83c164c 100644 --- a/pep.rst +++ b/pep.rst @@ -534,11 +534,11 @@ proposing to add that as a notion, but we could. Boolean operators ''''''''''''''''' -* ``IsSub[T, S]``: What we would **want** is that it returns a boolean - literal type indicating whether ``T`` is a subtype of ``S``. - To support runtime checking, we probably need something weaker. +* ``IsSub[T, S]``: Returns a boolean literal type indicating whether + ``T`` is a subtype of ``S``. - TODO: Discuss this in detail. + (Actually, I suppose, whether ``S`` is "assignable to" ``T``. We can + certainly bikeshed on this name.) * ``Matches[T, S]``: Equivalent to ``IsSub[T, S] and IsSub[S, T]``. @@ -560,10 +560,13 @@ Basic operators Negative indexes work in the usual way. - N.B: *Unfortunately* ``Base`` must be a proper class, *not* a - protocol. So, for example, ``GetArg[Ty, Iterable, 0]]`` to get the - type of something iterable *won't* work. This is because we can't do - protocol checks at runtime in general. Special forms unfortunately + N.B: Runtime evaluation will only be able to support proper classes + as ``Base``, *not* protocols. So, for example, ``GetArg[Ty, + Iterable, 0]]`` to get the type of something iterable will need to + fail in a runtime evaluator. We should be able to allow it + statically though. + + Special forms unfortunately require some special handling: the arguments list of a ``Callable`` will be packed in a tuple, and a ``...`` will become ``SpecialFormEllipsis``. @@ -1121,11 +1124,7 @@ Renounce all cares of runtime evaluation This would have a lot of simplifying features. -We wouldn't need to worry about making ``IsSub`` be checkable at -runtime, - -XXX - +TODO: Expand Support TypeScript style pattern matching in subtype checking ------------------------------------------------------------- @@ -1133,6 +1132,31 @@ Support TypeScript style pattern matching in subtype checking This would almost certainly only be possible if we also decide not to care about runtime evaluation, as above. +Replace ``IsSub`` with something weaker than "assignable to" checking +--------------------------------------------------------------------- + +Full python typing assignability checking is not fully implementable +at runtime (in particular, even if all the typeshed types for the +stdlib were made available, checking against protocols will often not +be possible, because class attributes may be inferred and have no visible +presence at runtime). + +As proposed, a runtime evaluator will need to be "best effort", +ideally with the contours of that effort well-documented. + +An alternative approach would be to have a weaker predicate as the +core primitive. + +One possibility would be a "sub-similarity" check: ``IsSubSimilar`` +would do *simple* checking of the *head* of types, essentially, +without looking at type parameters. It would not work with protocols. +It would still lift over unions and would check literals. + +We decided it probably was not a good idea to introduce a new notion +that is similar to but not the same as subtyping, and that would need +to either have a long and weird name like ``IsSubSimilar`` or a +misleading short one like ``IsSub``. + .. _less_syntax: From 69d3237b78c8badca20dd569a1c7f554c28fdfbb Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Fri, 30 Jan 2026 13:31:13 -0800 Subject: [PATCH 2/2] fix decorator section --- pep.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pep.rst b/pep.rst index 83c164c..792792b 100644 --- a/pep.rst +++ b/pep.rst @@ -261,14 +261,14 @@ typing. The situation was substantially improved by the introducing of ``ParamSpec`` in :pep:`PEP 612 <612>`, but a number of patterns remain unsupported: - * Adding/removing/modifying a keyword parameter - * Modifying a variable number of parameters -- XXX: check how well TypeVarTuple does this +* Adding/removing/modifying a keyword parameter +* Adding/removing/modifying a variable number of parameters. (Though + ``TypeVarTuple`` is close to being able to support adding and + removing, if multiple unpackings were to be allowed, and Pyre + implemented a ``Map`` operator that allowed modifying multiple.) This proposal will cover those cases. -XXX: Ehhhhhh the generic situation could be bad for some of it? For -partial certainly, I think, which otherwise we can almost do. - NumPy-style broadcasting ------------------------