Skip to content

Adding @abstractmethod __init__ to ABC breaks staticmethods #1706

Description

@euresti

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions