-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
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-127058: Make PySequence_Tuple
safer and probably faster.
#127758
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
``PySequence_Tuple`` now creates the resulting tuple atomically, preventing | ||
partially created tuples being visible to the garbage collector or through | ||
``gc.get_referrers()`` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3174,6 +3174,25 @@ PyList_AsTuple(PyObject *v) | |
return ret; | ||
} | ||
|
||
PyObject * | ||
_PyList_AsTupleAndClear(PyListObject *self) | ||
{ | ||
assert(self != NULL); | ||
PyObject *ret; | ||
if (self->ob_item == NULL) { | ||
return PyTuple_New(0); | ||
} | ||
Py_BEGIN_CRITICAL_SECTION(self); | ||
PyObject **items = self->ob_item; | ||
Py_ssize_t size = Py_SIZE(self); | ||
self->ob_item = NULL; | ||
Py_SET_SIZE(self, 0); | ||
ret = _PyTuple_FromArraySteal(items, size); | ||
free_list_items(items, false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically it is passed a stack-allocated array, so it can't free it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I meant if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
Py_END_CRITICAL_SECTION(); | ||
return ret; | ||
} | ||
|
||
PyObject * | ||
_PyList_FromStackRefSteal(const _PyStackRef *src, Py_ssize_t n) | ||
{ | ||
|
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 think the name
_PyList_AsTupleAndClear
might be confusing, because if you calledPy_CLEAR
on the list you wouldn't need to decref it.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.
But if you called
PyList_Clear
on it, you would need toPy_DECREF
it.It is the list being cleared, not the variable holding a reference to it.