Skip to content

Commit

Permalink
pythongh-74929: Make containment checks more efficient in `FrameLocal…
Browse files Browse the repository at this point in the history
…sProxy` (python#118624)

Properly implement the `sq_contains` slot for frame locals proxy containment checks.
  • Loading branch information
gaogaotiantian authored May 6, 2024
1 parent 757fd3e commit afbe5bf
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,29 +488,33 @@ framelocalsproxy_length(PyObject *self)
return size;
}

static PyObject*
static int
framelocalsproxy_contains(PyObject *self, PyObject *key)
{
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;

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*
Expand Down Expand Up @@ -604,14 +608,18 @@ 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
framelocalsproxy_setitem, // mp_ass_subscript
};

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},
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit afbe5bf

Please sign in to comment.