Jossy
Jossy

Reputation: 999

Abstract class with multiple inheritance error: Can't instantiate abstract class ... with abstract method

I'm trying to get the following to work:

from abc import ABC, abstractmethod


class Abc1(ABC):

    def __init__(self, example_variable_1: int) -> None:
        self.example_variable_1 = example_variable_1


class Abc2(ABC):

    def __init__(self, example_variable_2: int) -> None:
        self.example_variable_2 = example_variable_2

    @abstractmethod
    def example_method(self):
        pass


class Abc3(Abc1, Abc2, ABC):

    def __init__(self, example_variable_1: int, example_variable_2: int):
        Abc1(self).__init__(example_variable_1)
        Abc2(self).__init__(example_variable_2)

    @abstractmethod
    def example_method(self):
        pass


class InstantiateMe(Abc3):
    
    def __init__(self, example_variable_1: int, example_variable_2: int):
        super().__init__(example_variable_1, example_variable_2)

    def example_method(self):
        print("example_method ran")


instance = InstantiateMe(1, 2)

However, I get the error:

TypeError: Can't instantiate abstract class Abc2 with abstract method example_method`

I've read all the questions on SO on this topic and they all seem to be answered by adding in a missing abstractmethod or adjusting the MRO. I think I've got both of those covered off so am stumped.

Upvotes: 1

Views: 600

Answers (1)

Blckknght
Blckknght

Reputation: 104722

The issue is in Abc3.__init__, where you call Abc1(self) and Abc2(self). The second of those is what is giving you the error, since creating an instance of Abc2 is not allowed (and the first won't do what you want, even though it is technically legal, since Abc1 doesn't have any abstract methods). You probably want to be doing:

Abc1.__init__(self, example_variable_1)
Abc2.__init__(self, example_variable_2)

Though, really, you should redesign Abc1 and Abc2 to better support collaborative multiple inheritance. Generally, you do that by taking *args and/or **kwargs and calling super().__init__(*args, **kwargs) before or after doing their own setup.

Upvotes: 3

Related Questions