From 4bf23e68b08196d0ba24627014c5c61c6f4d6d4c Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 11 Sep 2024 13:13:43 +0300 Subject: [PATCH 1/3] gh-123935: Fix typo in `_get_slots` in `dataclasses.py` --- Lib/dataclasses.py | 2 +- Lib/test/test_dataclasses/__init__.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 141aa41c74d7ed..ac7d40cf2cac2e 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1208,7 +1208,7 @@ def _get_slots(cls): slots = [] if getattr(cls, '__weakrefoffset__', -1) != 0: slots.append('__weakref__') - if getattr(cls, '__dictrefoffset__', -1) != 0: + if getattr(cls, '__dictoffset__', -1) != 0: slots.append('__dict__') yield from slots case str(slot): diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index da696ad961cfd7..e5f0e643d2dc41 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -3664,6 +3664,23 @@ class A(WithDictSlot): ... self.assertEqual(A().__dict__, {}) A() + @support.cpython_only + def test_dataclass_slot_dict_ctype(self): + # https://github.com/python/cpython/issues/123935 + from test.support import import_helper + # Skips test if `_testcapi` is not present: + _testcapi = import_helper.import_module('_testcapi') + + @dataclass(slots=True) + class A(_testcapi.HeapCTypeWithDict): + __dict__: dict = {} + self.assertEqual(A.__slots__, ()) + + @dataclass(slots=True) + class A(_testcapi.HeapCTypeWithWeakref): + __dict__: dict = {} + self.assertEqual(A.__slots__, ('__dict__',)) + @support.cpython_only def test_slots_with_wrong_init_subclass(self): # TODO: This test is for a kinda-buggy behavior. From 64db162fb3f7013f01e3f52d1d838a2557b481cf Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 11 Sep 2024 13:33:25 +0300 Subject: [PATCH 2/3] Add NEWS --- .../next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst diff --git a/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst b/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst new file mode 100644 index 00000000000000..de720c3714c6ff --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-11-13-33-19.gh-issue-123935.fRZ_56.rst @@ -0,0 +1,2 @@ +Fix parent slots detection for dataclasses that inherit from classes with +``__dictoffset__``. From b2fae2720e6a369d3b2fde6417f877e2bd5ae355 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 11 Sep 2024 20:52:41 +0300 Subject: [PATCH 3/3] Address review --- Lib/test/test_dataclasses/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index e5f0e643d2dc41..6934e88d9d338c 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -3672,14 +3672,16 @@ def test_dataclass_slot_dict_ctype(self): _testcapi = import_helper.import_module('_testcapi') @dataclass(slots=True) - class A(_testcapi.HeapCTypeWithDict): + class HasDictOffset(_testcapi.HeapCTypeWithDict): __dict__: dict = {} - self.assertEqual(A.__slots__, ()) + self.assertNotEqual(_testcapi.HeapCTypeWithDict.__dictoffset__, 0) + self.assertEqual(HasDictOffset.__slots__, ()) @dataclass(slots=True) - class A(_testcapi.HeapCTypeWithWeakref): + class DoesNotHaveDictOffset(_testcapi.HeapCTypeWithWeakref): __dict__: dict = {} - self.assertEqual(A.__slots__, ('__dict__',)) + self.assertEqual(_testcapi.HeapCTypeWithWeakref.__dictoffset__, 0) + self.assertEqual(DoesNotHaveDictOffset.__slots__, ('__dict__',)) @support.cpython_only def test_slots_with_wrong_init_subclass(self):