You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, first of all thanks for this amazing library!
I have a problem though, when using interfaces with typed arguments. As I understand it, if a function accept argument of class A, if B inherits from A, it should also be accepted.
But when I try this code
from interface import Interface, implements
class A:
pass
class B(A):
pass
class I(Interface):
def my_func(self, a: A):
pass
class C(implements(I)):
def my_func(self, a: B):
pass
it throws this error
interface.interface.InvalidImplementation:
class C failed to implement interface I:
The following methods of I were implemented with invalid signatures:
- my_func(self, a: __main__.B) != my_func(self, a: __main__.A)
The text was updated successfully, but these errors were encountered:
isaaclok
changed the title
Subclasses in type arguments
Subclasses in typed arguments
Dec 9, 2020
I haven't used type annotations in a real project myself, so the current support for type annotations is a bit rudimentary. We currently just check that annotations for implementations exactly match the annotations on interfaces, which is more strict than necessary. I think a reasonable improvement would be for us to do type checking using issubclass, though it's a bit tricky to do this properly because annotations are no longer evaluated eagerly as of https://www.python.org/dev/peps/pep-0563/.
One thing to note is that if we taught interface to reason about subtyping relationships in annotations, we would probably still end up rejecting the code snippet in your example, because function parameters are generally modelled as contravariant, rather than covariant. That is to say, if your interface method takes an A as a parameter, then your implementation would need to take an A or a supertype of A, rather than a subtype.
The way I remember covariance vs. contravariance is as follows: if an impl satisfies your interface, then it must be possible to call your implementation with any set of arguments that could be passed to to the interface signature. Your interface signature promises that it can be called with any A (i.e., an A or any subtype of A), but your impl signature only accepts B, which is a more specific subtype of A. If there were a third type, C, which was a subtype of A but not B, then it would be valid to pass a C to the interface method, but it would not be valid to pass a C to your impl method. On the other hand, if your impl requires a supertype of A, then you know that an A (or any subtype of A) will still be accepted, so that's ok.
Hi, first of all thanks for this amazing library!
I have a problem though, when using interfaces with typed arguments. As I understand it, if a function accept argument of class A, if B inherits from A, it should also be accepted.
But when I try this code
it throws this error
The text was updated successfully, but these errors were encountered: