Consider the following example code
from dataclasses import dataclass, field
from typing import ClassVar
@dataclass
class Base:
x: str = field(default='x', init=False)
@dataclass
class A(Base):
name: str
@dataclass
class B(Base):
name: str
a = A('test_a')
b = B('test_b')
a.x = 'y'
a.x # prints 'y'
b.x # prints 'x'
which prints 'y' and 'x' as expected.
Now I'd like to make x a ClassVar of type dict:
from dataclasses import dataclass, field
from typing import ClassVar, Dict
@dataclass
class Base:
x: ClassVar[Dict[str, str]] = field(default={'x': 'x'}, init=False)
@dataclass
class A(Base):
name: str
@dataclass
class B(Base):
name: str
a = A('test_a')
b = B('test_b')
a.x['y'] = 'y'
a.x
b.x
However, now the output is
a.x => {'x': 'x', 'y': 'y'}
b.x => {'x': 'x', 'y': 'y'}
I'd expect that only a.x gets modified and b.x stays at the default init value `{'x': 'x'}.
If the field would not be a ClassVar then I could use the default_factory=dict but that doesn't work in combination with ClassVar since it returns the error
Field cannot have a default factory
default={'x': 'x'}means that all instances using the default value share a reference to the same dictionary. If you can't usedefault_factoryinstead this seems unavoidable.default_factory, it doesn't seem to be compatible