On 2/22/2018 1:56 AM, Raymond Hettinger wrote: > When working on the docs for dataclasses, something unexpected came up. If a dataclass is specified to be frozen, that characteristic is inherited by subclasses which prevents them from assigning additional attributes: > > >>> @dataclass(frozen=True) > class D: > x: int = 10 > > >>> class S(D): > pass > > >>> s = S() > >>> s.cached = True > Traceback (most recent call last): > File "<pyshell#49>", line 1, in <module> > s.cached = True > File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py", line 448, in _frozen_setattr > raise FrozenInstanceError(f'cannot assign to field {name!r}') > dataclasses.FrozenInstanceError: cannot assign to field 'cached' This is because "frozen-ness" is implemented by adding __setattr__ and __delattr__ methods in D, which get inherited by S. > Other immutable classes in Python don't behave the same way: > > > >>> class T(tuple): > pass > > >>> t = T([10, 20, 30]) > >>> t.cached = True > > >>> class F(frozenset): > pass > > >>> f = F([10, 20, 30]) > >>> f.cached = True > > >>> class B(bytes): > pass > > >>> b = B() > >>> b.cached = True The only way I can think of emulating this is checking in __setattr__ to see if the field name is a field of the frozen class, and only raising an error in that case. A related issue is that dataclasses derived from frozen dataclasses are automatically "promoted" to being frozen. >>> @dataclass(frozen=True) ... class A: ... i: int ... >>> @dataclass ... class B(A): ... j: int ... >>> b = B(1, 2) >>> b.j = 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\home\eric\local\python\cpython\lib\dataclasses.py", line 452, in _frozen_setattr raise FrozenInstanceError(f'cannot assign to field {name!r}') dataclasses.FrozenInstanceError: cannot assign to field 'j' Maybe it should be an error to declare B as non-frozen? Eric.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4