Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Paste
P769
Python 3.10 GADT
Active
Public
Actions
Authored by
vlorentz
on Sep 15 2020, 9:53 PM.
Edit Paste
Archive Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Flag For Later
Tags
None
Subscribers
None
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
created this paste.
Sep 15 2020, 9:53 PM
2020-09-15 21:53:50 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
vlorentz
edited the content of this paste.
(Show Details)
Sep 15 2020, 9:58 PM
2020-09-15 21:58:48 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
Sep 15 2020, 10:57 PM
2020-09-15 22:57:37 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
Sep 15 2020, 11:06 PM
2020-09-15 23:06:15 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
vlorentz
edited the content of this paste.
(Show Details)
Sep 15 2020, 11:10 PM
2020-09-15 23:10:03 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
vlorentz
edited the content of this paste.
(Show Details)
Sep 15 2020, 11:16 PM
2020-09-15 23:16:38 (UTC+2)
vlorentz
edited the content of this paste.
(Show Details)
Log In to Comment