Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1. Add Add NULL check and fallback to ga_vectorcall
2. Add Null check to _Py_make_parameters when_PyTuple_Resize fails and parameter is null
11 changes: 9 additions & 2 deletions Objects/genericaliasobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ _Py_make_parameters(PyObject *args)
len += needed;
if (_PyTuple_Resize(&parameters, len) < 0) {
Py_DECREF(subparams);
Py_DECREF(parameters);
Py_XDECREF(parameters);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Apparently _PyTuple_Resize sets its arg to NULL on failures, so this will never be non-NULL. Possibly the only safe way to use _PyTuple_Resize is to keep another pointer to the tuple around and DECREF that on failure? I haven't verified in the code though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Simply remove this line.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yes

checked in

Py_XDECREF(v);

removing the redundant Py_XDECREF call

Py_XDECREF(tuple_args);
return NULL;
}
Expand Down Expand Up @@ -650,7 +650,14 @@ ga_vectorcall(PyObject *self, PyObject *const *args,
size_t nargsf, PyObject *kwnames)
{
gaobject *alias = (gaobject *) self;
PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames);
vectorcallfunc origin_vectorcall = PyVectorcall_Function(alias->origin);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The docs say this is primarily useful for checking whether a callable supports vectorcall. Why don't we unconditionally call PyObject_Vectorcall, which automatically falls back to non-vectorcall if needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

makes sense
I checked the code flow PyObject_Vectorcall internally calls https://github.com/python/cpython/blob/main/Include/internal/pycore_call.h#L140-L142 PyVectorcall_Function

i will update the code

PyObject *obj;
if (origin_vectorcall != NULL) {
obj = origin_vectorcall(alias->origin, args, nargsf, kwnames);
} else {
/* Fallback to generic call path*/
obj = PyObject_Vectorcall(alias->origin, args, nargsf, kwnames);
}
return set_orig_class(obj, self);
}

Expand Down
Loading