I’m trying to make an Enum
the values of which are of a type which is a dataclass
. As per the official Python Enum HOWTO, this can be achieved by inheriting from both Enum
and the base dataclass
.
Ok, so far, so good.
Now, because the underlying dataclass
has quite a lot of fields, and the Enum
values have only slight modifications between each other, I’d like to specify one of the values as a copy of another, but with a few select parameters changed. That’s why I thought I’d use dataclasses.replace
, but that doesn’t work.
Here’s a minimal reproduction code:
import dataclasses
from enum import Enum
from typing import ClassVar
@dataclasses.dataclass(frozen=True)
class A:
s1: str
s2: str
class B(A, Enum):
b1: ClassVar[B] = 'b11', 'b12'
b2: ClassVar[B] = dataclasses.replace(b1, s2='b22')
This throws this error on the last line:
TypeError: replace() should be called on dataclass instances
and, as I can see, it’s because at the time b2
is instantiated, b1
is still just a tuple. Even if b1
would be properly initialized, because dataclasses.replace
internally calls b1.__class__(b1=b1.s1, b2='b22')
, this might fail as well because directly instantiating an Enum
is not generally allowed, and I’m not sure how dataclass.replace
would interfere with the mechanism that only allows instantiation inside class def.
Until now I was thinking to use something like astuple
to pass the params of b1
to b2
, but it’s pretty unreadable to use code that changes the correct positional argument.
So, any ideas on how to make this work in readable and pythonic manner?
Note: I’m using Python version 3.9, also tried 3.12, but to no avail.
2