17db96d56Sopenharmony_ci# Run the _testcapi module tests (tests for the Python/C API): by defn, 27db96d56Sopenharmony_ci# these are all functions _testcapi exports whose name begins with 'test_'. 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_cifrom collections import OrderedDict 57db96d56Sopenharmony_ciimport _thread 67db96d56Sopenharmony_ciimport importlib.machinery 77db96d56Sopenharmony_ciimport importlib.util 87db96d56Sopenharmony_ciimport os 97db96d56Sopenharmony_ciimport pickle 107db96d56Sopenharmony_ciimport random 117db96d56Sopenharmony_ciimport re 127db96d56Sopenharmony_ciimport subprocess 137db96d56Sopenharmony_ciimport sys 147db96d56Sopenharmony_ciimport textwrap 157db96d56Sopenharmony_ciimport threading 167db96d56Sopenharmony_ciimport time 177db96d56Sopenharmony_ciimport unittest 187db96d56Sopenharmony_ciimport weakref 197db96d56Sopenharmony_cifrom test import support 207db96d56Sopenharmony_cifrom test.support import MISSING_C_DOCSTRINGS 217db96d56Sopenharmony_cifrom test.support import import_helper 227db96d56Sopenharmony_cifrom test.support import threading_helper 237db96d56Sopenharmony_cifrom test.support import warnings_helper 247db96d56Sopenharmony_cifrom test.support.script_helper import assert_python_failure, assert_python_ok 257db96d56Sopenharmony_citry: 267db96d56Sopenharmony_ci import _posixsubprocess 277db96d56Sopenharmony_ciexcept ImportError: 287db96d56Sopenharmony_ci _posixsubprocess = None 297db96d56Sopenharmony_citry: 307db96d56Sopenharmony_ci import _testmultiphase 317db96d56Sopenharmony_ciexcept ImportError: 327db96d56Sopenharmony_ci _testmultiphase = None 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci# Skip this test if the _testcapi module isn't available. 357db96d56Sopenharmony_ci_testcapi = import_helper.import_module('_testcapi') 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ciimport _testinternalcapi 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci# Were we compiled --with-pydebug or with #define Py_DEBUG? 407db96d56Sopenharmony_ciPy_DEBUG = hasattr(sys, 'gettotalrefcount') 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_cidef decode_stderr(err): 447db96d56Sopenharmony_ci return err.decode('utf-8', 'replace').replace('\r', '') 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cidef testfunction(self): 487db96d56Sopenharmony_ci """some doc""" 497db96d56Sopenharmony_ci return self 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ciclass InstanceMethod: 537db96d56Sopenharmony_ci id = _testcapi.instancemethod(id) 547db96d56Sopenharmony_ci testfunction = _testcapi.instancemethod(testfunction) 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ciclass CAPITest(unittest.TestCase): 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci def test_instancemethod(self): 597db96d56Sopenharmony_ci inst = InstanceMethod() 607db96d56Sopenharmony_ci self.assertEqual(id(inst), inst.id()) 617db96d56Sopenharmony_ci self.assertTrue(inst.testfunction() is inst) 627db96d56Sopenharmony_ci self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__) 637db96d56Sopenharmony_ci self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__) 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci InstanceMethod.testfunction.attribute = "test" 667db96d56Sopenharmony_ci self.assertEqual(testfunction.attribute, "test") 677db96d56Sopenharmony_ci self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci @support.requires_subprocess() 707db96d56Sopenharmony_ci def test_no_FatalError_infinite_loop(self): 717db96d56Sopenharmony_ci with support.SuppressCrashReport(): 727db96d56Sopenharmony_ci p = subprocess.Popen([sys.executable, "-c", 737db96d56Sopenharmony_ci 'import _testcapi;' 747db96d56Sopenharmony_ci '_testcapi.crash_no_current_thread()'], 757db96d56Sopenharmony_ci stdout=subprocess.PIPE, 767db96d56Sopenharmony_ci stderr=subprocess.PIPE) 777db96d56Sopenharmony_ci (out, err) = p.communicate() 787db96d56Sopenharmony_ci self.assertEqual(out, b'') 797db96d56Sopenharmony_ci # This used to cause an infinite loop. 807db96d56Sopenharmony_ci self.assertTrue(err.rstrip().startswith( 817db96d56Sopenharmony_ci b'Fatal Python error: ' 827db96d56Sopenharmony_ci b'PyThreadState_Get: ' 837db96d56Sopenharmony_ci b'the function must be called with the GIL held, ' 847db96d56Sopenharmony_ci b'but the GIL is released ' 857db96d56Sopenharmony_ci b'(the current Python thread state is NULL)'), 867db96d56Sopenharmony_ci err) 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci def test_memoryview_from_NULL_pointer(self): 897db96d56Sopenharmony_ci self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci def test_exception(self): 927db96d56Sopenharmony_ci raised_exception = ValueError("5") 937db96d56Sopenharmony_ci new_exc = TypeError("TEST") 947db96d56Sopenharmony_ci try: 957db96d56Sopenharmony_ci raise raised_exception 967db96d56Sopenharmony_ci except ValueError as e: 977db96d56Sopenharmony_ci orig_sys_exception = sys.exception() 987db96d56Sopenharmony_ci orig_exception = _testcapi.set_exception(new_exc) 997db96d56Sopenharmony_ci new_sys_exception = sys.exception() 1007db96d56Sopenharmony_ci new_exception = _testcapi.set_exception(orig_exception) 1017db96d56Sopenharmony_ci reset_sys_exception = sys.exception() 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci self.assertEqual(orig_exception, e) 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci self.assertEqual(orig_exception, raised_exception) 1067db96d56Sopenharmony_ci self.assertEqual(orig_sys_exception, orig_exception) 1077db96d56Sopenharmony_ci self.assertEqual(reset_sys_exception, orig_exception) 1087db96d56Sopenharmony_ci self.assertEqual(new_exception, new_exc) 1097db96d56Sopenharmony_ci self.assertEqual(new_sys_exception, new_exception) 1107db96d56Sopenharmony_ci else: 1117db96d56Sopenharmony_ci self.fail("Exception not raised") 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci def test_exc_info(self): 1147db96d56Sopenharmony_ci raised_exception = ValueError("5") 1157db96d56Sopenharmony_ci new_exc = TypeError("TEST") 1167db96d56Sopenharmony_ci try: 1177db96d56Sopenharmony_ci raise raised_exception 1187db96d56Sopenharmony_ci except ValueError as e: 1197db96d56Sopenharmony_ci tb = e.__traceback__ 1207db96d56Sopenharmony_ci orig_sys_exc_info = sys.exc_info() 1217db96d56Sopenharmony_ci orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None) 1227db96d56Sopenharmony_ci new_sys_exc_info = sys.exc_info() 1237db96d56Sopenharmony_ci new_exc_info = _testcapi.set_exc_info(*orig_exc_info) 1247db96d56Sopenharmony_ci reset_sys_exc_info = sys.exc_info() 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci self.assertEqual(orig_exc_info[1], e) 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb)) 1297db96d56Sopenharmony_ci self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info) 1307db96d56Sopenharmony_ci self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info) 1317db96d56Sopenharmony_ci self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None)) 1327db96d56Sopenharmony_ci self.assertSequenceEqual(new_sys_exc_info, new_exc_info) 1337db96d56Sopenharmony_ci else: 1347db96d56Sopenharmony_ci self.assertTrue(False) 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci def test_set_object(self): 1377db96d56Sopenharmony_ci # new exception as obj is not an exception 1387db96d56Sopenharmony_ci with self.assertRaises(ValueError) as e: 1397db96d56Sopenharmony_ci _testcapi.exc_set_object(ValueError, 42) 1407db96d56Sopenharmony_ci self.assertEqual(e.exception.args, (42,)) 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci # wraps the exception because unrelated types 1437db96d56Sopenharmony_ci with self.assertRaises(ValueError) as e: 1447db96d56Sopenharmony_ci _testcapi.exc_set_object(ValueError, TypeError(1,2,3)) 1457db96d56Sopenharmony_ci wrapped = e.exception.args[0] 1467db96d56Sopenharmony_ci self.assertIsInstance(wrapped, TypeError) 1477db96d56Sopenharmony_ci self.assertEqual(wrapped.args, (1, 2, 3)) 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci # is superclass, so does not wrap 1507db96d56Sopenharmony_ci with self.assertRaises(PermissionError) as e: 1517db96d56Sopenharmony_ci _testcapi.exc_set_object(OSError, PermissionError(24)) 1527db96d56Sopenharmony_ci self.assertEqual(e.exception.args, (24,)) 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci class Meta(type): 1557db96d56Sopenharmony_ci def __subclasscheck__(cls, sub): 1567db96d56Sopenharmony_ci 1/0 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci class Broken(Exception, metaclass=Meta): 1597db96d56Sopenharmony_ci pass 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci with self.assertRaises(ZeroDivisionError) as e: 1627db96d56Sopenharmony_ci _testcapi.exc_set_object(Broken, Broken()) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') 1657db96d56Sopenharmony_ci def test_seq_bytes_to_charp_array(self): 1667db96d56Sopenharmony_ci # Issue #15732: crash in _PySequence_BytesToCharpArray() 1677db96d56Sopenharmony_ci class Z(object): 1687db96d56Sopenharmony_ci def __len__(self): 1697db96d56Sopenharmony_ci return 1 1707db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'indexing'): 1717db96d56Sopenharmony_ci _posixsubprocess.fork_exec( 1727db96d56Sopenharmony_ci 1,Z(),True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) 1737db96d56Sopenharmony_ci # Issue #15736: overflow in _PySequence_BytesToCharpArray() 1747db96d56Sopenharmony_ci class Z(object): 1757db96d56Sopenharmony_ci def __len__(self): 1767db96d56Sopenharmony_ci return sys.maxsize 1777db96d56Sopenharmony_ci def __getitem__(self, i): 1787db96d56Sopenharmony_ci return b'x' 1797db96d56Sopenharmony_ci self.assertRaises(MemoryError, _posixsubprocess.fork_exec, 1807db96d56Sopenharmony_ci 1,Z(),True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') 1837db96d56Sopenharmony_ci def test_subprocess_fork_exec(self): 1847db96d56Sopenharmony_ci class Z(object): 1857db96d56Sopenharmony_ci def __len__(self): 1867db96d56Sopenharmony_ci return 1 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci # Issue #15738: crash in subprocess_fork_exec() 1897db96d56Sopenharmony_ci self.assertRaises(TypeError, _posixsubprocess.fork_exec, 1907db96d56Sopenharmony_ci Z(),[b'1'],True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci @unittest.skipIf(MISSING_C_DOCSTRINGS, 1937db96d56Sopenharmony_ci "Signature information for builtins requires docstrings") 1947db96d56Sopenharmony_ci def test_docstring_signature_parsing(self): 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci self.assertEqual(_testcapi.no_docstring.__doc__, None) 1977db96d56Sopenharmony_ci self.assertEqual(_testcapi.no_docstring.__text_signature__, None) 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_empty.__doc__, None) 2007db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_empty.__text_signature__, None) 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_no_signature.__doc__, 2037db96d56Sopenharmony_ci "This docstring has no signature.") 2047db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, 2077db96d56Sopenharmony_ci "docstring_with_invalid_signature($module, /, boo)\n" 2087db96d56Sopenharmony_ci "\n" 2097db96d56Sopenharmony_ci "This docstring has an invalid signature." 2107db96d56Sopenharmony_ci ) 2117db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__, 2147db96d56Sopenharmony_ci "docstring_with_invalid_signature2($module, /, boo)\n" 2157db96d56Sopenharmony_ci "\n" 2167db96d56Sopenharmony_ci "--\n" 2177db96d56Sopenharmony_ci "\n" 2187db96d56Sopenharmony_ci "This docstring also has an invalid signature." 2197db96d56Sopenharmony_ci ) 2207db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None) 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature.__doc__, 2237db96d56Sopenharmony_ci "This docstring has a valid signature.") 2247db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)") 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None) 2277db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__, 2287db96d56Sopenharmony_ci "($module, /, sig)") 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, 2317db96d56Sopenharmony_ci "\nThis docstring has a valid signature and some extra newlines.") 2327db96d56Sopenharmony_ci self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, 2337db96d56Sopenharmony_ci "($module, /, parameter)") 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci def test_c_type_with_matrix_multiplication(self): 2367db96d56Sopenharmony_ci M = _testcapi.matmulType 2377db96d56Sopenharmony_ci m1 = M() 2387db96d56Sopenharmony_ci m2 = M() 2397db96d56Sopenharmony_ci self.assertEqual(m1 @ m2, ("matmul", m1, m2)) 2407db96d56Sopenharmony_ci self.assertEqual(m1 @ 42, ("matmul", m1, 42)) 2417db96d56Sopenharmony_ci self.assertEqual(42 @ m1, ("matmul", 42, m1)) 2427db96d56Sopenharmony_ci o = m1 2437db96d56Sopenharmony_ci o @= m2 2447db96d56Sopenharmony_ci self.assertEqual(o, ("imatmul", m1, m2)) 2457db96d56Sopenharmony_ci o = m1 2467db96d56Sopenharmony_ci o @= 42 2477db96d56Sopenharmony_ci self.assertEqual(o, ("imatmul", m1, 42)) 2487db96d56Sopenharmony_ci o = 42 2497db96d56Sopenharmony_ci o @= m1 2507db96d56Sopenharmony_ci self.assertEqual(o, ("matmul", 42, m1)) 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci def test_c_type_with_ipow(self): 2537db96d56Sopenharmony_ci # When the __ipow__ method of a type was implemented in C, using the 2547db96d56Sopenharmony_ci # modulo param would cause segfaults. 2557db96d56Sopenharmony_ci o = _testcapi.ipowType() 2567db96d56Sopenharmony_ci self.assertEqual(o.__ipow__(1), (1, None)) 2577db96d56Sopenharmony_ci self.assertEqual(o.__ipow__(2, 2), (2, 2)) 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci def test_return_null_without_error(self): 2607db96d56Sopenharmony_ci # Issue #23571: A function must not return NULL without setting an 2617db96d56Sopenharmony_ci # error 2627db96d56Sopenharmony_ci if Py_DEBUG: 2637db96d56Sopenharmony_ci code = textwrap.dedent(""" 2647db96d56Sopenharmony_ci import _testcapi 2657db96d56Sopenharmony_ci from test import support 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci with support.SuppressCrashReport(): 2687db96d56Sopenharmony_ci _testcapi.return_null_without_error() 2697db96d56Sopenharmony_ci """) 2707db96d56Sopenharmony_ci rc, out, err = assert_python_failure('-c', code) 2717db96d56Sopenharmony_ci err = decode_stderr(err) 2727db96d56Sopenharmony_ci self.assertRegex(err, 2737db96d56Sopenharmony_ci r'Fatal Python error: _Py_CheckFunctionResult: ' 2747db96d56Sopenharmony_ci r'a function returned NULL without setting an exception\n' 2757db96d56Sopenharmony_ci r'Python runtime state: initialized\n' 2767db96d56Sopenharmony_ci r'SystemError: <built-in function return_null_without_error> ' 2777db96d56Sopenharmony_ci r'returned NULL without setting an exception\n' 2787db96d56Sopenharmony_ci r'\n' 2797db96d56Sopenharmony_ci r'Current thread.*:\n' 2807db96d56Sopenharmony_ci r' File .*", line 6 in <module>\n') 2817db96d56Sopenharmony_ci else: 2827db96d56Sopenharmony_ci with self.assertRaises(SystemError) as cm: 2837db96d56Sopenharmony_ci _testcapi.return_null_without_error() 2847db96d56Sopenharmony_ci self.assertRegex(str(cm.exception), 2857db96d56Sopenharmony_ci 'return_null_without_error.* ' 2867db96d56Sopenharmony_ci 'returned NULL without setting an exception') 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci def test_return_result_with_error(self): 2897db96d56Sopenharmony_ci # Issue #23571: A function must not return a result with an error set 2907db96d56Sopenharmony_ci if Py_DEBUG: 2917db96d56Sopenharmony_ci code = textwrap.dedent(""" 2927db96d56Sopenharmony_ci import _testcapi 2937db96d56Sopenharmony_ci from test import support 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci with support.SuppressCrashReport(): 2967db96d56Sopenharmony_ci _testcapi.return_result_with_error() 2977db96d56Sopenharmony_ci """) 2987db96d56Sopenharmony_ci rc, out, err = assert_python_failure('-c', code) 2997db96d56Sopenharmony_ci err = decode_stderr(err) 3007db96d56Sopenharmony_ci self.assertRegex(err, 3017db96d56Sopenharmony_ci r'Fatal Python error: _Py_CheckFunctionResult: ' 3027db96d56Sopenharmony_ci r'a function returned a result with an exception set\n' 3037db96d56Sopenharmony_ci r'Python runtime state: initialized\n' 3047db96d56Sopenharmony_ci r'ValueError\n' 3057db96d56Sopenharmony_ci r'\n' 3067db96d56Sopenharmony_ci r'The above exception was the direct cause ' 3077db96d56Sopenharmony_ci r'of the following exception:\n' 3087db96d56Sopenharmony_ci r'\n' 3097db96d56Sopenharmony_ci r'SystemError: <built-in ' 3107db96d56Sopenharmony_ci r'function return_result_with_error> ' 3117db96d56Sopenharmony_ci r'returned a result with an exception set\n' 3127db96d56Sopenharmony_ci r'\n' 3137db96d56Sopenharmony_ci r'Current thread.*:\n' 3147db96d56Sopenharmony_ci r' File .*, line 6 in <module>\n') 3157db96d56Sopenharmony_ci else: 3167db96d56Sopenharmony_ci with self.assertRaises(SystemError) as cm: 3177db96d56Sopenharmony_ci _testcapi.return_result_with_error() 3187db96d56Sopenharmony_ci self.assertRegex(str(cm.exception), 3197db96d56Sopenharmony_ci 'return_result_with_error.* ' 3207db96d56Sopenharmony_ci 'returned a result with an exception set') 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci def test_getitem_with_error(self): 3237db96d56Sopenharmony_ci # Test _Py_CheckSlotResult(). Raise an exception and then calls 3247db96d56Sopenharmony_ci # PyObject_GetItem(): check that the assertion catches the bug. 3257db96d56Sopenharmony_ci # PyObject_GetItem() must not be called with an exception set. 3267db96d56Sopenharmony_ci code = textwrap.dedent(""" 3277db96d56Sopenharmony_ci import _testcapi 3287db96d56Sopenharmony_ci from test import support 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci with support.SuppressCrashReport(): 3317db96d56Sopenharmony_ci _testcapi.getitem_with_error({1: 2}, 1) 3327db96d56Sopenharmony_ci """) 3337db96d56Sopenharmony_ci rc, out, err = assert_python_failure('-c', code) 3347db96d56Sopenharmony_ci err = decode_stderr(err) 3357db96d56Sopenharmony_ci if 'SystemError: ' not in err: 3367db96d56Sopenharmony_ci self.assertRegex(err, 3377db96d56Sopenharmony_ci r'Fatal Python error: _Py_CheckSlotResult: ' 3387db96d56Sopenharmony_ci r'Slot __getitem__ of type dict succeeded ' 3397db96d56Sopenharmony_ci r'with an exception set\n' 3407db96d56Sopenharmony_ci r'Python runtime state: initialized\n' 3417db96d56Sopenharmony_ci r'ValueError: bug\n' 3427db96d56Sopenharmony_ci r'\n' 3437db96d56Sopenharmony_ci r'Current thread .* \(most recent call first\):\n' 3447db96d56Sopenharmony_ci r' File .*, line 6 in <module>\n' 3457db96d56Sopenharmony_ci r'\n' 3467db96d56Sopenharmony_ci r'Extension modules: _testcapi \(total: 1\)\n') 3477db96d56Sopenharmony_ci else: 3487db96d56Sopenharmony_ci # Python built with NDEBUG macro defined: 3497db96d56Sopenharmony_ci # test _Py_CheckFunctionResult() instead. 3507db96d56Sopenharmony_ci self.assertIn('returned a result with an exception set', err) 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ci def test_buildvalue_N(self): 3537db96d56Sopenharmony_ci _testcapi.test_buildvalue_N() 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_ci def test_set_nomemory(self): 3567db96d56Sopenharmony_ci code = """if 1: 3577db96d56Sopenharmony_ci import _testcapi 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci class C(): pass 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci # The first loop tests both functions and that remove_mem_hooks() 3627db96d56Sopenharmony_ci # can be called twice in a row. The second loop checks a call to 3637db96d56Sopenharmony_ci # set_nomemory() after a call to remove_mem_hooks(). The third 3647db96d56Sopenharmony_ci # loop checks the start and stop arguments of set_nomemory(). 3657db96d56Sopenharmony_ci for outer_cnt in range(1, 4): 3667db96d56Sopenharmony_ci start = 10 * outer_cnt 3677db96d56Sopenharmony_ci for j in range(100): 3687db96d56Sopenharmony_ci if j == 0: 3697db96d56Sopenharmony_ci if outer_cnt != 3: 3707db96d56Sopenharmony_ci _testcapi.set_nomemory(start) 3717db96d56Sopenharmony_ci else: 3727db96d56Sopenharmony_ci _testcapi.set_nomemory(start, start + 1) 3737db96d56Sopenharmony_ci try: 3747db96d56Sopenharmony_ci C() 3757db96d56Sopenharmony_ci except MemoryError as e: 3767db96d56Sopenharmony_ci if outer_cnt != 3: 3777db96d56Sopenharmony_ci _testcapi.remove_mem_hooks() 3787db96d56Sopenharmony_ci print('MemoryError', outer_cnt, j) 3797db96d56Sopenharmony_ci _testcapi.remove_mem_hooks() 3807db96d56Sopenharmony_ci break 3817db96d56Sopenharmony_ci """ 3827db96d56Sopenharmony_ci rc, out, err = assert_python_ok('-c', code) 3837db96d56Sopenharmony_ci lines = out.splitlines() 3847db96d56Sopenharmony_ci for i, line in enumerate(lines, 1): 3857db96d56Sopenharmony_ci self.assertIn(b'MemoryError', out) 3867db96d56Sopenharmony_ci *_, count = line.split(b' ') 3877db96d56Sopenharmony_ci count = int(count) 3887db96d56Sopenharmony_ci self.assertLessEqual(count, i*5) 3897db96d56Sopenharmony_ci self.assertGreaterEqual(count, i*5-2) 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci def test_mapping_keys_values_items(self): 3927db96d56Sopenharmony_ci class Mapping1(dict): 3937db96d56Sopenharmony_ci def keys(self): 3947db96d56Sopenharmony_ci return list(super().keys()) 3957db96d56Sopenharmony_ci def values(self): 3967db96d56Sopenharmony_ci return list(super().values()) 3977db96d56Sopenharmony_ci def items(self): 3987db96d56Sopenharmony_ci return list(super().items()) 3997db96d56Sopenharmony_ci class Mapping2(dict): 4007db96d56Sopenharmony_ci def keys(self): 4017db96d56Sopenharmony_ci return tuple(super().keys()) 4027db96d56Sopenharmony_ci def values(self): 4037db96d56Sopenharmony_ci return tuple(super().values()) 4047db96d56Sopenharmony_ci def items(self): 4057db96d56Sopenharmony_ci return tuple(super().items()) 4067db96d56Sopenharmony_ci dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), 4097db96d56Sopenharmony_ci dict_obj, OrderedDict(dict_obj), 4107db96d56Sopenharmony_ci Mapping1(dict_obj), Mapping2(dict_obj)]: 4117db96d56Sopenharmony_ci self.assertListEqual(_testcapi.get_mapping_keys(mapping), 4127db96d56Sopenharmony_ci list(mapping.keys())) 4137db96d56Sopenharmony_ci self.assertListEqual(_testcapi.get_mapping_values(mapping), 4147db96d56Sopenharmony_ci list(mapping.values())) 4157db96d56Sopenharmony_ci self.assertListEqual(_testcapi.get_mapping_items(mapping), 4167db96d56Sopenharmony_ci list(mapping.items())) 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci def test_mapping_keys_values_items_bad_arg(self): 4197db96d56Sopenharmony_ci self.assertRaises(AttributeError, _testcapi.get_mapping_keys, None) 4207db96d56Sopenharmony_ci self.assertRaises(AttributeError, _testcapi.get_mapping_values, None) 4217db96d56Sopenharmony_ci self.assertRaises(AttributeError, _testcapi.get_mapping_items, None) 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci class BadMapping: 4247db96d56Sopenharmony_ci def keys(self): 4257db96d56Sopenharmony_ci return None 4267db96d56Sopenharmony_ci def values(self): 4277db96d56Sopenharmony_ci return None 4287db96d56Sopenharmony_ci def items(self): 4297db96d56Sopenharmony_ci return None 4307db96d56Sopenharmony_ci bad_mapping = BadMapping() 4317db96d56Sopenharmony_ci self.assertRaises(TypeError, _testcapi.get_mapping_keys, bad_mapping) 4327db96d56Sopenharmony_ci self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping) 4337db96d56Sopenharmony_ci self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping) 4347db96d56Sopenharmony_ci 4357db96d56Sopenharmony_ci def test_mapping_has_key(self): 4367db96d56Sopenharmony_ci dct = {'a': 1} 4377db96d56Sopenharmony_ci self.assertTrue(_testcapi.mapping_has_key(dct, 'a')) 4387db96d56Sopenharmony_ci self.assertFalse(_testcapi.mapping_has_key(dct, 'b')) 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ci class SubDict(dict): 4417db96d56Sopenharmony_ci pass 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci dct2 = SubDict({'a': 1}) 4447db96d56Sopenharmony_ci self.assertTrue(_testcapi.mapping_has_key(dct2, 'a')) 4457db96d56Sopenharmony_ci self.assertFalse(_testcapi.mapping_has_key(dct2, 'b')) 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci def test_sequence_set_slice(self): 4487db96d56Sopenharmony_ci # Correct case: 4497db96d56Sopenharmony_ci data = [1, 2, 3, 4, 5] 4507db96d56Sopenharmony_ci data_copy = data.copy() 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci _testcapi.sequence_set_slice(data, 1, 3, [8, 9]) 4537db96d56Sopenharmony_ci data_copy[1:3] = [8, 9] 4547db96d56Sopenharmony_ci self.assertEqual(data, data_copy) 4557db96d56Sopenharmony_ci self.assertEqual(data, [1, 8, 9, 4, 5]) 4567db96d56Sopenharmony_ci 4577db96d56Sopenharmony_ci # Custom class: 4587db96d56Sopenharmony_ci class Custom: 4597db96d56Sopenharmony_ci def __setitem__(self, index, value): 4607db96d56Sopenharmony_ci self.index = index 4617db96d56Sopenharmony_ci self.value = value 4627db96d56Sopenharmony_ci 4637db96d56Sopenharmony_ci c = Custom() 4647db96d56Sopenharmony_ci _testcapi.sequence_set_slice(c, 0, 5, 'abc') 4657db96d56Sopenharmony_ci self.assertEqual(c.index, slice(0, 5)) 4667db96d56Sopenharmony_ci self.assertEqual(c.value, 'abc') 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci # Immutable sequences must raise: 4697db96d56Sopenharmony_ci bad_seq1 = (1, 2, 3, 4) 4707db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4717db96d56Sopenharmony_ci _testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9)) 4727db96d56Sopenharmony_ci self.assertEqual(bad_seq1, (1, 2, 3, 4)) 4737db96d56Sopenharmony_ci 4747db96d56Sopenharmony_ci bad_seq2 = 'abcd' 4757db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4767db96d56Sopenharmony_ci _testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy') 4777db96d56Sopenharmony_ci self.assertEqual(bad_seq2, 'abcd') 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci # Not a sequence: 4807db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4817db96d56Sopenharmony_ci _testcapi.sequence_set_slice(None, 1, 3, 'xy') 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_ci mapping = {1: 'a', 2: 'b', 3: 'c'} 4847db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4857db96d56Sopenharmony_ci _testcapi.sequence_set_slice(mapping, 1, 3, 'xy') 4867db96d56Sopenharmony_ci self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci def test_sequence_del_slice(self): 4897db96d56Sopenharmony_ci # Correct case: 4907db96d56Sopenharmony_ci data = [1, 2, 3, 4, 5] 4917db96d56Sopenharmony_ci data_copy = data.copy() 4927db96d56Sopenharmony_ci 4937db96d56Sopenharmony_ci _testcapi.sequence_del_slice(data, 1, 3) 4947db96d56Sopenharmony_ci del data_copy[1:3] 4957db96d56Sopenharmony_ci self.assertEqual(data, data_copy) 4967db96d56Sopenharmony_ci self.assertEqual(data, [1, 4, 5]) 4977db96d56Sopenharmony_ci 4987db96d56Sopenharmony_ci # Custom class: 4997db96d56Sopenharmony_ci class Custom: 5007db96d56Sopenharmony_ci def __delitem__(self, index): 5017db96d56Sopenharmony_ci self.index = index 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci c = Custom() 5047db96d56Sopenharmony_ci _testcapi.sequence_del_slice(c, 0, 5) 5057db96d56Sopenharmony_ci self.assertEqual(c.index, slice(0, 5)) 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_ci # Immutable sequences must raise: 5087db96d56Sopenharmony_ci bad_seq1 = (1, 2, 3, 4) 5097db96d56Sopenharmony_ci with self.assertRaises(TypeError): 5107db96d56Sopenharmony_ci _testcapi.sequence_del_slice(bad_seq1, 1, 3) 5117db96d56Sopenharmony_ci self.assertEqual(bad_seq1, (1, 2, 3, 4)) 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ci bad_seq2 = 'abcd' 5147db96d56Sopenharmony_ci with self.assertRaises(TypeError): 5157db96d56Sopenharmony_ci _testcapi.sequence_del_slice(bad_seq2, 1, 3) 5167db96d56Sopenharmony_ci self.assertEqual(bad_seq2, 'abcd') 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_ci # Not a sequence: 5197db96d56Sopenharmony_ci with self.assertRaises(TypeError): 5207db96d56Sopenharmony_ci _testcapi.sequence_del_slice(None, 1, 3) 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ci mapping = {1: 'a', 2: 'b', 3: 'c'} 5237db96d56Sopenharmony_ci with self.assertRaises(TypeError): 5247db96d56Sopenharmony_ci _testcapi.sequence_del_slice(mapping, 1, 3) 5257db96d56Sopenharmony_ci self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), 5287db96d56Sopenharmony_ci 'need _testcapi.negative_refcount') 5297db96d56Sopenharmony_ci def test_negative_refcount(self): 5307db96d56Sopenharmony_ci # bpo-35059: Check that Py_DECREF() reports the correct filename 5317db96d56Sopenharmony_ci # when calling _Py_NegativeRefcount() to abort Python. 5327db96d56Sopenharmony_ci code = textwrap.dedent(""" 5337db96d56Sopenharmony_ci import _testcapi 5347db96d56Sopenharmony_ci from test import support 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci with support.SuppressCrashReport(): 5377db96d56Sopenharmony_ci _testcapi.negative_refcount() 5387db96d56Sopenharmony_ci """) 5397db96d56Sopenharmony_ci rc, out, err = assert_python_failure('-c', code) 5407db96d56Sopenharmony_ci self.assertRegex(err, 5417db96d56Sopenharmony_ci br'_testcapimodule\.c:[0-9]+: ' 5427db96d56Sopenharmony_ci br'_Py_NegativeRefcount: Assertion failed: ' 5437db96d56Sopenharmony_ci br'object has negative ref count') 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci def test_trashcan_subclass(self): 5467db96d56Sopenharmony_ci # bpo-35983: Check that the trashcan mechanism for "list" is NOT 5477db96d56Sopenharmony_ci # activated when its tp_dealloc is being called by a subclass 5487db96d56Sopenharmony_ci from _testcapi import MyList 5497db96d56Sopenharmony_ci L = None 5507db96d56Sopenharmony_ci for i in range(1000): 5517db96d56Sopenharmony_ci L = MyList((L,)) 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_ci @support.requires_resource('cpu') 5547db96d56Sopenharmony_ci def test_trashcan_python_class1(self): 5557db96d56Sopenharmony_ci self.do_test_trashcan_python_class(list) 5567db96d56Sopenharmony_ci 5577db96d56Sopenharmony_ci @support.requires_resource('cpu') 5587db96d56Sopenharmony_ci def test_trashcan_python_class2(self): 5597db96d56Sopenharmony_ci from _testcapi import MyList 5607db96d56Sopenharmony_ci self.do_test_trashcan_python_class(MyList) 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_ci def do_test_trashcan_python_class(self, base): 5637db96d56Sopenharmony_ci # Check that the trashcan mechanism works properly for a Python 5647db96d56Sopenharmony_ci # subclass of a class using the trashcan (this specific test assumes 5657db96d56Sopenharmony_ci # that the base class "base" behaves like list) 5667db96d56Sopenharmony_ci class PyList(base): 5677db96d56Sopenharmony_ci # Count the number of PyList instances to verify that there is 5687db96d56Sopenharmony_ci # no memory leak 5697db96d56Sopenharmony_ci num = 0 5707db96d56Sopenharmony_ci def __init__(self, *args): 5717db96d56Sopenharmony_ci __class__.num += 1 5727db96d56Sopenharmony_ci super().__init__(*args) 5737db96d56Sopenharmony_ci def __del__(self): 5747db96d56Sopenharmony_ci __class__.num -= 1 5757db96d56Sopenharmony_ci 5767db96d56Sopenharmony_ci for parity in (0, 1): 5777db96d56Sopenharmony_ci L = None 5787db96d56Sopenharmony_ci # We need in the order of 2**20 iterations here such that a 5797db96d56Sopenharmony_ci # typical 8MB stack would overflow without the trashcan. 5807db96d56Sopenharmony_ci for i in range(2**20): 5817db96d56Sopenharmony_ci L = PyList((L,)) 5827db96d56Sopenharmony_ci L.attr = i 5837db96d56Sopenharmony_ci if parity: 5847db96d56Sopenharmony_ci # Add one additional nesting layer 5857db96d56Sopenharmony_ci L = (L,) 5867db96d56Sopenharmony_ci self.assertGreater(PyList.num, 0) 5877db96d56Sopenharmony_ci del L 5887db96d56Sopenharmony_ci self.assertEqual(PyList.num, 0) 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_ci def test_heap_ctype_doc_and_text_signature(self): 5917db96d56Sopenharmony_ci self.assertEqual(_testcapi.HeapDocCType.__doc__, "somedoc") 5927db96d56Sopenharmony_ci self.assertEqual(_testcapi.HeapDocCType.__text_signature__, "(arg1, arg2)") 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ci def test_null_type_doc(self): 5957db96d56Sopenharmony_ci self.assertEqual(_testcapi.NullTpDocType.__doc__, None) 5967db96d56Sopenharmony_ci 5977db96d56Sopenharmony_ci def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self): 5987db96d56Sopenharmony_ci class HeapGcCTypeSubclass(_testcapi.HeapGcCType): 5997db96d56Sopenharmony_ci def __init__(self): 6007db96d56Sopenharmony_ci self.value2 = 20 6017db96d56Sopenharmony_ci super().__init__() 6027db96d56Sopenharmony_ci 6037db96d56Sopenharmony_ci subclass_instance = HeapGcCTypeSubclass() 6047db96d56Sopenharmony_ci type_refcnt = sys.getrefcount(HeapGcCTypeSubclass) 6057db96d56Sopenharmony_ci 6067db96d56Sopenharmony_ci # Test that subclass instance was fully created 6077db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value, 10) 6087db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value2, 20) 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ci # Test that the type reference count is only decremented once 6117db96d56Sopenharmony_ci del subclass_instance 6127db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, sys.getrefcount(HeapGcCTypeSubclass)) 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci def test_subclass_of_heap_gc_ctype_with_del_modifying_dunder_class_only_decrefs_once(self): 6157db96d56Sopenharmony_ci class A(_testcapi.HeapGcCType): 6167db96d56Sopenharmony_ci def __init__(self): 6177db96d56Sopenharmony_ci self.value2 = 20 6187db96d56Sopenharmony_ci super().__init__() 6197db96d56Sopenharmony_ci 6207db96d56Sopenharmony_ci class B(A): 6217db96d56Sopenharmony_ci def __init__(self): 6227db96d56Sopenharmony_ci super().__init__() 6237db96d56Sopenharmony_ci 6247db96d56Sopenharmony_ci def __del__(self): 6257db96d56Sopenharmony_ci self.__class__ = A 6267db96d56Sopenharmony_ci A.refcnt_in_del = sys.getrefcount(A) 6277db96d56Sopenharmony_ci B.refcnt_in_del = sys.getrefcount(B) 6287db96d56Sopenharmony_ci 6297db96d56Sopenharmony_ci subclass_instance = B() 6307db96d56Sopenharmony_ci type_refcnt = sys.getrefcount(B) 6317db96d56Sopenharmony_ci new_type_refcnt = sys.getrefcount(A) 6327db96d56Sopenharmony_ci 6337db96d56Sopenharmony_ci # Test that subclass instance was fully created 6347db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value, 10) 6357db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value2, 20) 6367db96d56Sopenharmony_ci 6377db96d56Sopenharmony_ci del subclass_instance 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci # Test that setting __class__ modified the reference counts of the types 6407db96d56Sopenharmony_ci if Py_DEBUG: 6417db96d56Sopenharmony_ci # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference 6427db96d56Sopenharmony_ci # to the type while calling tp_dealloc() 6437db96d56Sopenharmony_ci self.assertEqual(type_refcnt, B.refcnt_in_del) 6447db96d56Sopenharmony_ci else: 6457db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, B.refcnt_in_del) 6467db96d56Sopenharmony_ci self.assertEqual(new_type_refcnt + 1, A.refcnt_in_del) 6477db96d56Sopenharmony_ci 6487db96d56Sopenharmony_ci # Test that the original type already has decreased its refcnt 6497db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, sys.getrefcount(B)) 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ci # Test that subtype_dealloc decref the newly assigned __class__ only once 6527db96d56Sopenharmony_ci self.assertEqual(new_type_refcnt, sys.getrefcount(A)) 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_ci def test_heaptype_with_dict(self): 6557db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithDict() 6567db96d56Sopenharmony_ci inst.foo = 42 6577db96d56Sopenharmony_ci self.assertEqual(inst.foo, 42) 6587db96d56Sopenharmony_ci self.assertEqual(inst.dictobj, inst.__dict__) 6597db96d56Sopenharmony_ci self.assertEqual(inst.dictobj, {"foo": 42}) 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithDict() 6627db96d56Sopenharmony_ci self.assertEqual({}, inst.__dict__) 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_ci def test_heaptype_with_negative_dict(self): 6657db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithNegativeDict() 6667db96d56Sopenharmony_ci inst.foo = 42 6677db96d56Sopenharmony_ci self.assertEqual(inst.foo, 42) 6687db96d56Sopenharmony_ci self.assertEqual(inst.dictobj, inst.__dict__) 6697db96d56Sopenharmony_ci self.assertEqual(inst.dictobj, {"foo": 42}) 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithNegativeDict() 6727db96d56Sopenharmony_ci self.assertEqual({}, inst.__dict__) 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ci def test_heaptype_with_weakref(self): 6757db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithWeakref() 6767db96d56Sopenharmony_ci ref = weakref.ref(inst) 6777db96d56Sopenharmony_ci self.assertEqual(ref(), inst) 6787db96d56Sopenharmony_ci self.assertEqual(inst.weakreflist, ref) 6797db96d56Sopenharmony_ci 6807db96d56Sopenharmony_ci def test_heaptype_with_buffer(self): 6817db96d56Sopenharmony_ci inst = _testcapi.HeapCTypeWithBuffer() 6827db96d56Sopenharmony_ci b = bytes(inst) 6837db96d56Sopenharmony_ci self.assertEqual(b, b"1234") 6847db96d56Sopenharmony_ci 6857db96d56Sopenharmony_ci def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self): 6867db96d56Sopenharmony_ci subclass_instance = _testcapi.HeapCTypeSubclass() 6877db96d56Sopenharmony_ci type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass) 6887db96d56Sopenharmony_ci 6897db96d56Sopenharmony_ci # Test that subclass instance was fully created 6907db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value, 10) 6917db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value2, 20) 6927db96d56Sopenharmony_ci 6937db96d56Sopenharmony_ci # Test that the type reference count is only decremented once 6947db96d56Sopenharmony_ci del subclass_instance 6957db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, sys.getrefcount(_testcapi.HeapCTypeSubclass)) 6967db96d56Sopenharmony_ci 6977db96d56Sopenharmony_ci def test_c_subclass_of_heap_ctype_with_del_modifying_dunder_class_only_decrefs_once(self): 6987db96d56Sopenharmony_ci subclass_instance = _testcapi.HeapCTypeSubclassWithFinalizer() 6997db96d56Sopenharmony_ci type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclassWithFinalizer) 7007db96d56Sopenharmony_ci new_type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass) 7017db96d56Sopenharmony_ci 7027db96d56Sopenharmony_ci # Test that subclass instance was fully created 7037db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value, 10) 7047db96d56Sopenharmony_ci self.assertEqual(subclass_instance.value2, 20) 7057db96d56Sopenharmony_ci 7067db96d56Sopenharmony_ci # The tp_finalize slot will set __class__ to HeapCTypeSubclass 7077db96d56Sopenharmony_ci del subclass_instance 7087db96d56Sopenharmony_ci 7097db96d56Sopenharmony_ci # Test that setting __class__ modified the reference counts of the types 7107db96d56Sopenharmony_ci if Py_DEBUG: 7117db96d56Sopenharmony_ci # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference 7127db96d56Sopenharmony_ci # to the type while calling tp_dealloc() 7137db96d56Sopenharmony_ci self.assertEqual(type_refcnt, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) 7147db96d56Sopenharmony_ci else: 7157db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) 7167db96d56Sopenharmony_ci self.assertEqual(new_type_refcnt + 1, _testcapi.HeapCTypeSubclass.refcnt_in_del) 7177db96d56Sopenharmony_ci 7187db96d56Sopenharmony_ci # Test that the original type already has decreased its refcnt 7197db96d56Sopenharmony_ci self.assertEqual(type_refcnt - 1, sys.getrefcount(_testcapi.HeapCTypeSubclassWithFinalizer)) 7207db96d56Sopenharmony_ci 7217db96d56Sopenharmony_ci # Test that subtype_dealloc decref the newly assigned __class__ only once 7227db96d56Sopenharmony_ci self.assertEqual(new_type_refcnt, sys.getrefcount(_testcapi.HeapCTypeSubclass)) 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci def test_heaptype_with_setattro(self): 7257db96d56Sopenharmony_ci obj = _testcapi.HeapCTypeSetattr() 7267db96d56Sopenharmony_ci self.assertEqual(obj.pvalue, 10) 7277db96d56Sopenharmony_ci obj.value = 12 7287db96d56Sopenharmony_ci self.assertEqual(obj.pvalue, 12) 7297db96d56Sopenharmony_ci del obj.value 7307db96d56Sopenharmony_ci self.assertEqual(obj.pvalue, 0) 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): 7337db96d56Sopenharmony_ci 7347db96d56Sopenharmony_ci class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): 7357db96d56Sopenharmony_ci pass 7367db96d56Sopenharmony_ci class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): 7377db96d56Sopenharmony_ci pass 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci for cls in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, 7407db96d56Sopenharmony_ci _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): 7417db96d56Sopenharmony_ci for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, 7427db96d56Sopenharmony_ci _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): 7437db96d56Sopenharmony_ci if cls is not cls2: 7447db96d56Sopenharmony_ci class S(cls, cls2): 7457db96d56Sopenharmony_ci pass 7467db96d56Sopenharmony_ci class B1(Both1, cls): 7477db96d56Sopenharmony_ci pass 7487db96d56Sopenharmony_ci class B2(Both1, cls): 7497db96d56Sopenharmony_ci pass 7507db96d56Sopenharmony_ci 7517db96d56Sopenharmony_ci def test_pynumber_tobase(self): 7527db96d56Sopenharmony_ci from _testcapi import pynumber_tobase 7537db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(123, 2), '0b1111011') 7547db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(123, 8), '0o173') 7557db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(123, 10), '123') 7567db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(123, 16), '0x7b') 7577db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(-123, 2), '-0b1111011') 7587db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(-123, 8), '-0o173') 7597db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(-123, 10), '-123') 7607db96d56Sopenharmony_ci self.assertEqual(pynumber_tobase(-123, 16), '-0x7b') 7617db96d56Sopenharmony_ci self.assertRaises(TypeError, pynumber_tobase, 123.0, 10) 7627db96d56Sopenharmony_ci self.assertRaises(TypeError, pynumber_tobase, '123', 10) 7637db96d56Sopenharmony_ci self.assertRaises(SystemError, pynumber_tobase, 123, 0) 7647db96d56Sopenharmony_ci 7657db96d56Sopenharmony_ci def check_fatal_error(self, code, expected, not_expected=()): 7667db96d56Sopenharmony_ci with support.SuppressCrashReport(): 7677db96d56Sopenharmony_ci rc, out, err = assert_python_failure('-sSI', '-c', code) 7687db96d56Sopenharmony_ci 7697db96d56Sopenharmony_ci err = decode_stderr(err) 7707db96d56Sopenharmony_ci self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n', 7717db96d56Sopenharmony_ci err) 7727db96d56Sopenharmony_ci 7737db96d56Sopenharmony_ci match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$', 7747db96d56Sopenharmony_ci err, re.MULTILINE) 7757db96d56Sopenharmony_ci if not match: 7767db96d56Sopenharmony_ci self.fail(f"Cannot find 'Extension modules:' in {err!r}") 7777db96d56Sopenharmony_ci modules = set(match.group(1).strip().split(', ')) 7787db96d56Sopenharmony_ci total = int(match.group(2)) 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci for name in expected: 7817db96d56Sopenharmony_ci self.assertIn(name, modules) 7827db96d56Sopenharmony_ci for name in not_expected: 7837db96d56Sopenharmony_ci self.assertNotIn(name, modules) 7847db96d56Sopenharmony_ci self.assertEqual(len(modules), total) 7857db96d56Sopenharmony_ci 7867db96d56Sopenharmony_ci @support.requires_subprocess() 7877db96d56Sopenharmony_ci def test_fatal_error(self): 7887db96d56Sopenharmony_ci # By default, stdlib extension modules are ignored, 7897db96d56Sopenharmony_ci # but not test modules. 7907db96d56Sopenharmony_ci expected = ('_testcapi',) 7917db96d56Sopenharmony_ci not_expected = ('sys',) 7927db96d56Sopenharmony_ci code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")' 7937db96d56Sopenharmony_ci self.check_fatal_error(code, expected, not_expected) 7947db96d56Sopenharmony_ci 7957db96d56Sopenharmony_ci # Mark _testcapi as stdlib module, but not sys 7967db96d56Sopenharmony_ci expected = ('sys',) 7977db96d56Sopenharmony_ci not_expected = ('_testcapi',) 7987db96d56Sopenharmony_ci code = textwrap.dedent(''' 7997db96d56Sopenharmony_ci import _testcapi, sys 8007db96d56Sopenharmony_ci sys.stdlib_module_names = frozenset({"_testcapi"}) 8017db96d56Sopenharmony_ci _testcapi.fatal_error(b"MESSAGE") 8027db96d56Sopenharmony_ci ''') 8037db96d56Sopenharmony_ci self.check_fatal_error(code, expected) 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci def test_pyobject_repr_from_null(self): 8067db96d56Sopenharmony_ci s = _testcapi.pyobject_repr_from_null() 8077db96d56Sopenharmony_ci self.assertEqual(s, '<NULL>') 8087db96d56Sopenharmony_ci 8097db96d56Sopenharmony_ci def test_pyobject_str_from_null(self): 8107db96d56Sopenharmony_ci s = _testcapi.pyobject_str_from_null() 8117db96d56Sopenharmony_ci self.assertEqual(s, '<NULL>') 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci def test_pyobject_bytes_from_null(self): 8147db96d56Sopenharmony_ci s = _testcapi.pyobject_bytes_from_null() 8157db96d56Sopenharmony_ci self.assertEqual(s, b'<NULL>') 8167db96d56Sopenharmony_ci 8177db96d56Sopenharmony_ci def test_Py_CompileString(self): 8187db96d56Sopenharmony_ci # Check that Py_CompileString respects the coding cookie 8197db96d56Sopenharmony_ci _compile = _testcapi.Py_CompileString 8207db96d56Sopenharmony_ci code = b"# -*- coding: latin1 -*-\nprint('\xc2\xa4')\n" 8217db96d56Sopenharmony_ci result = _compile(code) 8227db96d56Sopenharmony_ci expected = compile(code, "<string>", "exec") 8237db96d56Sopenharmony_ci self.assertEqual(result.co_consts, expected.co_consts) 8247db96d56Sopenharmony_ci 8257db96d56Sopenharmony_ci def test_export_symbols(self): 8267db96d56Sopenharmony_ci # bpo-44133: Ensure that the "Py_FrozenMain" and 8277db96d56Sopenharmony_ci # "PyThread_get_thread_native_id" symbols are exported by the Python 8287db96d56Sopenharmony_ci # (directly by the binary, or via by the Python dynamic library). 8297db96d56Sopenharmony_ci ctypes = import_helper.import_module('ctypes') 8307db96d56Sopenharmony_ci names = [] 8317db96d56Sopenharmony_ci 8327db96d56Sopenharmony_ci # Test if the PY_HAVE_THREAD_NATIVE_ID macro is defined 8337db96d56Sopenharmony_ci if hasattr(_thread, 'get_native_id'): 8347db96d56Sopenharmony_ci names.append('PyThread_get_thread_native_id') 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci # Python/frozenmain.c fails to build on Windows when the symbols are 8377db96d56Sopenharmony_ci # missing: 8387db96d56Sopenharmony_ci # - PyWinFreeze_ExeInit 8397db96d56Sopenharmony_ci # - PyWinFreeze_ExeTerm 8407db96d56Sopenharmony_ci # - PyInitFrozenExtensions 8417db96d56Sopenharmony_ci if os.name != 'nt': 8427db96d56Sopenharmony_ci names.append('Py_FrozenMain') 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci for name in names: 8457db96d56Sopenharmony_ci with self.subTest(name=name): 8467db96d56Sopenharmony_ci self.assertTrue(hasattr(ctypes.pythonapi, name)) 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_ci def test_eval_get_func_name(self): 8497db96d56Sopenharmony_ci def function_example(): ... 8507db96d56Sopenharmony_ci 8517db96d56Sopenharmony_ci class A: 8527db96d56Sopenharmony_ci def method_example(self): ... 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_name(function_example), 8557db96d56Sopenharmony_ci "function_example") 8567db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_name(A.method_example), 8577db96d56Sopenharmony_ci "method_example") 8587db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_name(A().method_example), 8597db96d56Sopenharmony_ci "method_example") 8607db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_name(sum), "sum") # c function 8617db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_name(A), "type") 8627db96d56Sopenharmony_ci 8637db96d56Sopenharmony_ci def test_eval_get_func_desc(self): 8647db96d56Sopenharmony_ci def function_example(): ... 8657db96d56Sopenharmony_ci 8667db96d56Sopenharmony_ci class A: 8677db96d56Sopenharmony_ci def method_example(self): ... 8687db96d56Sopenharmony_ci 8697db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_desc(function_example), 8707db96d56Sopenharmony_ci "()") 8717db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_desc(A.method_example), 8727db96d56Sopenharmony_ci "()") 8737db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_desc(A().method_example), 8747db96d56Sopenharmony_ci "()") 8757db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_desc(sum), "()") # c function 8767db96d56Sopenharmony_ci self.assertEqual(_testcapi.eval_get_func_desc(A), " object") 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_ci def test_function_get_code(self): 8797db96d56Sopenharmony_ci import types 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci def some(): 8827db96d56Sopenharmony_ci pass 8837db96d56Sopenharmony_ci 8847db96d56Sopenharmony_ci code = _testcapi.function_get_code(some) 8857db96d56Sopenharmony_ci self.assertIsInstance(code, types.CodeType) 8867db96d56Sopenharmony_ci self.assertEqual(code, some.__code__) 8877db96d56Sopenharmony_ci 8887db96d56Sopenharmony_ci with self.assertRaises(SystemError): 8897db96d56Sopenharmony_ci _testcapi.function_get_code(None) # not a function 8907db96d56Sopenharmony_ci 8917db96d56Sopenharmony_ci def test_function_get_globals(self): 8927db96d56Sopenharmony_ci def some(): 8937db96d56Sopenharmony_ci pass 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci globals_ = _testcapi.function_get_globals(some) 8967db96d56Sopenharmony_ci self.assertIsInstance(globals_, dict) 8977db96d56Sopenharmony_ci self.assertEqual(globals_, some.__globals__) 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci with self.assertRaises(SystemError): 9007db96d56Sopenharmony_ci _testcapi.function_get_globals(None) # not a function 9017db96d56Sopenharmony_ci 9027db96d56Sopenharmony_ci def test_function_get_module(self): 9037db96d56Sopenharmony_ci def some(): 9047db96d56Sopenharmony_ci pass 9057db96d56Sopenharmony_ci 9067db96d56Sopenharmony_ci module = _testcapi.function_get_module(some) 9077db96d56Sopenharmony_ci self.assertIsInstance(module, str) 9087db96d56Sopenharmony_ci self.assertEqual(module, some.__module__) 9097db96d56Sopenharmony_ci 9107db96d56Sopenharmony_ci with self.assertRaises(SystemError): 9117db96d56Sopenharmony_ci _testcapi.function_get_module(None) # not a function 9127db96d56Sopenharmony_ci 9137db96d56Sopenharmony_ci 9147db96d56Sopenharmony_ciclass TestPendingCalls(unittest.TestCase): 9157db96d56Sopenharmony_ci 9167db96d56Sopenharmony_ci def pendingcalls_submit(self, l, n): 9177db96d56Sopenharmony_ci def callback(): 9187db96d56Sopenharmony_ci #this function can be interrupted by thread switching so let's 9197db96d56Sopenharmony_ci #use an atomic operation 9207db96d56Sopenharmony_ci l.append(None) 9217db96d56Sopenharmony_ci 9227db96d56Sopenharmony_ci for i in range(n): 9237db96d56Sopenharmony_ci time.sleep(random.random()*0.02) #0.01 secs on average 9247db96d56Sopenharmony_ci #try submitting callback until successful. 9257db96d56Sopenharmony_ci #rely on regular interrupt to flush queue if we are 9267db96d56Sopenharmony_ci #unsuccessful. 9277db96d56Sopenharmony_ci while True: 9287db96d56Sopenharmony_ci if _testcapi._pending_threadfunc(callback): 9297db96d56Sopenharmony_ci break 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ci def pendingcalls_wait(self, l, n, context = None): 9327db96d56Sopenharmony_ci #now, stick around until l[0] has grown to 10 9337db96d56Sopenharmony_ci count = 0 9347db96d56Sopenharmony_ci while len(l) != n: 9357db96d56Sopenharmony_ci #this busy loop is where we expect to be interrupted to 9367db96d56Sopenharmony_ci #run our callbacks. Note that callbacks are only run on the 9377db96d56Sopenharmony_ci #main thread 9387db96d56Sopenharmony_ci if False and support.verbose: 9397db96d56Sopenharmony_ci print("(%i)"%(len(l),),) 9407db96d56Sopenharmony_ci for i in range(1000): 9417db96d56Sopenharmony_ci a = i*i 9427db96d56Sopenharmony_ci if context and not context.event.is_set(): 9437db96d56Sopenharmony_ci continue 9447db96d56Sopenharmony_ci count += 1 9457db96d56Sopenharmony_ci self.assertTrue(count < 10000, 9467db96d56Sopenharmony_ci "timeout waiting for %i callbacks, got %i"%(n, len(l))) 9477db96d56Sopenharmony_ci if False and support.verbose: 9487db96d56Sopenharmony_ci print("(%i)"%(len(l),)) 9497db96d56Sopenharmony_ci 9507db96d56Sopenharmony_ci @threading_helper.requires_working_threading() 9517db96d56Sopenharmony_ci def test_pendingcalls_threaded(self): 9527db96d56Sopenharmony_ci 9537db96d56Sopenharmony_ci #do every callback on a separate thread 9547db96d56Sopenharmony_ci n = 32 #total callbacks 9557db96d56Sopenharmony_ci threads = [] 9567db96d56Sopenharmony_ci class foo(object):pass 9577db96d56Sopenharmony_ci context = foo() 9587db96d56Sopenharmony_ci context.l = [] 9597db96d56Sopenharmony_ci context.n = 2 #submits per thread 9607db96d56Sopenharmony_ci context.nThreads = n // context.n 9617db96d56Sopenharmony_ci context.nFinished = 0 9627db96d56Sopenharmony_ci context.lock = threading.Lock() 9637db96d56Sopenharmony_ci context.event = threading.Event() 9647db96d56Sopenharmony_ci 9657db96d56Sopenharmony_ci threads = [threading.Thread(target=self.pendingcalls_thread, 9667db96d56Sopenharmony_ci args=(context,)) 9677db96d56Sopenharmony_ci for i in range(context.nThreads)] 9687db96d56Sopenharmony_ci with threading_helper.start_threads(threads): 9697db96d56Sopenharmony_ci self.pendingcalls_wait(context.l, n, context) 9707db96d56Sopenharmony_ci 9717db96d56Sopenharmony_ci def pendingcalls_thread(self, context): 9727db96d56Sopenharmony_ci try: 9737db96d56Sopenharmony_ci self.pendingcalls_submit(context.l, context.n) 9747db96d56Sopenharmony_ci finally: 9757db96d56Sopenharmony_ci with context.lock: 9767db96d56Sopenharmony_ci context.nFinished += 1 9777db96d56Sopenharmony_ci nFinished = context.nFinished 9787db96d56Sopenharmony_ci if False and support.verbose: 9797db96d56Sopenharmony_ci print("finished threads: ", nFinished) 9807db96d56Sopenharmony_ci if nFinished == context.nThreads: 9817db96d56Sopenharmony_ci context.event.set() 9827db96d56Sopenharmony_ci 9837db96d56Sopenharmony_ci def test_pendingcalls_non_threaded(self): 9847db96d56Sopenharmony_ci #again, just using the main thread, likely they will all be dispatched at 9857db96d56Sopenharmony_ci #once. It is ok to ask for too many, because we loop until we find a slot. 9867db96d56Sopenharmony_ci #the loop can be interrupted to dispatch. 9877db96d56Sopenharmony_ci #there are only 32 dispatch slots, so we go for twice that! 9887db96d56Sopenharmony_ci l = [] 9897db96d56Sopenharmony_ci n = 64 9907db96d56Sopenharmony_ci self.pendingcalls_submit(l, n) 9917db96d56Sopenharmony_ci self.pendingcalls_wait(l, n) 9927db96d56Sopenharmony_ci 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_ciclass SubinterpreterTest(unittest.TestCase): 9957db96d56Sopenharmony_ci 9967db96d56Sopenharmony_ci @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") 9977db96d56Sopenharmony_ci def test_subinterps(self): 9987db96d56Sopenharmony_ci import builtins 9997db96d56Sopenharmony_ci r, w = os.pipe() 10007db96d56Sopenharmony_ci code = """if 1: 10017db96d56Sopenharmony_ci import sys, builtins, pickle 10027db96d56Sopenharmony_ci with open({:d}, "wb") as f: 10037db96d56Sopenharmony_ci pickle.dump(id(sys.modules), f) 10047db96d56Sopenharmony_ci pickle.dump(id(builtins), f) 10057db96d56Sopenharmony_ci """.format(w) 10067db96d56Sopenharmony_ci with open(r, "rb") as f: 10077db96d56Sopenharmony_ci ret = support.run_in_subinterp(code) 10087db96d56Sopenharmony_ci self.assertEqual(ret, 0) 10097db96d56Sopenharmony_ci self.assertNotEqual(pickle.load(f), id(sys.modules)) 10107db96d56Sopenharmony_ci self.assertNotEqual(pickle.load(f), id(builtins)) 10117db96d56Sopenharmony_ci 10127db96d56Sopenharmony_ci @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") 10137db96d56Sopenharmony_ci def test_subinterps_recent_language_features(self): 10147db96d56Sopenharmony_ci r, w = os.pipe() 10157db96d56Sopenharmony_ci code = """if 1: 10167db96d56Sopenharmony_ci import pickle 10177db96d56Sopenharmony_ci with open({:d}, "wb") as f: 10187db96d56Sopenharmony_ci 10197db96d56Sopenharmony_ci @(lambda x:x) # Py 3.9 10207db96d56Sopenharmony_ci def noop(x): return x 10217db96d56Sopenharmony_ci 10227db96d56Sopenharmony_ci a = (b := f'1{{2}}3') + noop('x') # Py 3.8 (:=) / 3.6 (f'') 10237db96d56Sopenharmony_ci 10247db96d56Sopenharmony_ci async def foo(arg): return await arg # Py 3.5 10257db96d56Sopenharmony_ci 10267db96d56Sopenharmony_ci pickle.dump(dict(a=a, b=b), f) 10277db96d56Sopenharmony_ci """.format(w) 10287db96d56Sopenharmony_ci 10297db96d56Sopenharmony_ci with open(r, "rb") as f: 10307db96d56Sopenharmony_ci ret = support.run_in_subinterp(code) 10317db96d56Sopenharmony_ci self.assertEqual(ret, 0) 10327db96d56Sopenharmony_ci self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'}) 10337db96d56Sopenharmony_ci 10347db96d56Sopenharmony_ci def test_mutate_exception(self): 10357db96d56Sopenharmony_ci """ 10367db96d56Sopenharmony_ci Exceptions saved in global module state get shared between 10377db96d56Sopenharmony_ci individual module instances. This test checks whether or not 10387db96d56Sopenharmony_ci a change in one interpreter's module gets reflected into the 10397db96d56Sopenharmony_ci other ones. 10407db96d56Sopenharmony_ci """ 10417db96d56Sopenharmony_ci import binascii 10427db96d56Sopenharmony_ci 10437db96d56Sopenharmony_ci support.run_in_subinterp("import binascii; binascii.Error.foobar = 'foobar'") 10447db96d56Sopenharmony_ci 10457db96d56Sopenharmony_ci self.assertFalse(hasattr(binascii.Error, "foobar")) 10467db96d56Sopenharmony_ci 10477db96d56Sopenharmony_ci @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") 10487db96d56Sopenharmony_ci def test_module_state_shared_in_global(self): 10497db96d56Sopenharmony_ci """ 10507db96d56Sopenharmony_ci bpo-44050: Extension module state should be shared between interpreters 10517db96d56Sopenharmony_ci when it doesn't support sub-interpreters. 10527db96d56Sopenharmony_ci """ 10537db96d56Sopenharmony_ci r, w = os.pipe() 10547db96d56Sopenharmony_ci self.addCleanup(os.close, r) 10557db96d56Sopenharmony_ci self.addCleanup(os.close, w) 10567db96d56Sopenharmony_ci 10577db96d56Sopenharmony_ci script = textwrap.dedent(f""" 10587db96d56Sopenharmony_ci import importlib.machinery 10597db96d56Sopenharmony_ci import importlib.util 10607db96d56Sopenharmony_ci import os 10617db96d56Sopenharmony_ci 10627db96d56Sopenharmony_ci fullname = '_test_module_state_shared' 10637db96d56Sopenharmony_ci origin = importlib.util.find_spec('_testmultiphase').origin 10647db96d56Sopenharmony_ci loader = importlib.machinery.ExtensionFileLoader(fullname, origin) 10657db96d56Sopenharmony_ci spec = importlib.util.spec_from_loader(fullname, loader) 10667db96d56Sopenharmony_ci module = importlib.util.module_from_spec(spec) 10677db96d56Sopenharmony_ci attr_id = str(id(module.Error)).encode() 10687db96d56Sopenharmony_ci 10697db96d56Sopenharmony_ci os.write({w}, attr_id) 10707db96d56Sopenharmony_ci """) 10717db96d56Sopenharmony_ci exec(script) 10727db96d56Sopenharmony_ci main_attr_id = os.read(r, 100) 10737db96d56Sopenharmony_ci 10747db96d56Sopenharmony_ci ret = support.run_in_subinterp(script) 10757db96d56Sopenharmony_ci self.assertEqual(ret, 0) 10767db96d56Sopenharmony_ci subinterp_attr_id = os.read(r, 100) 10777db96d56Sopenharmony_ci self.assertEqual(main_attr_id, subinterp_attr_id) 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_ci 10807db96d56Sopenharmony_ciclass TestThreadState(unittest.TestCase): 10817db96d56Sopenharmony_ci 10827db96d56Sopenharmony_ci @threading_helper.reap_threads 10837db96d56Sopenharmony_ci @threading_helper.requires_working_threading() 10847db96d56Sopenharmony_ci def test_thread_state(self): 10857db96d56Sopenharmony_ci # some extra thread-state tests driven via _testcapi 10867db96d56Sopenharmony_ci def target(): 10877db96d56Sopenharmony_ci idents = [] 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_ci def callback(): 10907db96d56Sopenharmony_ci idents.append(threading.get_ident()) 10917db96d56Sopenharmony_ci 10927db96d56Sopenharmony_ci _testcapi._test_thread_state(callback) 10937db96d56Sopenharmony_ci a = b = callback 10947db96d56Sopenharmony_ci time.sleep(1) 10957db96d56Sopenharmony_ci # Check our main thread is in the list exactly 3 times. 10967db96d56Sopenharmony_ci self.assertEqual(idents.count(threading.get_ident()), 3, 10977db96d56Sopenharmony_ci "Couldn't find main thread correctly in the list") 10987db96d56Sopenharmony_ci 10997db96d56Sopenharmony_ci target() 11007db96d56Sopenharmony_ci t = threading.Thread(target=target) 11017db96d56Sopenharmony_ci t.start() 11027db96d56Sopenharmony_ci t.join() 11037db96d56Sopenharmony_ci 11047db96d56Sopenharmony_ci @threading_helper.reap_threads 11057db96d56Sopenharmony_ci @threading_helper.requires_working_threading() 11067db96d56Sopenharmony_ci def test_gilstate_ensure_no_deadlock(self): 11077db96d56Sopenharmony_ci # See https://github.com/python/cpython/issues/96071 11087db96d56Sopenharmony_ci code = textwrap.dedent(f""" 11097db96d56Sopenharmony_ci import _testcapi 11107db96d56Sopenharmony_ci 11117db96d56Sopenharmony_ci def callback(): 11127db96d56Sopenharmony_ci print('callback called') 11137db96d56Sopenharmony_ci 11147db96d56Sopenharmony_ci _testcapi._test_thread_state(callback) 11157db96d56Sopenharmony_ci """) 11167db96d56Sopenharmony_ci ret = assert_python_ok('-X', 'tracemalloc', '-c', code) 11177db96d56Sopenharmony_ci self.assertIn(b'callback called', ret.out) 11187db96d56Sopenharmony_ci 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ciclass Test_testcapi(unittest.TestCase): 11217db96d56Sopenharmony_ci locals().update((name, getattr(_testcapi, name)) 11227db96d56Sopenharmony_ci for name in dir(_testcapi) 11237db96d56Sopenharmony_ci if name.startswith('test_') and not name.endswith('_code')) 11247db96d56Sopenharmony_ci 11257db96d56Sopenharmony_ci # Suppress warning from PyUnicode_FromUnicode(). 11267db96d56Sopenharmony_ci @warnings_helper.ignore_warnings(category=DeprecationWarning) 11277db96d56Sopenharmony_ci def test_widechar(self): 11287db96d56Sopenharmony_ci _testcapi.test_widechar() 11297db96d56Sopenharmony_ci 11307db96d56Sopenharmony_ci def test_version_api_data(self): 11317db96d56Sopenharmony_ci self.assertEqual(_testcapi.Py_Version, sys.hexversion) 11327db96d56Sopenharmony_ci 11337db96d56Sopenharmony_ci 11347db96d56Sopenharmony_ciclass Test_testinternalcapi(unittest.TestCase): 11357db96d56Sopenharmony_ci locals().update((name, getattr(_testinternalcapi, name)) 11367db96d56Sopenharmony_ci for name in dir(_testinternalcapi) 11377db96d56Sopenharmony_ci if name.startswith('test_')) 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_ci@support.requires_subprocess() 11417db96d56Sopenharmony_ciclass PyMemDebugTests(unittest.TestCase): 11427db96d56Sopenharmony_ci PYTHONMALLOC = 'debug' 11437db96d56Sopenharmony_ci # '0x04c06e0' or '04C06E0' 11447db96d56Sopenharmony_ci PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' 11457db96d56Sopenharmony_ci 11467db96d56Sopenharmony_ci def check(self, code): 11477db96d56Sopenharmony_ci with support.SuppressCrashReport(): 11487db96d56Sopenharmony_ci out = assert_python_failure( 11497db96d56Sopenharmony_ci '-c', code, 11507db96d56Sopenharmony_ci PYTHONMALLOC=self.PYTHONMALLOC, 11517db96d56Sopenharmony_ci # FreeBSD: instruct jemalloc to not fill freed() memory 11527db96d56Sopenharmony_ci # with junk byte 0x5a, see JEMALLOC(3) 11537db96d56Sopenharmony_ci MALLOC_CONF="junk:false", 11547db96d56Sopenharmony_ci ) 11557db96d56Sopenharmony_ci stderr = out.err 11567db96d56Sopenharmony_ci return stderr.decode('ascii', 'replace') 11577db96d56Sopenharmony_ci 11587db96d56Sopenharmony_ci def test_buffer_overflow(self): 11597db96d56Sopenharmony_ci out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') 11607db96d56Sopenharmony_ci regex = (r"Debug memory block at address p={ptr}: API 'm'\n" 11617db96d56Sopenharmony_ci r" 16 bytes originally requested\n" 11627db96d56Sopenharmony_ci r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" 11637db96d56Sopenharmony_ci r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" 11647db96d56Sopenharmony_ci r" at tail\+0: 0x78 \*\*\* OUCH\n" 11657db96d56Sopenharmony_ci r" at tail\+1: 0xfd\n" 11667db96d56Sopenharmony_ci r" at tail\+2: 0xfd\n" 11677db96d56Sopenharmony_ci r" .*\n" 11687db96d56Sopenharmony_ci r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" 11697db96d56Sopenharmony_ci r" Data at p: cd cd cd .*\n" 11707db96d56Sopenharmony_ci r"\n" 11717db96d56Sopenharmony_ci r"Enable tracemalloc to get the memory block allocation traceback\n" 11727db96d56Sopenharmony_ci r"\n" 11737db96d56Sopenharmony_ci r"Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte") 11747db96d56Sopenharmony_ci regex = regex.format(ptr=self.PTR_REGEX) 11757db96d56Sopenharmony_ci regex = re.compile(regex, flags=re.DOTALL) 11767db96d56Sopenharmony_ci self.assertRegex(out, regex) 11777db96d56Sopenharmony_ci 11787db96d56Sopenharmony_ci def test_api_misuse(self): 11797db96d56Sopenharmony_ci out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') 11807db96d56Sopenharmony_ci regex = (r"Debug memory block at address p={ptr}: API 'm'\n" 11817db96d56Sopenharmony_ci r" 16 bytes originally requested\n" 11827db96d56Sopenharmony_ci r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" 11837db96d56Sopenharmony_ci r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" 11847db96d56Sopenharmony_ci r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" 11857db96d56Sopenharmony_ci r" Data at p: cd cd cd .*\n" 11867db96d56Sopenharmony_ci r"\n" 11877db96d56Sopenharmony_ci r"Enable tracemalloc to get the memory block allocation traceback\n" 11887db96d56Sopenharmony_ci r"\n" 11897db96d56Sopenharmony_ci r"Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\n") 11907db96d56Sopenharmony_ci regex = regex.format(ptr=self.PTR_REGEX) 11917db96d56Sopenharmony_ci self.assertRegex(out, regex) 11927db96d56Sopenharmony_ci 11937db96d56Sopenharmony_ci def check_malloc_without_gil(self, code): 11947db96d56Sopenharmony_ci out = self.check(code) 11957db96d56Sopenharmony_ci expected = ('Fatal Python error: _PyMem_DebugMalloc: ' 11967db96d56Sopenharmony_ci 'Python memory allocator called without holding the GIL') 11977db96d56Sopenharmony_ci self.assertIn(expected, out) 11987db96d56Sopenharmony_ci 11997db96d56Sopenharmony_ci def test_pymem_malloc_without_gil(self): 12007db96d56Sopenharmony_ci # Debug hooks must raise an error if PyMem_Malloc() is called 12017db96d56Sopenharmony_ci # without holding the GIL 12027db96d56Sopenharmony_ci code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' 12037db96d56Sopenharmony_ci self.check_malloc_without_gil(code) 12047db96d56Sopenharmony_ci 12057db96d56Sopenharmony_ci def test_pyobject_malloc_without_gil(self): 12067db96d56Sopenharmony_ci # Debug hooks must raise an error if PyObject_Malloc() is called 12077db96d56Sopenharmony_ci # without holding the GIL 12087db96d56Sopenharmony_ci code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' 12097db96d56Sopenharmony_ci self.check_malloc_without_gil(code) 12107db96d56Sopenharmony_ci 12117db96d56Sopenharmony_ci def check_pyobject_is_freed(self, func_name): 12127db96d56Sopenharmony_ci code = textwrap.dedent(f''' 12137db96d56Sopenharmony_ci import gc, os, sys, _testcapi 12147db96d56Sopenharmony_ci # Disable the GC to avoid crash on GC collection 12157db96d56Sopenharmony_ci gc.disable() 12167db96d56Sopenharmony_ci try: 12177db96d56Sopenharmony_ci _testcapi.{func_name}() 12187db96d56Sopenharmony_ci # Exit immediately to avoid a crash while deallocating 12197db96d56Sopenharmony_ci # the invalid object 12207db96d56Sopenharmony_ci os._exit(0) 12217db96d56Sopenharmony_ci except _testcapi.error: 12227db96d56Sopenharmony_ci os._exit(1) 12237db96d56Sopenharmony_ci ''') 12247db96d56Sopenharmony_ci assert_python_ok( 12257db96d56Sopenharmony_ci '-c', code, 12267db96d56Sopenharmony_ci PYTHONMALLOC=self.PYTHONMALLOC, 12277db96d56Sopenharmony_ci MALLOC_CONF="junk:false", 12287db96d56Sopenharmony_ci ) 12297db96d56Sopenharmony_ci 12307db96d56Sopenharmony_ci def test_pyobject_null_is_freed(self): 12317db96d56Sopenharmony_ci self.check_pyobject_is_freed('check_pyobject_null_is_freed') 12327db96d56Sopenharmony_ci 12337db96d56Sopenharmony_ci def test_pyobject_uninitialized_is_freed(self): 12347db96d56Sopenharmony_ci self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') 12357db96d56Sopenharmony_ci 12367db96d56Sopenharmony_ci def test_pyobject_forbidden_bytes_is_freed(self): 12377db96d56Sopenharmony_ci self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') 12387db96d56Sopenharmony_ci 12397db96d56Sopenharmony_ci def test_pyobject_freed_is_freed(self): 12407db96d56Sopenharmony_ci self.check_pyobject_is_freed('check_pyobject_freed_is_freed') 12417db96d56Sopenharmony_ci 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ciclass PyMemMallocDebugTests(PyMemDebugTests): 12447db96d56Sopenharmony_ci PYTHONMALLOC = 'malloc_debug' 12457db96d56Sopenharmony_ci 12467db96d56Sopenharmony_ci 12477db96d56Sopenharmony_ci@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') 12487db96d56Sopenharmony_ciclass PyMemPymallocDebugTests(PyMemDebugTests): 12497db96d56Sopenharmony_ci PYTHONMALLOC = 'pymalloc_debug' 12507db96d56Sopenharmony_ci 12517db96d56Sopenharmony_ci 12527db96d56Sopenharmony_ci@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG') 12537db96d56Sopenharmony_ciclass PyMemDefaultTests(PyMemDebugTests): 12547db96d56Sopenharmony_ci # test default allocator of Python compiled in debug mode 12557db96d56Sopenharmony_ci PYTHONMALLOC = '' 12567db96d56Sopenharmony_ci 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ci@unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") 12597db96d56Sopenharmony_ciclass Test_ModuleStateAccess(unittest.TestCase): 12607db96d56Sopenharmony_ci """Test access to module start (PEP 573)""" 12617db96d56Sopenharmony_ci 12627db96d56Sopenharmony_ci # The C part of the tests lives in _testmultiphase, in a module called 12637db96d56Sopenharmony_ci # _testmultiphase_meth_state_access. 12647db96d56Sopenharmony_ci # This module has multi-phase initialization, unlike _testcapi. 12657db96d56Sopenharmony_ci 12667db96d56Sopenharmony_ci def setUp(self): 12677db96d56Sopenharmony_ci fullname = '_testmultiphase_meth_state_access' # XXX 12687db96d56Sopenharmony_ci origin = importlib.util.find_spec('_testmultiphase').origin 12697db96d56Sopenharmony_ci loader = importlib.machinery.ExtensionFileLoader(fullname, origin) 12707db96d56Sopenharmony_ci spec = importlib.util.spec_from_loader(fullname, loader) 12717db96d56Sopenharmony_ci module = importlib.util.module_from_spec(spec) 12727db96d56Sopenharmony_ci loader.exec_module(module) 12737db96d56Sopenharmony_ci self.module = module 12747db96d56Sopenharmony_ci 12757db96d56Sopenharmony_ci def test_subclass_get_module(self): 12767db96d56Sopenharmony_ci """PyType_GetModule for defining_class""" 12777db96d56Sopenharmony_ci class StateAccessType_Subclass(self.module.StateAccessType): 12787db96d56Sopenharmony_ci pass 12797db96d56Sopenharmony_ci 12807db96d56Sopenharmony_ci instance = StateAccessType_Subclass() 12817db96d56Sopenharmony_ci self.assertIs(instance.get_defining_module(), self.module) 12827db96d56Sopenharmony_ci 12837db96d56Sopenharmony_ci def test_subclass_get_module_with_super(self): 12847db96d56Sopenharmony_ci class StateAccessType_Subclass(self.module.StateAccessType): 12857db96d56Sopenharmony_ci def get_defining_module(self): 12867db96d56Sopenharmony_ci return super().get_defining_module() 12877db96d56Sopenharmony_ci 12887db96d56Sopenharmony_ci instance = StateAccessType_Subclass() 12897db96d56Sopenharmony_ci self.assertIs(instance.get_defining_module(), self.module) 12907db96d56Sopenharmony_ci 12917db96d56Sopenharmony_ci def test_state_access(self): 12927db96d56Sopenharmony_ci """Checks methods defined with and without argument clinic 12937db96d56Sopenharmony_ci 12947db96d56Sopenharmony_ci This tests a no-arg method (get_count) and a method with 12957db96d56Sopenharmony_ci both a positional and keyword argument. 12967db96d56Sopenharmony_ci """ 12977db96d56Sopenharmony_ci 12987db96d56Sopenharmony_ci a = self.module.StateAccessType() 12997db96d56Sopenharmony_ci b = self.module.StateAccessType() 13007db96d56Sopenharmony_ci 13017db96d56Sopenharmony_ci methods = { 13027db96d56Sopenharmony_ci 'clinic': a.increment_count_clinic, 13037db96d56Sopenharmony_ci 'noclinic': a.increment_count_noclinic, 13047db96d56Sopenharmony_ci } 13057db96d56Sopenharmony_ci 13067db96d56Sopenharmony_ci for name, increment_count in methods.items(): 13077db96d56Sopenharmony_ci with self.subTest(name): 13087db96d56Sopenharmony_ci self.assertEqual(a.get_count(), b.get_count()) 13097db96d56Sopenharmony_ci self.assertEqual(a.get_count(), 0) 13107db96d56Sopenharmony_ci 13117db96d56Sopenharmony_ci increment_count() 13127db96d56Sopenharmony_ci self.assertEqual(a.get_count(), b.get_count()) 13137db96d56Sopenharmony_ci self.assertEqual(a.get_count(), 1) 13147db96d56Sopenharmony_ci 13157db96d56Sopenharmony_ci increment_count(3) 13167db96d56Sopenharmony_ci self.assertEqual(a.get_count(), b.get_count()) 13177db96d56Sopenharmony_ci self.assertEqual(a.get_count(), 4) 13187db96d56Sopenharmony_ci 13197db96d56Sopenharmony_ci increment_count(-2, twice=True) 13207db96d56Sopenharmony_ci self.assertEqual(a.get_count(), b.get_count()) 13217db96d56Sopenharmony_ci self.assertEqual(a.get_count(), 0) 13227db96d56Sopenharmony_ci 13237db96d56Sopenharmony_ci with self.assertRaises(TypeError): 13247db96d56Sopenharmony_ci increment_count(thrice=3) 13257db96d56Sopenharmony_ci 13267db96d56Sopenharmony_ci with self.assertRaises(TypeError): 13277db96d56Sopenharmony_ci increment_count(1, 2, 3) 13287db96d56Sopenharmony_ci 13297db96d56Sopenharmony_ci def test_get_module_bad_def(self): 13307db96d56Sopenharmony_ci # PyType_GetModuleByDef fails gracefully if it doesn't 13317db96d56Sopenharmony_ci # find what it's looking for. 13327db96d56Sopenharmony_ci # see bpo-46433 13337db96d56Sopenharmony_ci instance = self.module.StateAccessType() 13347db96d56Sopenharmony_ci with self.assertRaises(TypeError): 13357db96d56Sopenharmony_ci instance.getmodulebydef_bad_def() 13367db96d56Sopenharmony_ci 13377db96d56Sopenharmony_ci def test_get_module_static_in_mro(self): 13387db96d56Sopenharmony_ci # Here, the class PyType_GetModuleByDef is looking for 13397db96d56Sopenharmony_ci # appears in the MRO after a static type (Exception). 13407db96d56Sopenharmony_ci # see bpo-46433 13417db96d56Sopenharmony_ci class Subclass(BaseException, self.module.StateAccessType): 13427db96d56Sopenharmony_ci pass 13437db96d56Sopenharmony_ci self.assertIs(Subclass().get_defining_module(), self.module) 13447db96d56Sopenharmony_ci 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ciclass Test_FrameAPI(unittest.TestCase): 13477db96d56Sopenharmony_ci 13487db96d56Sopenharmony_ci def getframe(self): 13497db96d56Sopenharmony_ci return sys._getframe() 13507db96d56Sopenharmony_ci 13517db96d56Sopenharmony_ci def getgenframe(self): 13527db96d56Sopenharmony_ci yield sys._getframe() 13537db96d56Sopenharmony_ci 13547db96d56Sopenharmony_ci def test_frame_getters(self): 13557db96d56Sopenharmony_ci frame = self.getframe() 13567db96d56Sopenharmony_ci self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame)) 13577db96d56Sopenharmony_ci self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame)) 13587db96d56Sopenharmony_ci self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame)) 13597db96d56Sopenharmony_ci self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame)) 13607db96d56Sopenharmony_ci 13617db96d56Sopenharmony_ci def test_frame_get_generator(self): 13627db96d56Sopenharmony_ci gen = self.getgenframe() 13637db96d56Sopenharmony_ci frame = next(gen) 13647db96d56Sopenharmony_ci self.assertIs(gen, _testcapi.frame_getgenerator(frame)) 13657db96d56Sopenharmony_ci 13667db96d56Sopenharmony_ci def test_frame_fback_api(self): 13677db96d56Sopenharmony_ci """Test that accessing `f_back` does not cause a segmentation fault on 13687db96d56Sopenharmony_ci a frame created with `PyFrame_New` (GH-99110).""" 13697db96d56Sopenharmony_ci def dummy(): 13707db96d56Sopenharmony_ci pass 13717db96d56Sopenharmony_ci 13727db96d56Sopenharmony_ci frame = _testcapi.frame_new(dummy.__code__, globals(), locals()) 13737db96d56Sopenharmony_ci # The following line should not cause a segmentation fault. 13747db96d56Sopenharmony_ci self.assertIsNone(frame.f_back) 13757db96d56Sopenharmony_ci 13767db96d56Sopenharmony_ci 13777db96d56Sopenharmony_ciSUFFICIENT_TO_DEOPT_AND_SPECIALIZE = 100 13787db96d56Sopenharmony_ci 13797db96d56Sopenharmony_ciclass Test_Pep523API(unittest.TestCase): 13807db96d56Sopenharmony_ci 13817db96d56Sopenharmony_ci def do_test(self, func, names): 13827db96d56Sopenharmony_ci actual_calls = [] 13837db96d56Sopenharmony_ci start = SUFFICIENT_TO_DEOPT_AND_SPECIALIZE 13847db96d56Sopenharmony_ci count = start + SUFFICIENT_TO_DEOPT_AND_SPECIALIZE 13857db96d56Sopenharmony_ci try: 13867db96d56Sopenharmony_ci for i in range(count): 13877db96d56Sopenharmony_ci if i == start: 13887db96d56Sopenharmony_ci _testinternalcapi.set_eval_frame_record(actual_calls) 13897db96d56Sopenharmony_ci func() 13907db96d56Sopenharmony_ci finally: 13917db96d56Sopenharmony_ci _testinternalcapi.set_eval_frame_default() 13927db96d56Sopenharmony_ci expected_calls = names * SUFFICIENT_TO_DEOPT_AND_SPECIALIZE 13937db96d56Sopenharmony_ci self.assertEqual(len(expected_calls), len(actual_calls)) 13947db96d56Sopenharmony_ci for expected, actual in zip(expected_calls, actual_calls, strict=True): 13957db96d56Sopenharmony_ci self.assertEqual(expected, actual) 13967db96d56Sopenharmony_ci 13977db96d56Sopenharmony_ci def test_inlined_binary_subscr(self): 13987db96d56Sopenharmony_ci class C: 13997db96d56Sopenharmony_ci def __getitem__(self, other): 14007db96d56Sopenharmony_ci return None 14017db96d56Sopenharmony_ci def func(): 14027db96d56Sopenharmony_ci C()[42] 14037db96d56Sopenharmony_ci names = ["func", "__getitem__"] 14047db96d56Sopenharmony_ci self.do_test(func, names) 14057db96d56Sopenharmony_ci 14067db96d56Sopenharmony_ci def test_inlined_call(self): 14077db96d56Sopenharmony_ci def inner(x=42): 14087db96d56Sopenharmony_ci pass 14097db96d56Sopenharmony_ci def func(): 14107db96d56Sopenharmony_ci inner() 14117db96d56Sopenharmony_ci inner(42) 14127db96d56Sopenharmony_ci names = ["func", "inner", "inner"] 14137db96d56Sopenharmony_ci self.do_test(func, names) 14147db96d56Sopenharmony_ci 14157db96d56Sopenharmony_ci 14167db96d56Sopenharmony_ciif __name__ == "__main__": 14177db96d56Sopenharmony_ci unittest.main() 1418