Skip to content

Adding @abstractmethod __init__ to ABC breaks staticmethods #1706

Closed
@euresti

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