Page MenuHomeSoftware Heritage
Paste P769

Python 3.10 GADT
ActivePublic

Authored by vlorentz on Sep 15 2020, 9:53 PM.
import dataclasses
import typing
# need to set _root so typing._Final thinks we're allowed to be a subclass
class MyGenericAlias(typing._GenericAlias, _root=True):
def __subclasscheck__(self, cls):
"""Checks cls is a subclass of self, called by issubclass(cls, self)"""
# iterate through all parents transitively
# eg. if self=A[B1, B2] and cls_parent=C[D1, D2]
for cls_parent in cls.mro():
for base in getattr(cls_parent, "__orig_bases__", []):
if(
# check C is a subclass of A
issubclass(self.__origin__, base.__origin__)
# check they have the same number of args in brackets
# (they may differ in case of subclasses, I think?)
and len(self.__args__) == len(base.__args__)
# check all Dn are subclasses of their respective Bn
and all(
isinstance(self_arg, type) and isinstance(cls_arg, type) and issubclass(self_arg, cls_arg)
for (self_arg, cls_arg) in zip(self.__args__, base.__args__))
):
return True
return False
# In Python >=3.8, we're only allowed to subclass Generic in classes named
# "Protocol", so we're using this empty intermediate class.
# (In Python 3.7, you might be able to make it work by calling it "_Protocol"
# instead.)
class Protocol(typing.Generic):
pass
class MyGeneric(Protocol):
def __class_getitem__(cls, params):
return MyGenericAlias(cls, params)
T = typing.TypeVar("T", bool, int)
@typing.sealed
class Expr(MyGeneric[T]):
pass
@dataclasses.dataclass
class EBool(Expr[bool]):
b: bool
@dataclasses.dataclass
class EInt(Expr[int]):
n: int
@dataclasses.dataclass
class EEqual(Expr[bool]):
l: Expr[int]
r: Expr[int]
def eeval(e: Expr[T]) -> T:
match e:
case EBool(b):
return b
case EInt(n):
return n
case EEqual(l, r):
return eeval(l) == eeval(r)
a = EInt(42)
b = EInt(21)
c = EEqual(a, b)
print("a", eeval(a))
print("b", eeval(b))
print("c", eeval(c))
print("c is an Expr[int]: ", isinstance(c, Expr[int]))
print("c is an Expr[bool]:", isinstance(c, Expr[bool]))

Event Timeline

vlorentz edited the content of this paste. (Show Details)
vlorentz edited the content of this paste. (Show Details)
vlorentz edited the content of this paste. (Show Details)
vlorentz edited the content of this paste. (Show Details)