Skip to content

Add PyObject_Vectorcall() #62

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

Merged
merged 2 commits into from
Jul 10, 2023
Merged

Add PyObject_Vectorcall() #62

merged 2 commits into from
Jul 10, 2023

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Jul 7, 2023

No description provided.

@vstinner
Copy link
Member Author

vstinner commented Jul 7, 2023

cc @jdemeyer @markshannon @encukou @erlend-aasland @corona10

Do you think that it makes sense to provide PyObject_Vectorcall() on Python 3.8 and older? This PR works on Python 2.7-3.13, PyPy 2 and PyPy 3 (see PR tests).

I chose to only provide PyObject_Vectorcall(). I didn't implement PyObject_VectorcallDict() nor PyObject_VectorcallMethod() (yet). I implemented PyVectorcall_NARGS() and PY_VECTORCALL_ARGUMENTS_OFFSET as well, but I'm not sure that it's worth it.

In Python 3.13, I removed the private alias _PyObject_Vectorcall (to PyObject_Vectorcall()): https://github.com/python/cpython/issues/106084 In Python 3.13, I removed 181 private functions in total. According to a code search on PyPI top 5,000 projects, _PyObject_Vectorcall`` is the mostly called functons of these removed function: python/cpython#106320 (comment)

I chose to write a simple but inefficient implementation just for backward compatibility. It should not be used for best performance: it creates a temporary tuple for positional arguments and a temporary dictionary for keyword arguments.

Writing an efficient implementation would require way more code, but Python 3.7 recently (at 2023-06-27) reached end of life. On CPython 3.8, the private _PyObject_Vectorcall() function is simply used. Only PyPy 3.8 should get bad performance: in exchange, you can use a single code base working on all Python versions and implementations.

@encukou
Copy link
Member

encukou commented Jul 10, 2023

Do you think that it makes sense to provide PyObject_Vectorcall() on Python 3.8 and older?

Yes, I thought the purpose of pythoncapi-compat is to provide backports like this.

I chose to write a simple but inefficient implementation just for backward compatibility.

Yup, being inefficient but correct is IMO a good trade-off for backports.

@vstinner
Copy link
Member Author

Yes, I thought the purpose of pythoncapi-compat is to provide backports like this.

For me, this function is mostly written for performance. Using it on old Python versions make the code less efficient than using PyObject_Call(). But yeah, I concur that it's a nice trade-off.

@vstinner vstinner merged commit 1911dd4 into main Jul 10, 2023
@vstinner vstinner deleted the vectorcall branch July 10, 2023 13:22
@vstinner
Copy link
Member Author

I merged my PR. Thanks for the review @encukou.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants