Closed
Description
Bug Report
I wanted to have a quick way of concatenating results of several mixin-like implementations of similar algorithms. Below is a MWE of what I wanted to implement
To Reproduce
MWE:
from abc import abstractmethod
from typing import List
class A:
@abstractmethod
def foo(self, arg: str) -> str:
raise NotImplementedError
def bar(self, arg: str) -> List[str]:
ret: List[str] = []
for c in self.__class__.mro():
c_super = super(c, self)
if hasattr(c_super, 'foo'):
try:
ret.append(c_super.foo(arg))
except NotImplementedError:
pass
try:
ret.append(self.foo(arg))
except NotImplementedError:
pass
return ret
class B(A):
def foo(self, arg: str) -> str:
return f'B.foo[{arg}]'
class C(B):
def foo(self, arg: str) -> str:
return f'C.foo[{arg}]'
hello = 'hello'
c = C()
print(f'foo: {c.foo(hello)}')
print(f'bar: {c.bar(hello)}')
Expected Behavior
No warning
Actual Behavior
mypy recognizes
mwe.py:15: error: "super" has no attribute "foo"
even though it is executed after if hasattr(...)
What's even more strange, if you construct a similar pattern but with the method foo
with no arguments, then the same example just passes mypy checks.
Your Environment
- Mypy version used: 0.812, 0.900, 0.971
- Python version used: 3.8
- Operating system and version: Ubuntu 22.04