]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-146480: Add tests on _PyErr_SetKeyError() (#146486) (#146512)
authorVictor Stinner <vstinner@python.org>
Fri, 27 Mar 2026 13:09:46 +0000 (14:09 +0100)
committerGitHub <noreply@github.com>
Fri, 27 Mar 2026 13:09:46 +0000 (14:09 +0100)
gh-146480: Add tests on _PyErr_SetKeyError() (#146486)

(cherry picked from commit d4153a9f76736128306c4af01776729da846d926)

Lib/test/test_capi/test_exceptions.py
Modules/_testinternalcapi.c

index 120329542204832a1fa01434d166af96de284fbd..d26ba75b08d9940267aa9d1ee0d5354a05d0b250 100644 (file)
@@ -13,8 +13,9 @@ from test.support.testcase import ExceptionIsLikeMixin
 
 from .test_misc import decode_stderr
 
-# Skip this test if the _testcapi module isn't available.
+# Skip this test if the _testcapi or _testinternalcapi module isn't available.
 _testcapi = import_helper.import_module('_testcapi')
+_testinternalcapi = import_helper.import_module('_testinternalcapi')
 
 NULL = None
 
@@ -108,6 +109,26 @@ class Test_Exceptions(unittest.TestCase):
             b'<string>:7: RuntimeWarning: Testing PyErr_WarnEx',
         ])
 
+    def test__pyerr_setkeyerror(self):
+        # Test _PyErr_SetKeyError()
+        _pyerr_setkeyerror = _testinternalcapi._pyerr_setkeyerror
+        for arg in (
+            "key",
+            # check that a tuple argument is not unpacked
+            (1, 2, 3),
+            # PyErr_SetObject(exc_type, exc_value) uses exc_value if it's
+            # already an exception, but _PyErr_SetKeyError() always creates a
+            # new KeyError.
+            KeyError('arg'),
+        ):
+            with self.subTest(arg=arg):
+                with self.assertRaises(KeyError) as cm:
+                    # Test calling _PyErr_SetKeyError() with an exception set
+                    # to check that the function overrides the current
+                    # exception.
+                    _pyerr_setkeyerror(arg)
+                self.assertEqual(cm.exception.args, (arg,))
+
 
 class Test_FatalError(unittest.TestCase):
 
index dd0fe61d42d25e1483a235fa97cbcfb8253ecaa5..6b5e73e924a2c849b85d3090df6853aac3957447 100644 (file)
@@ -1986,6 +1986,20 @@ gh_119213_getargs_impl(PyObject *module, PyObject *spam)
 }
 
 
+static PyObject *
+_pyerr_setkeyerror(PyObject *self, PyObject *arg)
+{
+    // Test that _PyErr_SetKeyError() overrides the current exception
+    // if an exception is set
+    PyErr_NoMemory();
+
+    _PyErr_SetKeyError(arg);
+
+    assert(PyErr_Occurred());
+    return NULL;
+}
+
+
 static PyMethodDef module_functions[] = {
     {"get_configs", get_configs, METH_NOARGS},
     {"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -2076,6 +2090,7 @@ static PyMethodDef module_functions[] = {
     {"uop_symbols_test", _Py_uop_symbols_test, METH_NOARGS},
 #endif
     GH_119213_GETARGS_METHODDEF
+    {"_pyerr_setkeyerror", _pyerr_setkeyerror, METH_O},
     {NULL, NULL} /* sentinel */
 };