gh-138479: Ensure that __typing_subst__ returns a tuple (GH-138482)
Raise an exception if __typing_subst__ returns a non-tuple object. --------- Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
@@ -5844,6 +5844,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):
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Fix a crash when a generic object's ``__typing_subst__`` returns an object
|
||||
that isn't a :class:`tuple`.
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user