]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-102493: backport unit test for PyErr_SetObject (#102602)
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Sat, 11 Mar 2023 15:01:01 +0000 (15:01 +0000)
committerGitHub <noreply@github.com>
Sat, 11 Mar 2023 15:01:01 +0000 (15:01 +0000)
gh-102493: backport unit test for PyErr_SetObject

Lib/test/test_capi/test_misc.py
Modules/_testcapimodule.c

index db7a7741621979df16a007cfab243187c691b4fc..67150a8d24cb122c1d2941f789cdf818608abefc 100644 (file)
@@ -133,6 +133,34 @@ class CAPITest(unittest.TestCase):
         else:
             self.assertTrue(False)
 
+    def test_set_object(self):
+        # new exception as obj is not an exception
+        with self.assertRaises(ValueError) as e:
+            _testcapi.exc_set_object(ValueError, 42)
+        self.assertEqual(e.exception.args, (42,))
+
+        # wraps the exception because unrelated types
+        with self.assertRaises(ValueError) as e:
+            _testcapi.exc_set_object(ValueError, TypeError(1,2,3))
+        wrapped = e.exception.args[0]
+        self.assertIsInstance(wrapped, TypeError)
+        self.assertEqual(wrapped.args, (1, 2, 3))
+
+        # is superclass, so does not wrap
+        with self.assertRaises(PermissionError) as e:
+            _testcapi.exc_set_object(OSError, PermissionError(24))
+        self.assertEqual(e.exception.args, (24,))
+
+        class Meta(type):
+            def __subclasscheck__(cls, sub):
+                1/0
+
+        class Broken(Exception, metaclass=Meta):
+            pass
+
+        with self.assertRaises(ZeroDivisionError) as e:
+            _testcapi.exc_set_object(Broken, Broken())
+
     @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
     def test_seq_bytes_to_charp_array(self):
         # Issue #15732: crash in _PySequence_BytesToCharpArray()
index 71501b97a8c51a9ace6d412838db35523cf227b8..6a38cc17bcc7cb73a448f367dc839bf1c9e4956f 100644 (file)
@@ -2523,6 +2523,20 @@ pyobject_bytes_from_null(PyObject *self, PyObject *Py_UNUSED(ignored))
     return PyObject_Bytes(NULL);
 }
 
+static PyObject *
+exc_set_object(PyObject *self, PyObject *args)
+{
+    PyObject *exc;
+    PyObject *obj;
+
+    if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
+        return NULL;
+    }
+
+    PyErr_SetObject(exc, obj);
+    return NULL;
+}
+
 static PyObject *
 raise_exception(PyObject *self, PyObject *args)
 {
@@ -6379,6 +6393,7 @@ static PyObject *getargs_s_hash_int2(PyObject *, PyObject *, PyObject*);
 static PyObject *gh_99240_clear_args(PyObject *, PyObject *);
 
 static PyMethodDef TestMethods[] = {
+    {"exc_set_object",          exc_set_object,                  METH_VARARGS},
     {"raise_exception",         raise_exception,                 METH_VARARGS},
     {"raise_memoryerror",       raise_memoryerror,               METH_NOARGS},
     {"set_errno",               set_errno,                       METH_VARARGS},