Skip to content

Commit c67f1f5

Browse files
jfesereb8680
andauthored
Make instance operations compatible with super() (#643)
* make instance operations compatible with super() * also test handling instance operation --------- Co-authored-by: eb8680 <eb8680@users.noreply.github.com>
1 parent b28fa22 commit c67f1f5

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

effectful/ops/types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,9 @@ def __str__(self):
451451
def __set_name__[T](self, owner: type[T], name: str) -> None:
452452
if not issubclass(owner, Term):
453453
assert not hasattr(self, "_name_on_instance"), "should only be called once"
454-
self._name_on_instance: str = f"{INSTANCE_OP_PREFIX}_{name}"
454+
self._name_on_instance: str = (
455+
f"{INSTANCE_OP_PREFIX}_{owner.__name__}_{name}"
456+
)
455457

456458
def __get__[T](self, instance: T | None, owner: type[T] | None = None):
457459
if hasattr(instance, "__dict__") and hasattr(self, "_name_on_instance"):

tests/test_ops_semantics.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,3 +877,34 @@ def __init__(self, x: int):
877877

878878
v = Operation.define(int)
879879
assert fvsof(A(v())) == {v}
880+
881+
882+
def test_instanceop_super() -> None:
883+
class A:
884+
@Operation.define
885+
def f(self):
886+
return "A"
887+
888+
class B(A):
889+
@Operation.define
890+
def f(self):
891+
return super().f() + " and B"
892+
893+
assert isinstance(A.f, Operation)
894+
assert isinstance(A().f, Operation)
895+
assert isinstance(B.f, Operation)
896+
assert isinstance(B().f, Operation)
897+
898+
assert A.f != A().f != B.f != B().f
899+
900+
assert A().f() == "A"
901+
assert B().f() == "A and B"
902+
with handler({A.f: lambda self: "*A*"}):
903+
assert A().f() == "*A*"
904+
assert B().f() == "*A* and B"
905+
with handler({B.f: lambda self: super(B, self).f() + " and *B*"}):
906+
assert A().f() == "A"
907+
assert B().f() == "A and *B*"
908+
b = B()
909+
with handler({b.f: lambda: "*B*"}):
910+
assert b.f() == "*B*"

0 commit comments

Comments
 (0)