mirror of
https://github.com/python/cpython.git
synced 2025-11-03 15:11:34 +00:00
[3.14] gh-135228: When @dataclass(slots=True) replaces a dataclass, make the original class collectible (GH-136893) (#136960)
gh-135228: When @dataclass(slots=True) replaces a dataclass, make the original class collectible (GH-136893)
An interesting hack, but more localized in scope than GH-135230.
This may be a breaking change if people intentionally keep the original class around
when using `@dataclass(slots=True)`, and then use `__dict__` or `__weakref__` on the
original class.
(cherry picked from commit 46cbdf967a)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
parent
caef946a25
commit
6e1b31b87e
3 changed files with 54 additions and 0 deletions
|
|
@ -3804,6 +3804,41 @@ class WithCorrectSuper(CorrectSuper):
|
|||
# that we create internally.
|
||||
self.assertEqual(CorrectSuper.args, ["default", "default"])
|
||||
|
||||
def test_original_class_is_gced(self):
|
||||
# gh-135228: Make sure when we replace the class with slots=True, the original class
|
||||
# gets garbage collected.
|
||||
def make_simple():
|
||||
@dataclass(slots=True)
|
||||
class SlotsTest:
|
||||
pass
|
||||
|
||||
return SlotsTest
|
||||
|
||||
def make_with_annotations():
|
||||
@dataclass(slots=True)
|
||||
class SlotsTest:
|
||||
x: int
|
||||
|
||||
return SlotsTest
|
||||
|
||||
def make_with_annotations_and_method():
|
||||
@dataclass(slots=True)
|
||||
class SlotsTest:
|
||||
x: int
|
||||
|
||||
def method(self) -> int:
|
||||
return self.x
|
||||
|
||||
return SlotsTest
|
||||
|
||||
for make in (make_simple, make_with_annotations, make_with_annotations_and_method):
|
||||
with self.subTest(make=make):
|
||||
C = make()
|
||||
support.gc_collect()
|
||||
candidates = [cls for cls in object.__subclasses__() if cls.__name__ == 'SlotsTest'
|
||||
and cls.__firstlineno__ == make.__code__.co_firstlineno + 1]
|
||||
self.assertEqual(candidates, [C])
|
||||
|
||||
|
||||
class TestDescriptors(unittest.TestCase):
|
||||
def test_set_name(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue