I'm confused by this behavior: I have a frozen dataclass of which only 10 are ever needed, so I wanted to put them into an Enum, and did so successfully. Later, I realized I wanted to be able to put a name on them, and all of a sudden, the Enum can't instantiate the dataclass.
import enum
import dataclasses as dc
class Stats(int, enum.Enum):
HP = 0
STA = 1
SPD = 2
ATK = 3
DEF = 4
SPATK = 5
SPDEF = 6
@dc.dataclass(frozen=True)
class Strand:
keeps: tuple[Stats, ...]
costs: int
class Strands(Strand, enum.Enum):
VIT = ((Stats.HP,), 1000)
END = ((Stats.STA,), 1000)
LTH = ((Stats.SPD,), 1000)
AGG = ((Stats.ATK,), 1000)
HRD = ((Stats.DEF,), 1000)
GFT = ((Stats.SPATK,), 1000)
DOM = ((Stats.SPDEF,), 1000)
VIGOR = ((Stats.HP, Stats.STA), 5000)
MIGHT = ((Stats.ATK, Stats.SPATK), 5000)
IMMUN = ((Stats.DEF, Stats.SPDEF), 5000)
The above, what I had before adding the string field, runs successfully - it doesn't do anything. I'm adding a string to Strand
and altering the Enum as follows:
@dc.dataclass(frozen=True)
class Strand:
keeps: tuple[Stats, ...]
costs: int
name: str
class Strands(Strand, enum.Enum):
VIT = ((Stats.HP,), 1000, "Vitality")
END = ((Stats.STA,), 1000, "Endurance")
LTH = ((Stats.SPD,), 1000, "Lithe")
AGG = ((Stats.ATK,), 1000, "Aggressive")
HRD = ((Stats.DEF,), 1000, "Hardening")
GFT = ((Stats.SPATK,), 1000, "Gifted")
DOM = ((Stats.SPDEF,), 1000, "Dominant")
VIGOR = ((Stats.HP, Stats.STA), 5000, "Vigor")
MIGHT = ((Stats.ATK, Stats.SPATK), 5000, "Mighty")
IMMUN = ((Stats.DEF, Stats.SPDEF), 5000, "Immunity")
When I run it with those changes, it no longer exits successfully and instead gives me the following error:
Traceback (most recent call last):
File "test.py", line 20, in <module>
class Strands(Strand, enum.Enum):
File "C:\Program Files\Python310\lib\enum.py", line 298, in __new__
File "<string>", line 5, in __init__
File "C:\Program Files\Python310\lib\types.py", line 187, in __set__
raise AttributeError("can't set attribute")
AttributeError: can't set attribute
I'm confused as to why that's happening, and as to why it's only happening with strings and not the tuple
or int
. From what I can gather, python str
s are immutable just like the other two types in Strand
- though I'm not sure why it would matter, since you can have mutable types in a frozen dataclass.
Is there something weird that happens when initializing a frozen dataclass with a string, when the initialization is done by an Enum?
I'm not really looking for a solution since the issue is pretty easy to get around, I'm just confused by this behavior and wondered if there was an explanation. I'm using Python 3.10.2 - I haven't tested this with other Python versions.
After some time I figured this out. Apparently, Enum
has a built-in un-settable field called name
which collides with your identically named field name
. If you change the name of name
to something else, this will work as expected.