]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-135855: Raise TypeError When Passing Non-dict Object to `_interpreters...
authorBrian Schubert <brianm.schubert@gmail.com>
Tue, 24 Jun 2025 22:23:26 +0000 (18:23 -0400)
committerGitHub <noreply@github.com>
Tue, 24 Jun 2025 22:23:26 +0000 (16:23 -0600)
(cherry picked from commit 4e6f0d116e, AKA gh-135856)

Lib/test/test__interpreters.py
Misc/NEWS.d/next/Library/2025-06-23-10-19-11.gh-issue-135855.-J0AGF.rst [new file with mode: 0644]
Modules/_interpretersmodule.c
Python/crossinterp.c

index 3de774ae8b012ea786fdece8746332b3f9517a7e..6fb2bc24fa3ea45963dfbfdfd2e8f4fc7b15158d 100644 (file)
@@ -567,6 +567,22 @@ class CommonTests(TestBase):
             _interpreters.run_string(self.id, 'a', shared=1)
         with self.assertRaisesRegex(TypeError, msg):
             _interpreters.run_func(self.id, lambda: None, shared=1)
+        # See https://github.com/python/cpython/issues/135855
+        msg = r'_interpreters.set___main___attrs\(\) argument 2 must be dict, not int'
+        with self.assertRaisesRegex(TypeError, msg):
+            _interpreters.set___main___attrs(self.id, 1)
+
+    def test_invalid_shared_none(self):
+        msg = "expected 'shared' to be a dict"
+        with self.assertRaisesRegex(TypeError, msg):
+            _interpreters.exec(self.id, 'a', shared=None)
+        with self.assertRaisesRegex(TypeError, msg):
+            _interpreters.run_string(self.id, 'a', shared=None)
+        with self.assertRaisesRegex(TypeError, msg):
+            _interpreters.run_func(self.id, lambda: None, shared=None)
+        msg = "must be dict, not None"
+        with self.assertRaisesRegex(TypeError, msg):
+            _interpreters.set___main___attrs(self.id, None)
 
     def test_invalid_shared_encoding(self):
         # See https://github.com/python/cpython/issues/127196
diff --git a/Misc/NEWS.d/next/Library/2025-06-23-10-19-11.gh-issue-135855.-J0AGF.rst b/Misc/NEWS.d/next/Library/2025-06-23-10-19-11.gh-issue-135855.-J0AGF.rst
new file mode 100644 (file)
index 0000000..fcf495b
--- /dev/null
@@ -0,0 +1,3 @@
+Raise :exc:`TypeError` instead of :exc:`SystemError` when
+:func:`!_interpreters.set___main___attrs` is passed a non-dict object.
+Patch by Brian Schubert.
index 8f7106b6f1ac2a6b9bc7046664de45df0b4cdec0..a8fbf987ab18b3812e0e6f4ce6aba678a1f5b572 100644 (file)
@@ -811,8 +811,8 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
     PyObject *id, *updates;
     int restricted = 0;
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                                     "OO|$p:" MODULE_NAME_STR ".set___main___attrs",
-                                     kwlist, &id, &updates, &restricted))
+                                     "OO!|$p:" MODULE_NAME_STR ".set___main___attrs",
+                                     kwlist, &id, &PyDict_Type, &updates, &restricted))
     {
         return NULL;
     }
@@ -826,16 +826,14 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
     }
 
     // Check the updates.
-    if (updates != Py_None) {
-        Py_ssize_t size = PyObject_Size(updates);
-        if (size < 0) {
-            return NULL;
-        }
-        if (size == 0) {
-            PyErr_SetString(PyExc_ValueError,
-                            "arg 2 must be a non-empty mapping");
-            return NULL;
-        }
+    Py_ssize_t size = PyDict_Size(updates);
+    if (size < 0) {
+        return NULL;
+    }
+    if (size == 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "arg 2 must be a non-empty dict");
+        return NULL;
     }
 
     _PyXI_session session = {0};
index ac379a1ad0fb6d0a7fd710d02661a50915e75f91..8382d8b95e071cc8156650ce5869b1bcbb31c78a 100644 (file)
@@ -1704,6 +1704,7 @@ _PyXI_Enter(_PyXI_session *session,
     // Convert the attrs for cross-interpreter use.
     _PyXI_namespace *sharedns = NULL;
     if (nsupdates != NULL) {
+        assert(PyDict_Check(nsupdates));
         sharedns = _PyXI_NamespaceFromDict(nsupdates, NULL);
         if (sharedns == NULL && PyErr_Occurred()) {
             assert(session->error == NULL);