bpo-46417: remove_subclass() clears tp_subclasses (GH-30793)

The remove_subclass() function now deletes the dictionary when
removing the last subclass (if the dictionary becomes empty) to save
memory: set PyTypeObject.tp_subclasses to NULL. remove_subclass() is
called when a type is deallocated.

_PyType_GetSubclasses() no longer holds a reference to tp_subclasses:
its loop cannot modify tp_subclasses.
This commit is contained in:
Victor Stinner 2022-01-22 16:53:30 +01:00 committed by GitHub
parent f1c6ae3270
commit 2d03b73cc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 9 deletions

View file

@ -4923,6 +4923,23 @@ order (MRO) for bases """
cls.lst = [2**i for i in range(10000)]
X.descr
def test_remove_subclass(self):
# bpo-46417: when the last subclass of a type is deleted,
# remove_subclass() clears the internal dictionary of subclasses:
# set PyTypeObject.tp_subclasses to NULL. remove_subclass() is called
# when a type is deallocated.
class Parent:
pass
self.assertEqual(Parent.__subclasses__(), [])
class Child(Parent):
pass
self.assertEqual(Parent.__subclasses__(), [Child])
del Child
gc.collect()
self.assertEqual(Parent.__subclasses__(), [])
class DictProxyTests(unittest.TestCase):
def setUp(self):