diff --git a/python/src/proto-inherit.py b/python/src/proto-inherit.py index 559d098..45b3140 100644 --- a/python/src/proto-inherit.py +++ b/python/src/proto-inherit.py @@ -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: @@ -80,3 +72,12 @@ def __init__(self) -> None: def f(self): super().f() print("B.f") + + +if __name__ == "__main__": + MultiInheritNoParent() + print() + print() + MultiInherit() + + print() diff --git a/python/src/unpacking.py b/python/src/unpacking.py index d6b6ccf..6feec62 100644 --- a/python/src/unpacking.py +++ b/python/src/unpacking.py @@ -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()) diff --git a/python/src/variance.py b/python/src/variance.py index c57cebb..c11b0be 100644 --- a/python/src/variance.py +++ b/python/src/variance.py @@ -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() @@ -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()