@@ -2,6 +2,9 @@
22importunittest
3344_testcapi=import_helper.import_module('_testcapi')
5+_testlimitedcapi=import_helper.import_module('_testlimitedcapi')
6+7+NULL=None
5869710classBuiltinStaticTypesTests(unittest.TestCase):
@@ -39,15 +42,18 @@ def test_tp_mro_is_set(self):
39424043classTypeTests(unittest.TestCase):
4144deftest_get_type_name(self):
45+# Test PyType_GetName(), PyType_GetQualName(),
46+# PyType_GetFullyQualifiedName() and PyType_GetModuleName().
47+4248classMyType:
4349pass
445045-from_testcapiimport (
51+from_testlimitedcapiimport (
4652get_type_name, get_type_qualname,
4753get_type_fullyqualname, get_type_module_name)
48544955fromcollectionsimportOrderedDict
50-ht=_testcapi.get_heaptype_for_name()
56+ht=_testlimitedcapi.get_heaptype_for_name()
5157forcls, fullname, modname, qualname, namein (
5258 (int,
5359'int',
@@ -107,6 +113,15 @@ class MyType:
107113MyType.__module__=123
108114self.assertEqual(get_type_fullyqualname(MyType), 'my_qualname')
109115116+# CRASHES get_type_name(NULL)
117+# CRASHES get_type_qualname(NULL)
118+# CRASHES get_type_fullyqualname(NULL)
119+# CRASHES get_type_module_name(NULL)
120+# CRASHES get_type_name(object()): argument must be a type
121+# CRASHES get_type_qualname(object()): argument must be a type
122+# CRASHES get_type_fullyqualname(object()): argument must be a type
123+# CRASHES get_type_module_name(object()): argument must be a type
124+110125deftest_get_base_by_token(self):
111126defget_base_by_token(src, key, comparable=True):
112127defrun(use_mro):
@@ -215,7 +230,7 @@ class H2(int): pass
215230216231deftest_freeze(self):
217232# test PyType_Freeze()
218-type_freeze=_testcapi.type_freeze
233+type_freeze=_testlimitedcapi.type_freeze
219234220235# simple case, no inherante
221236classMyType:
@@ -245,12 +260,15 @@ class D(A, C): pass
245260# as well
246261type_freeze(D)
247262263+# CRASHES type_freeze(NULL)
264+# CRASHES type_freeze(object()): argument must be a type
249267Py_GIL_DISABLEDandrefleak_helper.hunting_for_refleaks(),
250268"Specialization failure triggers gh-127773")
251269deftest_freeze_meta(self):
252270"""test PyType_Freeze() with overridden MRO"""
253-type_freeze=_testcapi.type_freeze
271+type_freeze=_testlimitedcapi.type_freeze
254272255273classBase:
256274value=1
@@ -299,3 +317,181 @@ def test_extension_managed_weakref_nogc_type(self):
299317"flag but not Py_TPFLAGS_HAVE_GC flag")
300318withself.assertRaisesRegex(SystemError, msg):
301319_testcapi.create_managed_weakref_nogc_type()
320+321+deftest_type_ready(self):
322+# Test PyType_Ready(): calling it on initialized types
323+# must not raise an exception.
324+type_ready=_testlimitedcapi.type_ready
325+326+classHeapType:
327+pass
328+329+type_ready(int)
330+type_ready(dict)
331+type_ready(HeapType)
332+333+# CRASHES type_ready(NULL)
334+# CRASHES type_ready(123): argument must be a type
335+336+deftest_type_clearcache(self):
337+# Test PyType_ClearCache()
338+type_clearcache=_testlimitedcapi.type_clearcache
339+version_tag=type_clearcache()
340+self.assertEqual(type(version_tag), int)
341+self.assertGreaterEqual(version_tag, 0)
342+343+deftest_type_getflags(self):
344+# Test PyType_GetFlags()
345+type_getflags=_testlimitedcapi.type_getflags
346+347+from_testlimitedcapiimport (
348+Py_TPFLAGS_HEAPTYPE,
349+Py_TPFLAGS_HAVE_GC,
350+Py_TPFLAGS_HAVE_FINALIZE,
351+Py_TPFLAGS_HAVE_VERSION_TAG,
352+Py_TPFLAGS_VALID_VERSION_TAG,
353+Py_TPFLAGS_HAVE_VECTORCALL,
354+Py_TPFLAGS_DISALLOW_INSTANTIATION,
355+Py_TPFLAGS_IMMUTABLETYPE,
356+Py_TPFLAGS_READY,
357+Py_TPFLAGS_READYING,
358+Py_TPFLAGS_LONG_SUBCLASS,
359+Py_TPFLAGS_LIST_SUBCLASS,
360+Py_TPFLAGS_TUPLE_SUBCLASS,
361+Py_TPFLAGS_BYTES_SUBCLASS,
362+Py_TPFLAGS_UNICODE_SUBCLASS,
363+Py_TPFLAGS_DICT_SUBCLASS,
364+Py_TPFLAGS_BASE_EXC_SUBCLASS,
365+Py_TPFLAGS_TYPE_SUBCLASS,
366+Py_TPFLAGS_IS_ABSTRACT,
367+Py_TPFLAGS_BASETYPE,
368+_Py_TPFLAGS_MATCH_SELF,
369+Py_TPFLAGS_ITEMS_AT_END,
370+Py_TPFLAGS_METHOD_DESCRIPTOR,
371+ )
372+from_testcapiimport (
373+_Py_TPFLAGS_STATIC_BUILTIN,
374+Py_TPFLAGS_SEQUENCE,
375+Py_TPFLAGS_MAPPING,
376+Py_TPFLAGS_INLINE_VALUES,
377+Py_TPFLAGS_MANAGED_WEAKREF,
378+Py_TPFLAGS_MANAGED_DICT,
379+ )
380+381+defcheck_flag(flags, flag, expected):
382+self.assertEqual(bool(flags&flag), expected)
383+384+defcheck_subclasses(test_type, flags):
385+forflag, base_typein (
386+ (Py_TPFLAGS_LONG_SUBCLASS, int),
387+ (Py_TPFLAGS_LIST_SUBCLASS, list),
388+ (Py_TPFLAGS_TUPLE_SUBCLASS, tuple),
389+ (Py_TPFLAGS_BYTES_SUBCLASS, bytes),
390+ (Py_TPFLAGS_UNICODE_SUBCLASS, str),
391+ (Py_TPFLAGS_DICT_SUBCLASS, dict),
392+ (Py_TPFLAGS_BASE_EXC_SUBCLASS, BaseException),
393+ (Py_TPFLAGS_TYPE_SUBCLASS, type),
394+ ):
395+withself.subTest(test_type=test_type, flag=flag, base_type=base_type):
396+check_flag(flags, flag, issubclass(test_type, base_type))
397+398+defcheck_type(test_type, static_type, have_gc=False, have_vectorcall=False,
399+is_base_type=True, sequence=False, mapping=False,
400+match_self=True, items_at_end=False):
401+heap_type=notstatic_type
402+403+flags=type_getflags(test_type)
404+check_flag(flags, _Py_TPFLAGS_STATIC_BUILTIN, static_type)
405+check_flag(flags, Py_TPFLAGS_HEAPTYPE, heap_type)
406+check_flag(flags, Py_TPFLAGS_HAVE_GC, have_gc)
407+check_subclasses(test_type, flags)
408+check_flag(flags, Py_TPFLAGS_HAVE_VECTORCALL, have_vectorcall)
409+check_flag(flags, Py_TPFLAGS_DISALLOW_INSTANTIATION, False)
410+check_flag(flags, Py_TPFLAGS_IMMUTABLETYPE, static_type)
411+check_flag(flags, Py_TPFLAGS_READY, True)
412+check_flag(flags, Py_TPFLAGS_READYING, False)
413+check_flag(flags, Py_TPFLAGS_IS_ABSTRACT, False)
414+check_flag(flags, Py_TPFLAGS_BASETYPE, is_base_type)
415+check_flag(flags, Py_TPFLAGS_SEQUENCE, sequence)
416+check_flag(flags, Py_TPFLAGS_MAPPING, mapping)
417+418+check_flag(flags, Py_TPFLAGS_INLINE_VALUES, heap_type)
419+check_flag(flags, Py_TPFLAGS_MANAGED_WEAKREF, heap_type)
420+check_flag(flags, Py_TPFLAGS_MANAGED_DICT, heap_type)
421+check_flag(flags, Py_TPFLAGS_ITEMS_AT_END, items_at_end)
422+check_flag(flags, Py_TPFLAGS_METHOD_DESCRIPTOR, False)
423+424+check_flag(flags, _Py_TPFLAGS_MATCH_SELF, match_self)
425+426+# Flags kept for backward compatibility
427+check_flag(flags, Py_TPFLAGS_HAVE_FINALIZE, False)
428+check_flag(flags, Py_TPFLAGS_HAVE_VERSION_TAG, False)
429+check_flag(flags, Py_TPFLAGS_VALID_VERSION_TAG, False)
430+431+# Scalar types
432+check_type(int, static_type=True)
433+check_type(bool, static_type=True,
434+is_base_type=False)
435+check_type(float, static_type=True)
436+check_type(complex, static_type=True,
437+match_self=False)
438+check_type(bytes, static_type=True)
439+check_type(bytearray, static_type=True)
440+check_type(str, static_type=True)
441+442+# Collection types
443+check_type(tuple, static_type=True, have_gc=True,
444+sequence=True)
445+check_type(list, static_type=True, have_gc=True,
446+sequence=True)
447+check_type(dict, static_type=True, have_gc=True,
448+mapping=True)
449+check_type(frozendict, static_type=True, have_gc=True,
450+mapping=True)
451+check_type(set, static_type=True, have_gc=True)
452+check_type(frozenset, static_type=True, have_gc=True)
453+454+# Other types
455+check_type(BaseException, static_type=True, have_gc=True,
456+match_self=False)
457+check_type(type, static_type=True, have_gc=True,
458+have_vectorcall=True,
459+match_self=False,
460+items_at_end=True)
461+462+# Heap type
463+classHeapType:
464+pass
465+check_type(HeapType, static_type=False, have_gc=True, match_self=False)
466+467+# CRASHES type_getflags(NULL)
468+469+deftest_type_issubtype(self):
470+# Test PyType_IsSubtype()
471+_type_issubtype=_testlimitedcapi.type_issubtype
472+473+deftype_issubtype(type1, type2):
474+res=_type_issubtype(type1, type2)
475+self.assertIn(res, (0, 1))
476+returnbool(res)
477+478+classMyList(list):
479+pass
480+481+self.assertTrue(type_issubtype(bool, int))
482+self.assertTrue(type_issubtype(MyList, list))
483+484+self.assertFalse(type_issubtype(int, type))
485+self.assertFalse(type_issubtype(frozendict, dict))
486+self.assertFalse(type_issubtype(MyList, tuple))
487+488+deftest_type_modified(self):
489+# Test PyType_Modified()
490+type_modified=_testlimitedcapi.type_modified
491+492+classMyType:
493+pass
494+type_modified(MyType)
495+496+# CRASHES type_modified(NULL)
497+# CRASHES type_modified({}): argument must be a type