1""" Tests for the internal type cache in CPython. """ 2import unittest 3from test import support 4from test.support import import_helper 5try: 6 from sys import _clear_type_cache 7except ImportError: 8 _clear_type_cache = None 9 10# Skip this test if the _testcapi module isn't available. 11type_get_version = import_helper.import_module('_testcapi').type_get_version 12 13 14@support.cpython_only 15@unittest.skipIf(_clear_type_cache is None, "requires sys._clear_type_cache") 16class TypeCacheTests(unittest.TestCase): 17 def test_tp_version_tag_unique(self): 18 """tp_version_tag should be unique assuming no overflow, even after 19 clearing type cache. 20 """ 21 # Check if global version tag has already overflowed. 22 Y = type('Y', (), {}) 23 Y.x = 1 24 Y.x # Force a _PyType_Lookup, populating version tag 25 y_ver = type_get_version(Y) 26 # Overflow, or not enough left to conduct the test. 27 if y_ver == 0 or y_ver > 0xFFFFF000: 28 self.skipTest("Out of type version tags") 29 # Note: try to avoid any method lookups within this loop, 30 # It will affect global version tag. 31 all_version_tags = [] 32 append_result = all_version_tags.append 33 assertNotEqual = self.assertNotEqual 34 for _ in range(30): 35 _clear_type_cache() 36 X = type('Y', (), {}) 37 X.x = 1 38 X.x 39 tp_version_tag_after = type_get_version(X) 40 assertNotEqual(tp_version_tag_after, 0, msg="Version overflowed") 41 append_result(tp_version_tag_after) 42 self.assertEqual(len(set(all_version_tags)), 30, 43 msg=f"{all_version_tags} contains non-unique versions") 44 45 46if __name__ == "__main__": 47 support.run_unittest(TypeCacheTests) 48