User defined type-level operators works, are they legal?
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 20.6k
- Forks
- 3.3k
- Merge medio
- 1 d 18 h
- PR fusionados (30 d)
- 54
Descripción
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
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza revisando los operadores definidos por el usuario y los ejemplos de reveal_type del issue; después, compáralos con mypy/typeshed/stdlib/typing.pyi y con el comportamiento de pyright enlazado. Determina si las reglas de typing documentadas abordan estas construcciones y qué laguna específica de documentación queda; el issue solo estará completo cuando la legalidad y el uso compatible estén documentados o claramente resueltos.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- devtools
- Tipo de issue
- Documentación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Estancado
- Claridad
- Necesita aclaración
- Aptitud para principiantes
- 25/100