Skip to content

super(cls, self) seemingly has no attribute it actually has #13497

Closed
@pjoziak

Description

@pjoziak

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions