Multiple inheritance metaclass conflict involving Enum
Asked Answered
D

1

10

I need a double inheritance for a class that is an Enum but also support my own methods. Here's the context:

import abc
from enum import Enum

class MyFirstClass(abc.ABC):
    @abc.abstractmethod
    def func(self):
        pass

class MySecondClass(Enum, MyFirstClass):
    VALUE_1 = 0
    VALUE_2 = 1
    
    def func(self):
        return 42

The declaration of MySecondClass yields the following error:

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

I tried applying this stackoverflow solution by doing:

class MyMetaClass(type(Enum), type(MyFirstClass)):
    pass

class MyFinalClass(Enum, MyFirstClass, metaclass=MyMetaClass):
    VALUE_1 = 0
    VALUE_2 = 1
    
    def func(self):
        return 42 

But I get the following error:

TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`

Is this an issue specific to the Enum type, or am I missing something else regarding metaclasses?

Derogative answered 31/8, 2021 at 20:35 Comment(2)
In general, metaclasses don't compose. I would rethink whether you really need FirstClass to be an abstract base class.Isotope
For a proper abstract Enum type, use the ABCEnumMeta from this answer.Irrespective
I
6

The solution to your immediate problem is:

class MyFinalClass(MyFirstClass, Enum, metaclass=MyMetaClass):
    pass

Note that Enum is the last regular class listed.

For a fully functioning abstract Enum you'll want to use the ABCEnumMeta from this answer -- otherwise missing abstract methods will not be properly flagged.

Irrespective answered 1/9, 2021 at 13:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.