https://github.com/python/cpython/commit/04fe3836023ac30dc6cdb6529c7a7d6eb0549c91
commit: 04fe3836023ac30dc6cdb6529c7a7d6eb0549c91
branch: 3.13
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-27T14:09:46+01:00
summary:

[3.13] gh-146480: Add tests on _PyErr_SetKeyError() (#146486) (#146512)

gh-146480: Add tests on _PyErr_SetKeyError() (#146486)

(cherry picked from commit d4153a9f76736128306c4af01776729da846d926)

files:
M Lib/test/test_capi/test_exceptions.py
M Modules/_testinternalcapi.c

diff --git a/Lib/test/test_capi/test_exceptions.py 
b/Lib/test/test_capi/test_exceptions.py
index 12032954220483..d26ba75b08d994 100644
--- a/Lib/test/test_capi/test_exceptions.py
+++ b/Lib/test/test_capi/test_exceptions.py
@@ -13,8 +13,9 @@
 
 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 @@ def __del__(self):
             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):
 
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index dd0fe61d42d25e..6b5e73e924a2c8 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -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 */
 };
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to