Skip to content
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

gh-124445: Allow specializing generic ParamSpec aliases #124512

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

tomasr8
Copy link
Member

@tomasr8 tomasr8 commented Sep 25, 2024

I think I more or less understood how this is supposed to work, but please let me know if I missed something :)
Also, if you think I should add more tests.

Objects/genericaliasobject.c Outdated Show resolved Hide resolved
Objects/genericaliasobject.c Outdated Show resolved Hide resolved
Lib/test/test_genericalias.py Show resolved Hide resolved
Objects/genericaliasobject.c Outdated Show resolved Hide resolved
@tomasr8
Copy link
Member Author

tomasr8 commented Sep 25, 2024

Just trying to debug this weird error now:

Objects/tupleobject.c:408: _PyObject_GC_TRACK: Assertion "!_PyObject_GC_IS_TRACKED(((PyObject*)(op)))" failed: object already tracked by the garbage collector                                
Fatal Python error: Segmentation fault

Unfortunately seems to only happen when running the tests, not when I run the test case as a script :/

tomasr8 and others added 2 commits September 25, 2024 22:05
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
@tomasr8
Copy link
Member Author

tomasr8 commented Sep 26, 2024

Ready for another round :)

Lib/test/test_genericalias.py Show resolved Hide resolved
Objects/genericaliasobject.c Outdated Show resolved Hide resolved
Objects/genericaliasobject.c Outdated Show resolved Hide resolved
Objects/genericaliasobject.c Outdated Show resolved Hide resolved
tomasr8 and others added 3 commits September 29, 2024 16:16
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Py_ssize_t len = nargs;
PyObject *parameters = PyTuple_New(len);
if (parameters == NULL)
return NULL;
Py_ssize_t iparam = 0;
for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
PyObject *t = PyTuple_GET_ITEM(args, iarg);
PyObject *t = is_args_tuple ? PyTuple_GET_ITEM(args, iarg) : PyList_GET_ITEM(args, iarg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still unsafe for lists, since below you invoke code that might call back into arbitrary Python code that mutates the list. I think for safety, you need to either convert the list into a tuple or use an iteration API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn Python getting in the way of my C code 😅 I'll use the tuple workaround..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I think that should be fixed. I now convert the arguments to a tuple before processing them. Btw, do you have any opinion on this? #124512 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't entirely agree with Daraan; I have it on my todo list to respond to the Discuss thread they opened.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Jelle, just wondering if you've had the time to ponder this issue? What should we do about this PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again I'm not sure what I was thinking of; I think Daraan's post was mostly right.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(replying to your discourse answer): I think making generic aliases hashable by converting lists to tuples is a good idea but I'd prefer to implement it in a separate PR (@Daraan already made an issue for it) since it affects both the C (GenericAlias) and Python (_GenericAlias) implementations.

If that's fine by you, then this PR is ready for a final check :)

Lib/test/test_genericalias.py Show resolved Hide resolved

// Recursively substitute params in lists/tuples.
if (PyTuple_Check(arg) || PyList_Check(arg)) {
PyObject *subargs = _Py_subs_parameters(self, arg, parameters, item);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing parameters as is here seems wrong; what if we only need part of the parameters? _Py_subs_parameters will error if the count doesn't match. The test case I suggested should help verify this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually with some local testing it seems this does work correctly. More tests would be useful though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually uncovered an issue where nested args tuples would be converted to lists, which should be now fixed.
Also added more tests if you feel like having another look :)

@@ -0,0 +1 @@
Allow specializing Generic ParamSpec aliases
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't very clear. Something like "Fix specialization of generic aliases that are generic over a :class:typing.ParamSpec and have been specialized with a nested type variable."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! That's much clearer 🙂

@tomasr8 tomasr8 requested a review from Daraan November 16, 2024 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants