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):
--- /dev/null
+Fix a crash when a generic object's ``__typing_subst__`` returns an object
+that isn't a :class:`tuple`.
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;
}
}