1import textwrap 2import unittest 3from test import support 4 5from .util import setup_module, DebuggerTests 6 7 8def setUpModule(): 9 setup_module() 10 11 12@unittest.skipIf(support.python_is_optimized(), 13 "Python was compiled with optimizations") 14@support.requires_resource('cpu') 15class CFunctionTests(DebuggerTests): 16 def check(self, func_name, cmd): 17 # Verify with "py-bt": 18 gdb_output = self.get_stack_trace( 19 cmd, 20 breakpoint=func_name, 21 cmds_after_breakpoint=['bt', 'py-bt'], 22 # bpo-45207: Ignore 'Function "meth_varargs" not 23 # defined.' message in stderr. 24 ignore_stderr=True, 25 ) 26 self.assertIn(f'<built-in method {func_name}', gdb_output) 27 28 # Some older versions of gdb will fail with 29 # "Cannot find new threads: generic error" 30 # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround 31 # 32 # gdb will also generate many erroneous errors such as: 33 # Function "meth_varargs" not defined. 34 # This is because we are calling functions from an "external" module 35 # (_testcapimodule) rather than compiled-in functions. It seems difficult 36 # to suppress these. See also the comment in DebuggerTests.get_stack_trace 37 def check_pycfunction(self, func_name, args): 38 'Verify that "py-bt" displays invocations of PyCFunction instances' 39 40 if support.verbose: 41 print() 42 43 # Various optimizations multiply the code paths by which these are 44 # called, so test a variety of calling conventions. 45 for obj in ( 46 '_testcapi', 47 '_testcapi.MethClass', 48 '_testcapi.MethClass()', 49 '_testcapi.MethStatic()', 50 51 # XXX: bound methods don't yet give nice tracebacks 52 # '_testcapi.MethInstance()', 53 ): 54 with self.subTest(f'{obj}.{func_name}'): 55 call = f'{obj}.{func_name}({args})' 56 cmd = textwrap.dedent(f''' 57 import _testcapi 58 def foo(): 59 {call} 60 def bar(): 61 foo() 62 bar() 63 ''') 64 if support.verbose: 65 print(f' test call: {call}', flush=True) 66 67 self.check(func_name, cmd) 68 69 def test_pycfunction_noargs(self): 70 self.check_pycfunction('meth_noargs', '') 71 72 def test_pycfunction_o(self): 73 self.check_pycfunction('meth_o', '[]') 74 75 def test_pycfunction_varargs(self): 76 self.check_pycfunction('meth_varargs', '') 77 78 def test_pycfunction_varargs_keywords(self): 79 self.check_pycfunction('meth_varargs_keywords', '') 80 81 def test_pycfunction_fastcall(self): 82 self.check_pycfunction('meth_fastcall', '') 83 84 def test_pycfunction_fastcall_keywords(self): 85 self.check_pycfunction('meth_fastcall_keywords', '') 86