mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	* Split test_pycfunction.py: add test_cfunction_full.py. Split the function into the following 6 functions. In verbose mode, these "pycfunction" tests now log each tested call. * test_pycfunction_noargs() * test_pycfunction_o() * test_pycfunction_varargs() * test_pycfunction_varargs_keywords() * test_pycfunction_fastcall() * test_pycfunction_fastcall_keywords() * Move get_gdb_repr() to PrettyPrintTests. * Replace DebuggerTests.get_sample_script() with SAMPLE_SCRIPT. * Rename checkout_hook_path to CHECKOUT_HOOK_PATH. * Rename gdb_version to GDB_VERSION_TEXT. * Replace (gdb_major_version, gdb_minor_version) with GDB_VERSION. * run_gdb() uses "backslashreplace" error handler instead of "replace". * Add check_gdb() function to util.py. * Enhance support.check_cflags_pgo(): check also for sysconfig PGO_PROF_USE_FLAG (if available) in compiler flags. * Move some SkipTest checks to test_gdb/__init__.py. * Elaborate why gdb cannot be tested on Windows: gdb doesn't support PDB debug symbol files.
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import textwrap
 | 
						|
import unittest
 | 
						|
from test import support
 | 
						|
 | 
						|
from .util import setup_module, DebuggerTests
 | 
						|
 | 
						|
 | 
						|
def setUpModule():
 | 
						|
    setup_module()
 | 
						|
 | 
						|
 | 
						|
@unittest.skipIf(support.python_is_optimized(),
 | 
						|
                 "Python was compiled with optimizations")
 | 
						|
@support.requires_resource('cpu')
 | 
						|
class CFunctionTests(DebuggerTests):
 | 
						|
    def check(self, func_name, cmd):
 | 
						|
        # Verify with "py-bt":
 | 
						|
        gdb_output = self.get_stack_trace(
 | 
						|
            cmd,
 | 
						|
            breakpoint=func_name,
 | 
						|
            cmds_after_breakpoint=['bt', 'py-bt'],
 | 
						|
            # bpo-45207: Ignore 'Function "meth_varargs" not
 | 
						|
            # defined.' message in stderr.
 | 
						|
            ignore_stderr=True,
 | 
						|
        )
 | 
						|
        self.assertIn(f'<built-in method {func_name}', gdb_output)
 | 
						|
 | 
						|
    # Some older versions of gdb will fail with
 | 
						|
    #  "Cannot find new threads: generic error"
 | 
						|
    # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
 | 
						|
    #
 | 
						|
    # gdb will also generate many erroneous errors such as:
 | 
						|
    #     Function "meth_varargs" not defined.
 | 
						|
    # This is because we are calling functions from an "external" module
 | 
						|
    # (_testcapimodule) rather than compiled-in functions. It seems difficult
 | 
						|
    # to suppress these. See also the comment in DebuggerTests.get_stack_trace
 | 
						|
    def check_pycfunction(self, func_name, args):
 | 
						|
        'Verify that "py-bt" displays invocations of PyCFunction instances'
 | 
						|
 | 
						|
        if support.verbose:
 | 
						|
            print()
 | 
						|
 | 
						|
        # Various optimizations multiply the code paths by which these are
 | 
						|
        # called, so test a variety of calling conventions.
 | 
						|
        for obj in (
 | 
						|
            '_testcapi',
 | 
						|
            '_testcapi.MethClass',
 | 
						|
            '_testcapi.MethClass()',
 | 
						|
            '_testcapi.MethStatic()',
 | 
						|
 | 
						|
            # XXX: bound methods don't yet give nice tracebacks
 | 
						|
            # '_testcapi.MethInstance()',
 | 
						|
        ):
 | 
						|
            with self.subTest(f'{obj}.{func_name}'):
 | 
						|
                call = f'{obj}.{func_name}({args})'
 | 
						|
                cmd = textwrap.dedent(f'''
 | 
						|
                    import _testcapi
 | 
						|
                    def foo():
 | 
						|
                        {call}
 | 
						|
                    def bar():
 | 
						|
                        foo()
 | 
						|
                    bar()
 | 
						|
                ''')
 | 
						|
                if support.verbose:
 | 
						|
                    print(f'  test call: {call}', flush=True)
 | 
						|
 | 
						|
                self.check(func_name, cmd)
 | 
						|
 | 
						|
    def test_pycfunction_noargs(self):
 | 
						|
        self.check_pycfunction('meth_noargs', '')
 | 
						|
 | 
						|
    def test_pycfunction_o(self):
 | 
						|
        self.check_pycfunction('meth_o', '[]')
 | 
						|
 | 
						|
    def test_pycfunction_varargs(self):
 | 
						|
        self.check_pycfunction('meth_varargs', '')
 | 
						|
 | 
						|
    def test_pycfunction_varargs_keywords(self):
 | 
						|
        self.check_pycfunction('meth_varargs_keywords', '')
 | 
						|
 | 
						|
    def test_pycfunction_fastcall(self):
 | 
						|
        self.check_pycfunction('meth_fastcall', '')
 | 
						|
 | 
						|
    def test_pycfunction_fastcall_keywords(self):
 | 
						|
        self.check_pycfunction('meth_fastcall_keywords', '')
 |