-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
This works fine:
def __add__(self, other: object) -> 'Currency':
if isinstance(other, self.__class__) and isinstance(other, Currency):
return self.__class__(other.amt + self.amt)
return NotImplementedbut this does not:
def __add__(self, other: object) -> 'Currency':
if isinstance(other, Currency) and isinstance(other, self.__class__): # only expression order is flipped
return self.__class__(other.amt + self.amt)
return NotImplementedthrows: error: "object" has no attribute "amt"
Full code to reproduce it locally: https://gist.github.com/pirate/b3ef5a25449285dadc366dd926cebcea
The intention is to check that other is the same class as self (to prevent adding BTC to USD by accident). That check alone should imply that other is a subclass of Currency (since the __add__ method is defined on Currency), but it looks like I have to explicitly make both assertions, and make the Currency assertion after the self.__class__ one in order for mypy to narrow the type correctly.
Correct me if I'm mistaken, but I think there may be two bugs here:
- The order of
isinstancechecks shouldn't matter (especially not in anandexpression) - The
isinstance(other, Currency)should not even be necessary, as it's implied that other is aCurrencyifother.__class__ == self.__class__
This issue discusses a vaguely similar type-narrowing problem, but I'm not sure if it's actually related: #2776