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
{{ message }}
Repository navigation
Adding @abstractmethod __init__ to ABC breaks staticmethods #1706
I was trying to create an ABC that also worked as a factory.
from abc import (
ABCMeta,
abstractmethod,
)
class WidgetWithInit(object):
__metaclass__ = ABCMeta
@abstractmethod
def __init__(self, foo, bar):
# type: (int, int) -> None
pass
@staticmethod
def add(foo, bar):
# type: (int, int) -> int
return foo + bar
@classmethod
def add_class(cls, foo, bar):
# type: (int, int) -> int
return foo + bar
WidgetWithInit.add(1, '2')
WidgetWithInit.add_class(1, '2')
class WidgetNoInit(object):
__metaclass__ = ABCMeta
@staticmethod
def add(foo, bar):
# type: (int, int) -> int
return foo + bar
@classmethod
def add_class(cls, foo, bar):
# type: (int, int) -> int
return foo + bar
WidgetNoInit.add(1, '2')
WidgetNoInit.add_class(1, '2')
MyPy will respond:
rt6.py:40: error: Argument 2 to "add" of "WidgetNoInit" has incompatible type "str"; expected "int"
rt6.py:41: error: Argument 2 to "add_class" of "WidgetNoInit" has incompatible type "str"; expected "int"
So adding the def __init__ seems to make the staticmethod and classmethod have a type of Any.
Fortunately I can work around it by not defining init in the ABC, and having my def create enforce the signature.
I think this bug is deep and important. I've encountered something similar in #3227. The logic that handles decorators seems to be flawed in a way which is difficult to fix.
True, decorators are one of mypy's weak spots. We're slowly chipping away at it (e.g. #3918) but it's not easy because of special-casing in various places (both in Python and in mypy).
Activity
rwbarton commentedon Jun 14, 2016
In fact mypy thinks the expression
WidgetNoInitalready has typeAnywith the definitionrwbarton commentedon Jun 29, 2016
In fact
__init__having any decorator will result in the class being treated asAny, sincetype_object_typestarts like this:and
get_methoddoesn't return decorated things.rwbarton commentedon Jun 29, 2016
Here's a possible test case
But I gave up on trying to fix this because the logic around recognizing decorators is too hairy.
elazarg commentedon Sep 24, 2017
I think this bug is deep and important. I've encountered something similar in #3227. The logic that handles decorators seems to be flawed in a way which is difficult to fix.
gvanrossum commentedon Sep 24, 2017
True, decorators are one of mypy's weak spots. We're slowly chipping away at it (e.g. #3918) but it's not easy because of special-casing in various places (both in Python and in mypy).
Support decorated constructors (#6645)