From 9c861190076bb2509327c2b4fb5f648465001a20 Mon Sep 17 00:00:00 2001 From: Joshua Cannon <3956745+thejcannon@users.noreply.github.com> Date: Sun, 9 Feb 2025 14:05:20 -0600 Subject: [PATCH 1/3] fix 129915 by adding __qualname__ to class namespace --- Lib/dataclasses.py | 7 ++++--- Lib/test/test_dataclasses/__init__.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 7a24f8a9e5ccee..be3ec596757a04 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1299,11 +1299,12 @@ def _add_slots(cls, is_frozen, weakref_slot, defined_fields): # Clear existing `__weakref__` descriptor, it belongs to a previous type: cls_dict.pop('__weakref__', None) # gh-102069 + # Set the `__qualname__ accordingly + if (qualname := getattr(cls, '__qualname__', None) is not None): + cls_dict['__qualname__'] = qualname + # And finally create the class. - qualname = getattr(cls, '__qualname__', None) newcls = type(cls)(cls.__name__, cls.__bases__, cls_dict) - if qualname is not None: - newcls.__qualname__ = qualname if is_frozen: # Need this for pickling frozen classes with slots. diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index 2e6c49e29ce828..6dccbbcb3a34c7 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -3367,6 +3367,25 @@ class A: self.assertFalse(hasattr(A, "__slots__")) self.assertTrue(hasattr(B, "__slots__")) + def test_slots_qualname(self): + # Test that __qualname__ is set correctly when using slots + @dataclass(slots=True) + class C: + x: int + + def __init_subclass__(cls): + expected = f'TestSlots.test_slots_qualname..{cls.__name__}' + self.assertEqual(cls.__qualname__, expected) + + self.assertTrue('__qualname__' in C.__dict__) + self.assertEqual(C.__qualname__, 'TestSlots.test_slots_qualname..C') + + @dataclass(slots=True) + class D(C): + pass + + self.assertEqual(D.__qualname__, 'TestSlots.test_slots_qualname..D') + # Can't be local to test_frozen_pickle. @dataclass(frozen=True, slots=True) class FrozenSlotsClass: From a9d248b7bf7ac13bd7cf2a41ae6aaac57621a351 Mon Sep 17 00:00:00 2001 From: Josh Cannon <3956745+thejcannon@users.noreply.github.com> Date: Sun, 9 Feb 2025 19:12:04 -0600 Subject: [PATCH 2/3] Update Lib/dataclasses.py Co-authored-by: sobolevn --- Lib/dataclasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index be3ec596757a04..ea2f2e4912c8f1 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1300,7 +1300,7 @@ def _add_slots(cls, is_frozen, weakref_slot, defined_fields): cls_dict.pop('__weakref__', None) # gh-102069 # Set the `__qualname__ accordingly - if (qualname := getattr(cls, '__qualname__', None) is not None): + if (qualname := getattr(cls, '__qualname__', None)) is not None: cls_dict['__qualname__'] = qualname # And finally create the class. From 6e4e62dfdcf9a55808bddf6cdfbaedc6e8a7c7bf Mon Sep 17 00:00:00 2001 From: Joshua Cannon <3956745+thejcannon@users.noreply.github.com> Date: Sun, 9 Feb 2025 20:18:02 -0600 Subject: [PATCH 3/3] this line aint doing much --- Lib/test/test_dataclasses/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index 6dccbbcb3a34c7..b69ce168127097 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -3377,7 +3377,6 @@ def __init_subclass__(cls): expected = f'TestSlots.test_slots_qualname..{cls.__name__}' self.assertEqual(cls.__qualname__, expected) - self.assertTrue('__qualname__' in C.__dict__) self.assertEqual(C.__qualname__, 'TestSlots.test_slots_qualname..C') @dataclass(slots=True)