gh-123660: Internal macros for accessing empty tuple singleton #123661
+34
−74
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While writing this PR, I thought about the following:
For callables that need an empty tuple, using the macro should be recommended. This will 1) reduce the number of lines (we don't need to check if the value is NULL for instance) 2) make it clear that we are using an empty tuple.
We should replace calls of the form
return PyTuple_New(0)
to calls of the formPy_GetConstant(...)
andPy_GetConstantBorrowed
depending on the semantics. This is something that is important, both for contributors that read the code and for detecting the places where this should be done.There are places where the compiler would not accept a non-static value (when you initialize structures for instance). In those places, AFAICT, we can only use the macro form and not a call.
While there are many occurrences of constructing empty tuples, they don't have the same semantic meaning. I decided to only replace the following:
_Py_SINGLETON
.PyArg_ParseTupleAndKeywords
.There are other usages where you return an empty tuple, you call
PyObject_Call
or other functions, but since the diff would be much larger, I decided not to do it for those files. I also removed an empty tuple reference from the lzma's state since it's not needed at all and could make the module slightly faster to instantiate.While using
_Py_EMPTY_TUPLE
overPyTuple_New(0)
could be slightly faster (or maybe not, I don't know), it removes the needs of redundant checksif (arg == NULL) { ... }
since empty tuples are immortal. Currently, those kind of checks still exist, probably because they were not removed when we introduced immortal objects. There is a trade-off between changing everything and removing the checks or not changing all places and only keep the relevant ones changed.I'm willing to revert the commit for the changes with
PyArg_ParseTupleAndKeywords
andPyCode_New
but I'd like to keep the one concerning the LZMA module.