summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorTian Gao <gaogaotiantian@hotmail.com>2024-05-06 10:16:48 (GMT)
committerGitHub <noreply@github.com>2024-05-06 10:16:48 (GMT)
commitafbe5bf9c8c621bb19833a06e296245c41f0dbc5 (patch)
tree6bf544f596c6d33f6604634921b63d99ab764ca2 /Objects
parent757fd3e0101c85081dfec60cbab26519b7a40305 (diff)
downloadcpython-afbe5bf9c8c621bb19833a06e296245c41f0dbc5.zip
cpython-afbe5bf9c8c621bb19833a06e296245c41f0dbc5.tar.gz
cpython-afbe5bf9c8c621bb19833a06e296245c41f0dbc5.tar.bz2
gh-74929: Make containment checks more efficient in `FrameLocalsProxy` (#118624)
Properly implement the `sq_contains` slot for frame locals proxy containment checks.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/frameobject.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index fdac869..aac809b 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -488,7 +488,7 @@ framelocalsproxy_length(PyObject *self)
return size;
}
-static PyObject*
+static int
framelocalsproxy_contains(PyObject *self, PyObject *key)
{
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
@@ -496,21 +496,25 @@ framelocalsproxy_contains(PyObject *self, PyObject *key)
if (PyUnicode_CheckExact(key)) {
int i = framelocalsproxy_getkeyindex(frame, key, true);
if (i >= 0) {
- Py_RETURN_TRUE;
+ return 1;
}
}
PyObject *extra = ((PyFrameObject*)frame)->f_extra_locals;
if (extra != NULL) {
- int result = PyDict_Contains(extra, key);
- if (result < 0) {
- return NULL;
- } else if (result > 0) {
- Py_RETURN_TRUE;
- }
+ return PyDict_Contains(extra, key);
}
- Py_RETURN_FALSE;
+ return 0;
+}
+
+static PyObject* framelocalsproxy___contains__(PyObject *self, PyObject *key)
+{
+ int result = framelocalsproxy_contains(self, key);
+ if (result < 0) {
+ return NULL;
+ }
+ return PyBool_FromLong(result);
}
static PyObject*
@@ -604,6 +608,10 @@ static PyNumberMethods framelocalsproxy_as_number = {
.nb_inplace_or = framelocalsproxy_inplace_or,
};
+static PySequenceMethods framelocalsproxy_as_sequence = {
+ .sq_contains = framelocalsproxy_contains,
+};
+
static PyMappingMethods framelocalsproxy_as_mapping = {
framelocalsproxy_length, // mp_length
framelocalsproxy_getitem, // mp_subscript
@@ -611,7 +619,7 @@ static PyMappingMethods framelocalsproxy_as_mapping = {
};
static PyMethodDef framelocalsproxy_methods[] = {
- {"__contains__", framelocalsproxy_contains, METH_O | METH_COEXIST,
+ {"__contains__", framelocalsproxy___contains__, METH_O | METH_COEXIST,
NULL},
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST,
NULL},
@@ -639,6 +647,7 @@ PyTypeObject PyFrameLocalsProxy_Type = {
.tp_dealloc = (destructor)framelocalsproxy_dealloc,
.tp_repr = &framelocalsproxy_repr,
.tp_as_number = &framelocalsproxy_as_number,
+ .tp_as_sequence = &framelocalsproxy_as_sequence,
.tp_as_mapping = &framelocalsproxy_as_mapping,
.tp_getattro = PyObject_GenericGetAttr,
.tp_setattro = PyObject_GenericSetAttr,