User defined type-level operators works, are they legal?
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
While looking for a workaround about the lack of extensible typed records, found some approaches that works, but then I realized, I'm using quite a few type level operators for that, are they legal?
My use case is too cumbersome and irrelevant to explain, but a simpler self-explanatory example:
Retrieving inner type of Awaitable:
from typing import Awaitable, Type, TypeVar
A = TypeVar("A")
class typeofMeta(type):
def __getitem__(cls, value: A) -> Type[A]: raise NotImplementedError
class AwaitedMeta(type):
def __getitem__(cls, value: Type[Awaitable[A]]) -> Type[A]: raise NotImplementedError
class typeof(metaclass=typeofMeta): ...
class Awaited(metaclass=AwaitedMeta): ...
async def add(a: int, b: int) -> int:
return a + b
coro = add(1, 2)
reveal_type(Awaited[typeof[coro]])
# Revealed type is "Type[builtins.int]"
By defining a __getitem__ at class level I can do whatever with the types and make native-looking type operators. After that I noticed the use of @_SpecialForm in typing internals, but no mention that I could find in docs if this use can be replicated by developers. So I'm wondering if it's safe to rely on this kind of stuff, it enables a lot of nice composition patterns and zero-cost abstractions structures, like is common is TS.
Here are a few more typescript util clones, full implementation in gist:
Type-Level if-else
reveal_type(InstanceType[If[True, int, str]])
# Revealed type is 'builtins.int'
reveal_type(InstanceType[If[False, int, str]])
# Revealed type is 'builtins.str'
Get precise type of an object
def add(a: int, b: int) -> int: return a + b
reveal_type(typeof[add])
# Revealed type is 'def (builtins.int, builtins.int) -> builtins.int'
reveal_type(Type[add]) # with builtin `Type` get down to object
# Revealed type is builtins.object'
Get instance type from a class
class Box(Generic[A]):
value: A
reveal_type(InstanceType[Box[int]])
# Revealed type is 'Box[builtins.int]'
Get return type of a callable
def add(a: int, b: int) -> int: return a + b
reveal_type(ReturnType[add])
# Revealed type is 'builtins.int'
Get parameter typle of a callable
def add(a: int, b: int) -> int: return a + b
reveal_type(Parameters[add])
# Revealed type is 'Tuple[builtins.int, builtins.int]'
Get inner type of an Awaitable
async def add(a: int, b: int) -> int: return a + b
coro = add(1, 2)
reveal_type(Awaited[typeof[coro]])
# Revealed type is "Type[builtins.int]"
Get item type of an iterable
reveal_type(ItemOf[list[int]])
# Revealed type is 'Type[builtins.int]'
Get key type of a Mapping
reveal_type(keyof[dict[str, int]])
# Revealed type is 'builtins.str'
So, are those legal?
Searched but couldn't find docs on it. I do remember seeing @gvanrossum commenting on some issue (couldn't find it now) that mypy is being conservative about allowing user-defined type operators, so I'm a bit afraid of using those.
In pyright it's even crazier, a lot of tricks with tuples are possible with Head[Unpack[Vars]] and Tail[Unpack[Vars]], plus some typevar bounding behaviour that made me notice even higher kinded types implementation is possible using the Lightweight higher-kinded polymorphism encoding, or maybe even a small type-level implementation of lisp
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit der Überprüfung der benutzerdefinierten Operatoren und der reveal_type-Beispiele im Issue und vergleiche sie anschließend mit mypy/typeshed/stdlib/typing.pyi und dem verlinkten pyright-Verhalten. Ermittle, ob die dokumentierten Typing-Regeln diese Konstrukte abdecken und welche konkrete Dokumentationslücke verbleibt; das Issue ist erst abgeschlossen, wenn die Zulässigkeit und die unterstützte Verwendung dokumentiert oder eindeutig geklärt sind.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- devtools
- Issue-Typ
- Dokumentation
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 25/100