Skip to content

Commit fbfbfdf

Browse files
miss-islingtonZeroIntensityserhiy-storchaka
authored
[3.14] pythongh-138479: Ensure that __typing_subst__ returns a tuple (pythonGH-138482) (python#138784)
Co-authored-by: Peter Bierma <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 440b83f commit fbfbfdf

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

Lib/test/test_typing.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5797,6 +5797,23 @@ class A:
57975797
with self.assertRaises(TypeError):
57985798
a[int]
57995799

5800+
def test_return_non_tuple_while_unpacking(self):
5801+
# GH-138497: GenericAlias objects didn't ensure that __typing_subst__ actually
5802+
# returned a tuple
5803+
class EvilTypeVar:
5804+
__typing_is_unpacked_typevartuple__ = True
5805+
def __typing_prepare_subst__(*_):
5806+
return None # any value
5807+
def __typing_subst__(*_):
5808+
return 42 # not tuple
5809+
5810+
evil = EvilTypeVar()
5811+
# Create a dummy TypeAlias that will be given the evil generic from
5812+
# above.
5813+
type type_alias[*_] = 0
5814+
with self.assertRaisesRegex(TypeError, ".+__typing_subst__.+tuple.+int.*"):
5815+
type_alias[evil][0]
5816+
58005817

58015818
class ClassVarTests(BaseTestCase):
58025819

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash when a generic object's ``__typing_subst__`` returns an object
2+
that isn't a :class:`tuple`.

Objects/genericaliasobject.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,12 +525,24 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
525525
return NULL;
526526
}
527527
if (unpack) {
528+
if (!PyTuple_Check(arg)) {
529+
Py_DECREF(newargs);
530+
Py_DECREF(item);
531+
Py_XDECREF(tuple_args);
532+
PyObject *original = PyTuple_GET_ITEM(args, iarg);
533+
PyErr_Format(PyExc_TypeError,
534+
"expected __typing_subst__ of %T objects to return a tuple, not %T",
535+
original, arg);
536+
Py_DECREF(arg);
537+
return NULL;
538+
}
528539
jarg = tuple_extend(&newargs, jarg,
529540
&PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg));
530541
Py_DECREF(arg);
531542
if (jarg < 0) {
532543
Py_DECREF(item);
533544
Py_XDECREF(tuple_args);
545+
assert(newargs == NULL);
534546
return NULL;
535547
}
536548
}

0 commit comments

Comments
 (0)