Uh oh!
There was an error while loading. Please reload this page.
gh-87390: Fix starred tuple equality and pickling - #92249
Conversation
b808ffd to
335747dCompareJelleZijlstra
commented
May 3, 2022
I think this is worth a NEWS entry; it's been a while since we put the rest of this code into main. I'll review the PR now. |
JelleZijlstra
left a comment
There was a problem hiding this comment.
Thanks! I'm a little unhappy about making unpacked a public argument to the constructor, but I'm not sure how else we'd get pickling to work.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
mrahtz
commented
May 3, 2022
I've added a NEWS entry for this specific change, but just to double check - were you thinking of this specific change, or the rest of the PEP 646-related changes we made to |
JelleZijlstra
commented
May 3, 2022
Just for this change (the PR title would be good as a NEWS entry too). |
| "must be a bool (since it's a flag controlling " | ||
| "whether the alias is unpacked)"); |
There was a problem hiding this comment.
| "must be a bool (since it's a flag controlling " | |
| "whether the alias is unpacked)"); | |
| "must be a bool"); |
We don't need the explanation.
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Great work! We're pretty close.
| PyObject *starred = PyBool_FromLong(alias->starred); | ||
| PyObject *value = Py_BuildValue("O(OOO)", Py_TYPE(alias), | ||
| alias->origin, alias->args, starred); | ||
| // Avoid double increment of reference count on Py_True/Py_False - once from | ||
| // PyBool_FromLong, and once from Py_BuildValue. | ||
| Py_CLEAR(starred); | ||
| return value; |
There was a problem hiding this comment.
How about:
| PyObject*starred=PyBool_FromLong(alias->starred); | |
| PyObject*value=Py_BuildValue("O(OOO)", Py_TYPE(alias), | |
| alias->origin, alias->args, starred); | |
| // Avoid double increment of reference count on Py_True/Py_False - once from | |
| // PyBool_FromLong, and once from Py_BuildValue. | |
| Py_CLEAR(starred); | |
| returnvalue; | |
| PyObject*starred=alias->starred ? Py_True : Py_False; | |
| returnPy_BuildValue("O(OOO)", Py_TYPE(alias), | |
| alias->origin, alias->args, starred); | |
BTW, if you don't want to use the code above, you can avoid the double incref by using the format string O(OON). N doesn't incref. https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
| return NULL; | ||
| } | ||
| if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2)) { | ||
| if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 3)) { |
There was a problem hiding this comment.
Please update the creation signature in the docs https://docs.python.org/3/library/types.html#types.GenericAlias.
Also, this doesn't break backwards compatibility right? IIUC, the two-argument form will still work.
| PyObject *origin = PyTuple_GET_ITEM(args, 0); | ||
| PyObject *arguments = PyTuple_GET_ITEM(args, 1); | ||
There was a problem hiding this comment.
This code has gotten complex enough that I recommend using https://docs.python.org/3/c-api/arg.html#c.PyArg_ParseTuple or https://docs.python.org/3/c-api/arg.html#c.PyArg_UnpackTuple instead to parse our arguments for us.
The format value list is on that page. But off the top of my head, it should be OO|O:GenericAlias. Then you keep your bool checking/error raising code below.
There was a problem hiding this comment.
Argument clinic can also be used here.
| "whether the alias is unpacked)"); | ||
| return NULL; | ||
| } | ||
| starred = PyLong_AsLong(py_starred); |
There was a problem hiding this comment.
I'm surprised you don't need to cast to (bool) here (or maybe it's implicit, I don't remember how C treats this).
Fidget-Spinner
commented
May 4, 2022
Azure pipelines patcheck fail is unrelated, I will fix it on main. |
Fidget-Spinner
commented
May 4, 2022
Nevermind, it seems that 65f88a6 fixed the whitespace issues, so this just needs updating from main. |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
I do not like an idea about extending GenericAlias() with the third parameter. It is a public API.
I'll provide an alternate PR.
serhiy-storchaka
commented
May 5, 2022
See #92337. |
carljm
commented
May 7, 2022
Looks like this can be closed since the alternative was already merged. |
Hilariously, before this PR, it turned out that
*tuple[int]was equal totuple[int]. Fixing it, I realised that pickling was also broken: it didn't preservegaobject.starred. This PR fixes both.I've tested for refleaks with
python3 -m test -v test_genericalias -R 3:3, and it came back clean, so I think we're good.@Fidget-Spinner I guess you're the one most familiar with this code? :)