Strict `__call__` invariance
sobolevn opened this issue · 1 comments
sobolevn commented
Now we have a problem, because function args in Python are covariant we can use it incorrectly with a typeclass
.
Let's see an example:
from classes import typeclass
class A:
...
class B(A):
...
class C(B):
...
@typeclass
def some(instance) -> str:
...
@some.instance(B)
def _some_b(instance: B) -> str:
...
reveal_type(some(A())) # Should be an error
# Argument 1 to "some" has incompatible type "A"; expected "B"
reveal_type(some(B())) # ok
reveal_type(some(C())) # Should be an error, but is not
sobolevn commented
Ok, we have another solution: we can change how __call__
is dispatched.
For example, we can use the same logic simgledispatch
has with mro
traversal.
This can help us to support more general types. In this case, we won't have to implement strict variance (which is really hard).
And, one more thing, we can have better defaults and better code reuse.