It looks like my question was quite clearly answered in the docs (which derived from PEP 557, as shmee mentioned):
Python stores default member variable values in class attributes. Consider this example, not using dataclasses:
class C: x = [] def add(self, element): self.x.append(element) o1 = C() o2 = C() o1.add(1) o2.add(2) assert o1.x == [1, 2] assert o1.x is o2.xNote that the two instances of class
Cshare the same class variablex, as expected.Using dataclasses, if this code was valid:
@dataclass class D: x: List = [] def add(self, element): self.x += elementit would generate code similar to:
class D: x = [] def __init__(self, x=x): self.x = x def add(self, element): self.x += elementThis has the same issue as the original example using class
C. That is, two instances of classDthat do not specify a value forxwhen creating a class instance will share the same copy ofx. Because dataclasses just use normal Python class creation they also share this behavior. There is no general way for Data Classes to detect this condition. Instead, dataclasses will raise aValueErrorif it detects a default parameter of typelist,dict, orset. This is a partial solution, but it does protect against many common errors.