Skip to content

Commit d97757f

Browse files
authored
gh-102069: Fix __weakref__ descriptor generation for custom dataclasses (#102075)
1 parent 71e37d9 commit d97757f

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

Lib/dataclasses.py

+3
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,9 @@ def _add_slots(cls, is_frozen, weakref_slot):
11891189
# Remove __dict__ itself.
11901190
cls_dict.pop('__dict__', None)
11911191

1192+
# Clear existing `__weakref__` descriptor, it belongs to a previous type:
1193+
cls_dict.pop('__weakref__', None) # gh-102069
1194+
11921195
# And finally create the class.
11931196
qualname = getattr(cls, '__qualname__', None)
11941197
cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)

Lib/test/test_dataclasses.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,8 @@ class A:
31753175
with self.assertRaisesRegex(TypeError,
31763176
"cannot create weak reference"):
31773177
weakref.ref(a)
3178+
with self.assertRaises(AttributeError):
3179+
a.__weakref__
31783180

31793181
def test_slots_weakref(self):
31803182
@dataclass(slots=True, weakref_slot=True)
@@ -3183,7 +3185,9 @@ class A:
31833185

31843186
self.assertIn("__weakref__", A.__slots__)
31853187
a = A(1)
3186-
weakref.ref(a)
3188+
a_ref = weakref.ref(a)
3189+
3190+
self.assertIs(a.__weakref__, a_ref)
31873191

31883192
def test_slots_weakref_base_str(self):
31893193
class Base:
@@ -3249,7 +3253,8 @@ class A(Base):
32493253
self.assertIn("__weakref__", Base.__slots__)
32503254
self.assertNotIn("__weakref__", A.__slots__)
32513255
a = A(1)
3252-
weakref.ref(a)
3256+
a_ref = weakref.ref(a)
3257+
self.assertIs(a.__weakref__, a_ref)
32533258

32543259
def test_weakref_slot_subclass_no_weakref_slot(self):
32553260
@dataclass(slots=True, weakref_slot=True)
@@ -3265,7 +3270,8 @@ class A(Base):
32653270
self.assertIn("__weakref__", Base.__slots__)
32663271
self.assertNotIn("__weakref__", A.__slots__)
32673272
a = A(1)
3268-
weakref.ref(a)
3273+
a_ref = weakref.ref(a)
3274+
self.assertIs(a.__weakref__, a_ref)
32693275

32703276
def test_weakref_slot_normal_base_weakref_slot(self):
32713277
class Base:
@@ -3280,7 +3286,8 @@ class A(Base):
32803286
self.assertIn("__weakref__", Base.__slots__)
32813287
self.assertNotIn("__weakref__", A.__slots__)
32823288
a = A(1)
3283-
weakref.ref(a)
3289+
a_ref = weakref.ref(a)
3290+
self.assertIs(a.__weakref__, a_ref)
32843291

32853292

32863293
class TestDescriptors(unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``__weakref__`` descriptor generation for custom dataclasses.

0 commit comments

Comments
 (0)