Skip to content

Commit

Permalink
🐍 Python codependent inheritance possible with Generic.
Browse files Browse the repository at this point in the history
I might got inspired from reading spark / scala.
  • Loading branch information
rentruewang committed Sep 15, 2024
1 parent 9ec9622 commit 8eb4143
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
17 changes: 9 additions & 8 deletions python/src/proto-inherit.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ def __init__(self) -> None:
print("i inherit so much")


MultiInheritNoParent()
print()
print()
MultiInherit()

print()


class A(Protocol):
@abc.abstractmethod
def __init__(self) -> None:
Expand All @@ -80,3 +72,12 @@ def __init__(self) -> None:
def f(self):
super().f()
print("B.f")


if __name__ == "__main__":
MultiInheritNoParent()
print()
print()
MultiInherit()

print()
5 changes: 4 additions & 1 deletion python/src/unpacking.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ def print_args_kwargs(*args, **kwargs):
print(kwargs)


print_args_kwargs(*CustomIter(), **CustomMapping())
if __name__ == "__main__":
# Despite them not being `Iterable` or `Mapping` subclasses,
# it still would work.
print_args_kwargs(*CustomIter(), **CustomMapping())
26 changes: 26 additions & 0 deletions python/src/variance.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,29 @@ def attack_and_defend(self) -> None:
self.b.defend(self.a)


def codependent_generic():
# Using generic to solve this.
# I think I noticed this is possible by reading the source code of spark.
_B = TypeVar("_B", bound="B")
_A = TypeVar("_A", bound="A")

class A(Generic[_B]):
def attack(self, b: _B) -> None:
print(self, "attacking", b)

class B(Generic("_A")):
def defend(self, a: "_A") -> None:
print(self, "defending", a)

class SubA(A[SubB]):
def attack(self, b: "SubB") -> None:
return super().attack(b)

class SubB(B["SubA"]):
def defend(self, a: "SubA") -> None:
return super().defend(a)


if __name__ == "__main__":
g_ng()
ng_g()
Expand All @@ -478,3 +501,6 @@ def attack_and_defend(self) -> None:
print()
print("co dependent generics")
codependent()

# How come I din't think of this?
codependent_generic()

0 comments on commit 8eb4143

Please sign in to comment.