[3.12] gh-113190: Reenable non-debug interned string cleanup (GH-113601) by hugovk · Pull Request #130582 · python/cpython · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions Doc/c-api/init.rst
40 changes: 18 additions & 22 deletions Lib/test/_test_embed_structseq.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import sys
import types
import unittest

# Note: This test file can't import `unittest` since the runtime can't
# currently guarantee that it will not leak memory. Doing so will mark
# the test as passing but with reference leaks. This can safely import
# the `unittest` library once there's a strict guarantee of no leaks
# during runtime shutdown.

# bpo-46417: Test that structseq types used by the sys module are still
# valid when Py_Finalize()/Py_Initialize() are called multiple times.
class TestStructSeq:
class TestStructSeq(unittest.TestCase):
# test PyTypeObject members
def _check_structseq(self, obj_type):
def check_structseq(self, obj_type):
# ob_refcnt
assert sys.getrefcount(obj_type) > 1
self.assertGreaterEqual(sys.getrefcount(obj_type), 1)
# tp_base
assert issubclass(obj_type, tuple)
self.assertTrue(issubclass(obj_type, tuple))
# tp_bases
assert obj_type.__bases__ == (tuple,)
self.assertEqual(obj_type.__bases__, (tuple,))
# tp_dict
assert isinstance(obj_type.__dict__, types.MappingProxyType)
self.assertIsInstance(obj_type.__dict__, types.MappingProxyType)
# tp_mro
assert obj_type.__mro__ == (obj_type, tuple, object)
self.assertEqual(obj_type.__mro__, (obj_type, tuple, object))
# tp_name
assert isinstance(type.__name__, str)
self.assertIsInstance(type.__name__, str)
# tp_subclasses
assert obj_type.__subclasses__() == []
self.assertEqual(obj_type.__subclasses__(), [])

def test_sys_attrs(self):
for attr_name in (
Expand All @@ -36,23 +32,23 @@ def test_sys_attrs(self):
'thread_info', # ThreadInfoType
'version_info', # VersionInfoType
):
attr = getattr(sys, attr_name)
self._check_structseq(type(attr))
with self.subTest(attr=attr_name):
attr = getattr(sys, attr_name)
self.check_structseq(type(attr))

def test_sys_funcs(self):
func_names = ['get_asyncgen_hooks'] # AsyncGenHooksType
if hasattr(sys, 'getwindowsversion'):
func_names.append('getwindowsversion') # WindowsVersionType
for func_name in func_names:
func = getattr(sys, func_name)
obj = func()
self._check_structseq(type(obj))
with self.subTest(func=func_name):
func = getattr(sys, func_name)
obj = func()
self.check_structseq(type(obj))


try:
tests = TestStructSeq()
tests.test_sys_attrs()
tests.test_sys_funcs()
unittest.main()
except SystemExit as exc:
if exc.args[0] != 0:
raise
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:c:func:`Py_Finalize` now deletes all interned strings.
15 changes: 1 addition & 14 deletions Objects/unicodeobject.c