Skip to content

Commit 1c3e0c9

Browse files
committed
gh-143969: Add NEWS entry for frozen slotted dataclass fix
1 parent d3b62e4 commit 1c3e0c9

File tree

3 files changed

+24
-23
lines changed

3 files changed

+24
-23
lines changed

Lib/dataclasses.py

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -732,29 +732,20 @@ def _frozen_get_del_attr(cls, fields, func_builder):
732732
if fields:
733733
condition += ' or name in {' + ', '.join(repr(f.name) for f in fields) + '}'
734734

735-
func_builder.add_fn(
736-
'__setattr__',
737-
('self', 'name', 'value'),
738-
(
739-
f' if {condition}:',
740-
' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
741-
' object.__setattr__(self, name, value)',
742-
),
743-
locals=locals,
744-
overwrite_error=True,
745-
)
746-
747-
func_builder.add_fn(
748-
'__delattr__',
749-
('self', 'name'),
750-
(
751-
f' if {condition}:',
752-
' raise FrozenInstanceError(f"cannot delete field {name!r}")',
753-
' object.__delattr__(self, name)',
754-
),
755-
locals=locals,
756-
overwrite_error=True,
757-
)
735+
func_builder.add_fn('__setattr__',
736+
('self', 'name', 'value'),
737+
(f' if {condition}:',
738+
' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
739+
f' object.__setattr__(self, name, value)'),
740+
locals=locals,
741+
overwrite_error=True)
742+
func_builder.add_fn('__delattr__',
743+
('self', 'name'),
744+
(f' if {condition}:',
745+
' raise FrozenInstanceError(f"cannot delete field {name!r}")',
746+
f' object.__delattr__(self, name)'),
747+
locals=locals,
748+
overwrite_error=True)
758749

759750

760751
def _is_classvar(a_type, typing):

Lib/test/test_dataclasses/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,6 +3404,14 @@ class C:
34043404

34053405
c = C('hello')
34063406
self.assertEqual(deepcopy(c), c)
3407+
def test_frozen_slots_setattr(self):
3408+
# gh-143969: Ensure frozen+slots uses object.__setattr__
3409+
@dataclass(frozen=True, slots=True)
3410+
class A:
3411+
x: int
3412+
a = A(1)
3413+
with self.assertRaisesRegex(FrozenInstanceError, 'cannot assign to field'):
3414+
a.x = 2
34073415

34083416

34093417
class TestSlots(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a crash in frozen slotted dataclasses where assigning to an attribute
2+
could raise an internal TypeError instead of failing cleanly.

0 commit comments

Comments
 (0)