python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.18k stars 2.78k forks source link

Virtual subclasses of abstract base classes #1459

Closed jtatum closed 2 years ago

jtatum commented 8 years ago

Seeing a couple of different errors with virtual subclasses:

from abc import ABCMeta
class M(metaclass=ABCMeta):
    pass
class A:
    pass
M.register(A)  # error: "M" has no attribute "register"
def test(obj: M):
    pass
obj = A()
test(obj)  # error: Argument 1 to "test" has incompatible type "A"; expected "M"
gvanrossum commented 8 years ago

ABC.register() is not supported and it's unclear to me how it could be supported without a relatively big change to mypy. It probably would require an extra pass over the code looking for register() calls everywhere.

The only thing that's easy to do is to add register() to the stubs in typeshed -- can you send a PR for that?

jtatum commented 8 years ago

Hmm, there might be another issue with metaclasses that prevents me from adding register to typeshed:

class M(type):
    def test(cls):
        pass
class C(metaclass=M):
    pass
C.test()  # error: "C" has no attribute "test"
gvanrossum commented 8 years ago

Ohh... Yes, that looks like we have a problem with metaclasses.

jsoref commented 4 years ago

FWIW, this is a pretty common/frustrating bug in the Python ecosystem, here's the equivalent IntelliJ/PyCharm issue.

AlexWaygood commented 2 years ago

For ABCMeta.register() support, see #2922 (newer issue but has more discussion than this one).

For generalised metaclass support, this example no longer reproduces on mypy 0.941.