]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-138479: Ensure that `__typing_subst__` returns a tuple (GH-138482) (#138784)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 12 Sep 2025 13:23:03 +0000 (15:23 +0200)
committerGitHub <noreply@github.com>
Fri, 12 Sep 2025 13:23:03 +0000 (16:23 +0300)
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_typing.py
Misc/NEWS.d/next/Core_and_Builtins/2025-09-03-17-00-30.gh-issue-138479.qUxgWs.rst [new file with mode: 0644]
Objects/genericaliasobject.c

index cd552f9887d8a01c1ef88a9f96442c0816d3d96a..2aae92c5ea10216baab08cca767495e318d3e0ba 100644 (file)
@@ -5797,6 +5797,23 @@ class GenericTests(BaseTestCase):
                     with self.assertRaises(TypeError):
                         a[int]
 
+    def test_return_non_tuple_while_unpacking(self):
+        # GH-138497: GenericAlias objects didn't ensure that __typing_subst__ actually
+        # returned a tuple
+        class EvilTypeVar:
+            __typing_is_unpacked_typevartuple__ = True
+            def __typing_prepare_subst__(*_):
+                return None  # any value
+            def __typing_subst__(*_):
+                return 42  # not tuple
+
+        evil = EvilTypeVar()
+        # Create a dummy TypeAlias that will be given the evil generic from
+        # above.
+        type type_alias[*_] = 0
+        with self.assertRaisesRegex(TypeError, ".+__typing_subst__.+tuple.+int.*"):
+            type_alias[evil][0]
+
 
 class ClassVarTests(BaseTestCase):
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-03-17-00-30.gh-issue-138479.qUxgWs.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-03-17-00-30.gh-issue-138479.qUxgWs.rst
new file mode 100644 (file)
index 0000000..c94640a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a crash when a generic object's ``__typing_subst__`` returns an object
+that isn't a :class:`tuple`.
index 3bb961aa2b619d982c7b4679395fd3d8d4c2ea13..2ef2ec1c54a2342927783a267b72616cb06484a6 100644 (file)
@@ -525,12 +525,24 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
             return NULL;
         }
         if (unpack) {
+            if (!PyTuple_Check(arg)) {
+                Py_DECREF(newargs);
+                Py_DECREF(item);
+                Py_XDECREF(tuple_args);
+                PyObject *original = PyTuple_GET_ITEM(args, iarg);
+                PyErr_Format(PyExc_TypeError,
+                             "expected __typing_subst__ of %T objects to return a tuple, not %T",
+                             original, arg);
+                Py_DECREF(arg);
+                return NULL;
+            }
             jarg = tuple_extend(&newargs, jarg,
                     &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg));
             Py_DECREF(arg);
             if (jarg < 0) {
                 Py_DECREF(item);
                 Py_XDECREF(tuple_args);
+                assert(newargs == NULL);
                 return NULL;
             }
         }