summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_gdb/test_cfunction.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_gdb/test_cfunction.py')
-rw-r--r--Lib/test/test_gdb/test_cfunction.py114
1 files changed, 58 insertions, 56 deletions
diff --git a/Lib/test/test_gdb/test_cfunction.py b/Lib/test/test_gdb/test_cfunction.py
index 55796d0..0a62014 100644
--- a/Lib/test/test_gdb/test_cfunction.py
+++ b/Lib/test/test_gdb/test_cfunction.py
@@ -1,8 +1,6 @@
-import re
import textwrap
import unittest
from test import support
-from test.support import python_is_optimized
from .util import setup_module, DebuggerTests
@@ -11,10 +9,22 @@ def setUpModule():
setup_module()
-@unittest.skipIf(python_is_optimized(),
+@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
@@ -24,60 +34,52 @@ class CFunctionTests(DebuggerTests):
# 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 test_pycfunction(self):
+ def check_pycfunction(self, func_name, args):
'Verify that "py-bt" displays invocations of PyCFunction instances'
- # bpo-46600: If the compiler inlines _null_to_none() in meth_varargs()
- # (ex: clang -Og), _null_to_none() is the frame #1. Otherwise,
- # meth_varargs() is the frame #1.
- expected_frame = r'#(1|2)'
+
+ if support.verbose:
+ print()
+
# Various optimizations multiply the code paths by which these are
# called, so test a variety of calling conventions.
- for func_name, args in (
- ('meth_varargs', ''),
- ('meth_varargs_keywords', ''),
- ('meth_o', '[]'),
- ('meth_noargs', ''),
- ('meth_fastcall', ''),
- ('meth_fastcall_keywords', ''),
+ for obj in (
+ '_testcapi',
+ '_testcapi.MethClass',
+ '_testcapi.MethClass()',
+ '_testcapi.MethStatic()',
+
+ # XXX: bound methods don't yet give nice tracebacks
+ # '_testcapi.MethInstance()',
):
- 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}'):
- cmd = textwrap.dedent(f'''
- import _testcapi
- def foo():
- {obj}.{func_name}({args})
- def bar():
- foo()
- bar()
- ''')
- # 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)
-
- # Verify with "py-bt-full":
- gdb_output = self.get_stack_trace(
- cmd,
- breakpoint=func_name,
- cmds_after_breakpoint=['py-bt-full'],
- # bpo-45207: Ignore 'Function "meth_varargs" not
- # defined.' message in stderr.
- ignore_stderr=True,
- )
- regex = expected_frame
- regex += re.escape(f' <built-in method {func_name}')
- self.assertRegex(gdb_output, regex)
+ 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', '')