mirror of https://github.com/python/cpython
gh-74929: Make containment checks more efficient in `FrameLocalsProxy` (#118624)
Properly implement the `sq_contains` slot for frame locals proxy containment checks.
This commit is contained in:
parent
757fd3e010
commit
afbe5bf9c8
|
@ -488,7 +488,7 @@ framelocalsproxy_length(PyObject *self)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static int
|
||||||
framelocalsproxy_contains(PyObject *self, PyObject *key)
|
framelocalsproxy_contains(PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
||||||
|
@ -496,21 +496,25 @@ framelocalsproxy_contains(PyObject *self, PyObject *key)
|
||||||
if (PyUnicode_CheckExact(key)) {
|
if (PyUnicode_CheckExact(key)) {
|
||||||
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
Py_RETURN_TRUE;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *extra = ((PyFrameObject*)frame)->f_extra_locals;
|
PyObject *extra = ((PyFrameObject*)frame)->f_extra_locals;
|
||||||
if (extra != NULL) {
|
if (extra != NULL) {
|
||||||
int result = PyDict_Contains(extra, key);
|
return PyDict_Contains(extra, key);
|
||||||
if (result < 0) {
|
|
||||||
return NULL;
|
|
||||||
} else if (result > 0) {
|
|
||||||
Py_RETURN_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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*
|
static PyObject*
|
||||||
|
@ -604,6 +608,10 @@ static PyNumberMethods framelocalsproxy_as_number = {
|
||||||
.nb_inplace_or = framelocalsproxy_inplace_or,
|
.nb_inplace_or = framelocalsproxy_inplace_or,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PySequenceMethods framelocalsproxy_as_sequence = {
|
||||||
|
.sq_contains = framelocalsproxy_contains,
|
||||||
|
};
|
||||||
|
|
||||||
static PyMappingMethods framelocalsproxy_as_mapping = {
|
static PyMappingMethods framelocalsproxy_as_mapping = {
|
||||||
framelocalsproxy_length, // mp_length
|
framelocalsproxy_length, // mp_length
|
||||||
framelocalsproxy_getitem, // mp_subscript
|
framelocalsproxy_getitem, // mp_subscript
|
||||||
|
@ -611,7 +619,7 @@ static PyMappingMethods framelocalsproxy_as_mapping = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef framelocalsproxy_methods[] = {
|
static PyMethodDef framelocalsproxy_methods[] = {
|
||||||
{"__contains__", framelocalsproxy_contains, METH_O | METH_COEXIST,
|
{"__contains__", framelocalsproxy___contains__, METH_O | METH_COEXIST,
|
||||||
NULL},
|
NULL},
|
||||||
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST,
|
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST,
|
||||||
NULL},
|
NULL},
|
||||||
|
@ -639,6 +647,7 @@ PyTypeObject PyFrameLocalsProxy_Type = {
|
||||||
.tp_dealloc = (destructor)framelocalsproxy_dealloc,
|
.tp_dealloc = (destructor)framelocalsproxy_dealloc,
|
||||||
.tp_repr = &framelocalsproxy_repr,
|
.tp_repr = &framelocalsproxy_repr,
|
||||||
.tp_as_number = &framelocalsproxy_as_number,
|
.tp_as_number = &framelocalsproxy_as_number,
|
||||||
|
.tp_as_sequence = &framelocalsproxy_as_sequence,
|
||||||
.tp_as_mapping = &framelocalsproxy_as_mapping,
|
.tp_as_mapping = &framelocalsproxy_as_mapping,
|
||||||
.tp_getattro = PyObject_GenericGetAttr,
|
.tp_getattro = PyObject_GenericGetAttr,
|
||||||
.tp_setattro = PyObject_GenericSetAttr,
|
.tp_setattro = PyObject_GenericSetAttr,
|
||||||
|
|
Loading…
Reference in New Issue