|
6 | 6 | import random |
7 | 7 | import subprocess |
8 | 8 | import sys |
| 9 | +import textwrap |
9 | 10 | import time |
10 | 11 | import unittest |
11 | 12 | from test import support |
12 | 13 | from test.support import MISSING_C_DOCSTRINGS |
| 14 | +from test.script_helper import assert_python_failure |
13 | 15 | try: |
14 | 16 | import _posixsubprocess |
15 | 17 | except ImportError: |
|
21 | 23 | # Skip this test if the _testcapi module isn't available. |
22 | 24 | _testcapi = support.import_module('_testcapi') |
23 | 25 |
|
| 26 | +# Were we compiled --with-pydebug or with #define Py_DEBUG? |
| 27 | +Py_DEBUG = hasattr(sys, 'gettotalrefcount') |
| 28 | + |
24 | 29 |
|
25 | 30 | def testfunction(self): |
26 | 31 | """some doc""" |
@@ -167,6 +172,45 @@ def test_c_type_with_matrix_multiplication(self): |
167 | 172 | o @= m1 |
168 | 173 | self.assertEqual(o, ("matmul", 42, m1)) |
169 | 174 |
|
| 175 | + def test_return_null_without_error(self): |
| 176 | + # Issue #23571: A function must not return NULL without setting an |
| 177 | + # error |
| 178 | + if Py_DEBUG: |
| 179 | + code = textwrap.dedent(""" |
| 180 | + import _testcapi |
| 181 | + from test import support |
| 182 | +
|
| 183 | + with support.SuppressCrashReport(): |
| 184 | + _testcapi.return_null_without_error() |
| 185 | + """) |
| 186 | + rc, out, err = assert_python_failure('-c', code) |
| 187 | + self.assertIn(b'_Py_CheckFunctionResult: Assertion', err) |
| 188 | + else: |
| 189 | + with self.assertRaises(SystemError) as cm: |
| 190 | + _testcapi.return_null_without_error() |
| 191 | + self.assertRegex(str(cm.exception), |
| 192 | + 'return_null_without_error.* ' |
| 193 | + 'returned NULL without setting an error') |
| 194 | + |
| 195 | + def test_return_result_with_error(self): |
| 196 | + # Issue #23571: A function must not return a result with an error set |
| 197 | + if Py_DEBUG: |
| 198 | + code = textwrap.dedent(""" |
| 199 | + import _testcapi |
| 200 | + from test import support |
| 201 | +
|
| 202 | + with support.SuppressCrashReport(): |
| 203 | + _testcapi.return_result_with_error() |
| 204 | + """) |
| 205 | + rc, out, err = assert_python_failure('-c', code) |
| 206 | + self.assertIn(b'_Py_CheckFunctionResult: Assertion', err) |
| 207 | + else: |
| 208 | + with self.assertRaises(SystemError) as cm: |
| 209 | + _testcapi.return_result_with_error() |
| 210 | + self.assertRegex(str(cm.exception), |
| 211 | + 'return_result_with_error.* ' |
| 212 | + 'returned a result with an error set') |
| 213 | + |
170 | 214 |
|
171 | 215 | @unittest.skipUnless(threading, 'Threading required for this test.') |
172 | 216 | class TestPendingCalls(unittest.TestCase): |
|
0 commit comments