diff options
author | Victor Stinner <vstinner@python.org> | 2022-01-21 00:42:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-21 00:42:25 (GMT) |
commit | e9e3eab0b868c7d0b48e472705024240d5c39d5c (patch) | |
tree | 65c254d948a37dd822085887ebb84f390ad48d94 /Lib/test/_test_embed_structseq.py | |
parent | 27df7566bc19699b967e0e30d7808637b90141f6 (diff) | |
download | cpython-e9e3eab0b868c7d0b48e472705024240d5c39d5c.zip cpython-e9e3eab0b868c7d0b48e472705024240d5c39d5c.tar.gz cpython-e9e3eab0b868c7d0b48e472705024240d5c39d5c.tar.bz2 |
bpo-46417: Finalize structseq types at exit (GH-30645)
Add _PyStructSequence_FiniType() and _PyStaticType_Dealloc()
functions to finalize a structseq static type in Py_Finalize().
Currrently, these functions do nothing if Python is built in release
mode.
Clear static types:
* AsyncGenHooksType: sys.set_asyncgen_hooks()
* FlagsType: sys.flags
* FloatInfoType: sys.float_info
* Hash_InfoType: sys.hash_info
* Int_InfoType: sys.int_info
* ThreadInfoType: sys.thread_info
* UnraisableHookArgsType: sys.unraisablehook
* VersionInfoType: sys.version
* WindowsVersionType: sys.getwindowsversion()
Diffstat (limited to 'Lib/test/_test_embed_structseq.py')
-rw-r--r-- | Lib/test/_test_embed_structseq.py | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/Lib/test/_test_embed_structseq.py b/Lib/test/_test_embed_structseq.py new file mode 100644 index 0000000..868f9f8 --- /dev/null +++ b/Lib/test/_test_embed_structseq.py @@ -0,0 +1,55 @@ +import sys +import types +import unittest + + +# 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(unittest.TestCase): + # test PyTypeObject members + def check_structseq(self, obj_type): + # ob_refcnt + self.assertGreaterEqual(sys.getrefcount(obj_type), 1) + # tp_base + self.assertTrue(issubclass(obj_type, tuple)) + # tp_bases + self.assertEqual(obj_type.__bases__, (tuple,)) + # tp_dict + self.assertIsInstance(obj_type.__dict__, types.MappingProxyType) + # tp_mro + self.assertEqual(obj_type.__mro__, (obj_type, tuple, object)) + # tp_name + self.assertIsInstance(type.__name__, str) + # tp_subclasses + self.assertEqual(obj_type.__subclasses__(), []) + + def test_sys_attrs(self): + for attr_name in ( + 'flags', # FlagsType + 'float_info', # FloatInfoType + 'hash_info', # Hash_InfoType + 'int_info', # Int_InfoType + 'thread_info', # ThreadInfoType + 'version_info', # VersionInfoType + ): + 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: + with self.subTest(func=func_name): + func = getattr(sys, func_name) + obj = func() + self.check_structseq(type(obj)) + + +try: + unittest.main() +except SystemExit as exc: + if exc.args[0] != 0: + raise +print("Tests passed") |