https://github.com/python/cpython/commit/6140b0896e95ca96aa15472e14d0502966391485
commit: 6140b0896e95ca96aa15472e14d0502966391485
branch: main
author: Tian Gao <[email protected]>
committer: gaogaotiantian <[email protected]>
date: 2025-02-27T18:12:04-05:00
summary:
gh-127271: Remove the PyCell_Get usage for framelocalsproxy (#130383)
files:
M Objects/frameobject.c
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index dbeee50fcff090..001b58dc052416 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -28,7 +28,7 @@
#define OFF(x) offsetof(PyFrameObject, x)
-// Returns borrowed reference or NULL
+// Returns new reference or NULL
static PyObject *
framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
{
@@ -57,7 +57,10 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame,
PyCodeObject *co, int i)
}
if (cell != NULL) {
- value = PyCell_GET(cell);
+ value = PyCell_GetRef((PyCellObject *)cell);
+ }
+ else {
+ Py_XINCREF(value);
}
if (value == NULL) {
@@ -67,8 +70,19 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame,
PyCodeObject *co, int i)
return value;
}
+static bool
+framelocalsproxy_hasval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
+{
+ PyObject *value = framelocalsproxy_getval(frame, co, i);
+ if (value == NULL) {
+ return false;
+ }
+ Py_DECREF(value);
+ return true;
+}
+
static int
-framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
+framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject *key, bool read,
PyObject **value_ptr)
{
/*
* Returns -2 (!) if an error occurred; exception will be set.
@@ -76,8 +90,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject*
key, bool read)
* - if read == true, returns the index if the value is not NULL
* - if read == false, returns the index if the value is not hidden
* Otherwise returns -1.
+ *
+ * If read == true and value_ptr is not NULL, *value_ptr is set to
+ * the value of the key if it is found (with a new reference).
*/
+ // value_ptr should only be given if we are reading the value
+ assert(read || value_ptr == NULL);
+
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
// Ensure that the key is hashable.
@@ -85,6 +105,7 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject*
key, bool read)
if (key_hash == -1) {
return -2;
}
+
bool found = false;
// We do 2 loops here because it's highly possible the key is interned
@@ -93,7 +114,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame,
PyObject* key, bool read)
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
if (name == key) {
if (read) {
- if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
+ PyObject *value = framelocalsproxy_getval(frame->f_frame, co,
i);
+ if (value != NULL) {
+ if (value_ptr != NULL) {
+ *value_ptr = value;
+ }
+ else {
+ Py_DECREF(value);
+ }
return i;
}
} else {
@@ -124,7 +152,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame,
PyObject* key, bool read)
}
if (same) {
if (read) {
- if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
+ PyObject *value = framelocalsproxy_getval(frame->f_frame, co,
i);
+ if (value != NULL) {
+ if (value_ptr != NULL) {
+ *value_ptr = value;
+ }
+ else {
+ Py_DECREF(value);
+ }
return i;
}
} else {
@@ -142,25 +177,27 @@ static PyObject *
framelocalsproxy_getitem(PyObject *self, PyObject *key)
{
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
- PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
+ PyObject *value = NULL;
- int i = framelocalsproxy_getkeyindex(frame, key, true);
+ int i = framelocalsproxy_getkeyindex(frame, key, true, &value);
if (i == -2) {
return NULL;
}
if (i >= 0) {
- PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
assert(value != NULL);
- return Py_NewRef(value);
+ return value;
}
+ assert(value == NULL);
// Okay not in the fast locals, try extra locals
PyObject *extra = frame->f_extra_locals;
if (extra != NULL) {
- PyObject *value = PyDict_GetItem(extra, key);
+ if (PyDict_GetItemRef(extra, key, &value) < 0) {
+ return NULL;
+ }
if (value != NULL) {
- return Py_NewRef(value);
+ return value;
}
}
@@ -176,7 +213,7 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key,
PyObject *value)
_PyStackRef *fast = _PyFrame_GetLocalsArray(frame->f_frame);
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
- int i = framelocalsproxy_getkeyindex(frame, key, false);
+ int i = framelocalsproxy_getkeyindex(frame, key, false, NULL);
if (i == -2) {
return -1;
}
@@ -297,8 +334,7 @@ framelocalsproxy_keys(PyObject *self, PyObject
*Py_UNUSED(ignored))
}
for (int i = 0; i < co->co_nlocalsplus; i++) {
- PyObject *val = framelocalsproxy_getval(frame->f_frame, co, i);
- if (val) {
+ if (framelocalsproxy_hasval(frame->f_frame, co, i)) {
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
if (PyList_Append(names, name) < 0) {
Py_DECREF(names);
@@ -511,8 +547,10 @@ framelocalsproxy_values(PyObject *self, PyObject
*Py_UNUSED(ignored))
if (value) {
if (PyList_Append(values, value) < 0) {
Py_DECREF(values);
+ Py_DECREF(value);
return NULL;
}
+ Py_DECREF(value);
}
}
@@ -550,16 +588,19 @@ framelocalsproxy_items(PyObject *self, PyObject
*Py_UNUSED(ignored))
PyObject *pair = PyTuple_Pack(2, name, value);
if (pair == NULL) {
Py_DECREF(items);
+ Py_DECREF(value);
return NULL;
}
if (PyList_Append(items, pair) < 0) {
Py_DECREF(items);
Py_DECREF(pair);
+ Py_DECREF(value);
return NULL;
}
Py_DECREF(pair);
+ Py_DECREF(value);
}
}
@@ -601,7 +642,7 @@ framelocalsproxy_length(PyObject *self)
}
for (int i = 0; i < co->co_nlocalsplus; i++) {
- if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
+ if (framelocalsproxy_hasval(frame->f_frame, co, i)) {
size++;
}
}
@@ -613,7 +654,7 @@ framelocalsproxy_contains(PyObject *self, PyObject *key)
{
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
- int i = framelocalsproxy_getkeyindex(frame, key, true);
+ int i = framelocalsproxy_getkeyindex(frame, key, true, NULL);
if (i == -2) {
return -1;
}
@@ -724,7 +765,7 @@ framelocalsproxy_pop(PyObject* self, PyObject *const *args,
Py_ssize_t nargs)
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
- int i = framelocalsproxy_getkeyindex(frame, key, false);
+ int i = framelocalsproxy_getkeyindex(frame, key, false, NULL);
if (i == -2) {
return NULL;
}
@@ -2066,9 +2107,7 @@ _PyFrame_HasHiddenLocals(_PyInterpreterFrame *frame)
_PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
if (kind & CO_FAST_HIDDEN) {
- PyObject* value = framelocalsproxy_getval(frame, co, i);
-
- if (value != NULL) {
+ if (framelocalsproxy_hasval(frame, co, i)) {
return true;
}
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]