-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
gh-138479: Ensure that __typing_subst__
returns a tuple
#138482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
9458120
c70e82e
cb4351b
c50846b
04d509c
761812d
46b6fa3
4445b5a
d80223a
b8ced40
ff5078e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5844,6 +5844,21 @@ class A: | |
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() | ||
type type_alias[*_] = 0 | ||
with self.assertRaises(TypeError): | ||
|
||
type_alias[evil][0] | ||
|
||
|
||
class ClassVarTests(BaseTestCase): | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fix a crash when a generic object's ``__typing_subst__`` returns an object | ||
that isn't a :class:`tuple`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -525,12 +525,24 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje | |
return NULL; | ||
} | ||
if (unpack) { | ||
if (!PyTuple_Check(arg)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we care about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be fine to do either. It would technically be a breaking change to disallow tuple subclasses here, but I doubt anyone is actually doing that in practice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an internal undocumented API so I wouldn't feel terrible about disallowing tuple subclasses, but we could go either way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's just use |
||
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; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't comment there but are we leaking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like it. Do you want me to fix that in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, might as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
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); | ||
/* newargs was stolen */ | ||
picnixz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
return NULL; | ||
} | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.