-
-
Notifications
You must be signed in to change notification settings - Fork 34k
gh-115754: Add Py_GetConstantRef() function #116883
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
Conversation
|
About the function name Py_GetConstantRef(): sometimes documentation refer to them as "constants", sometimes as "singletons": C API:
Python API:
In PyPy, are these constants guaranteed to be unique singletons? I added Py_IsNone() for PyPy and HPy.
To be more friendly with other Python implementations which will implement these functions, I would prefer to avoid being specific about "singletons" and stick to "constant" name. |
|
See also the discussion in 2020 about per-interpreter singletons: #83692 At the end, it was decided to go with PEP 683 Immortal objects. |
|
Thanks for trying it out! I only have two comments about the naming. I'd rather I also think that we need an extra part to the enum names - |
Do you have a name to suggest? In practice, you can just use
Currently, Py_None, Py_True, etc. are borrowed references. For backward compatibility, I would prefer to keep a public function replacing them. Moreover, it looks easy to upgrade code from PyConstant() to PyConstantRef(), since you just have to add
|
|
As for the function naming, I think I'd be happy with Languages other than C are going to have to use this function, as they can't use our macros. And I want them to choose the "right" function (strong reference) because it's obvious. |
|
I updated my PR:
At the end, we get: I'm not sure that |
gvanrossum
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't force-push, it makes reviewing hard.
Oh. I'm used to use |
|
That's more productive for you, but more work for a reviewer. :-( |
Or |
|
I'm fine with |
|
I updated the PR:
I rebased the PR to fix merge conflicts. |
zooba
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No changes needed, but I did suggest a couple things to maybe think about either now or in the future.
| _PyUnicode_InitState(interp); | ||
|
|
||
| if (_Py_IsMainInterpreter(interp)) { | ||
| _Py_GetConstant_Init(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking ahead a little bit here, and we could change this later, but I think I'd pass interp into the init function (and it can do the IsMain check now, or later change to some other interpreter-specific behaviour if it becomes interesting/necessary).
@ericsnowcurrently FYI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 10 constants are immortal, right now I don't see the advantage to pass an interpreter state (or check for _Py_IsMainInterpreter () inside the funciton). If later it changes, we can easily pass interp, since it's an internal function.
|
Thanks for mentioning immortality as an implementation detail. If it was a guarantee of the API, there'd be no difference between |
|
I updated the PR to address @zooba's review. |
|
About the doc, I chose to use a table to give constant values: |
|
@zooba @encukou @gvanrossum: Would you mind to review the updated PR? |
encukou
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall, thank you for the addition!
I do have some comments:
|
@encukou: I applied your suggestions, please review the updated PR. |
This is stable ABI; future versions of Python might add new values. But yes, |
encukou
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
gvanrossum
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, looks good!
Add Py_GetConstant() and Py_GetConstantBorrowed() functions. In the limited C API version 3.13, getting Py_None, Py_False, Py_True, Py_Ellipsis and Py_NotImplemented singletons is now implemented as function calls at the stable ABI level to hide implementation details. Getting these constants still return borrowed references. Add _testlimitedcapi/object.c and test_capi/test_object.py to test Py_GetConstant() and Py_GetConstantBorrowed() functions.
|
Ok, thanks for reviews. Now that the PR is approved, I rebased it to solve the merge conflicts, and I enabled auto-merged. |
|
I added the two functions to pythoncapi-commit: python/pythoncapi-compat@b16ff9a |

Add Py_GetConstantRef() and Py_GetConstant() functions.
In the limited C API version 3.13, getting Py_None, Py_False, Py_True, Py_Ellipsis and Py_NotImplemented singletons is now implemented as function calls at the stable ABI level to hide implementation details. Getting these constants still return borrowed references.
Add _testlimitedcapi/object.c and test_capi/test_object.py to test Py_GetConstantRef() and Py_GetConstant() functions.
📚 Documentation preview 📚: https://cpython-previews--116883.org.readthedocs.build/