mirror of
https://github.com/python/cpython.git
synced 2025-08-11 04:19:06 +00:00
gh-87729: specialize LOAD_SUPER_ATTR_METHOD (#103809)
This commit is contained in:
parent
cef542ca57
commit
ef25febcf2
14 changed files with 539 additions and 357 deletions
|
@ -9380,22 +9380,19 @@ super_repr(PyObject *self)
|
|||
su->type ? su->type->tp_name : "NULL");
|
||||
}
|
||||
|
||||
// if `method` is non-NULL, we are looking for a method descriptor,
|
||||
// and setting `*method` to 1 means we found one.
|
||||
/* Do a super lookup without executing descriptors or falling back to getattr
|
||||
on the super object itself.
|
||||
|
||||
May return NULL with or without an exception set, like PyDict_GetItemWithError. */
|
||||
static PyObject *
|
||||
do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj,
|
||||
PyTypeObject *su_obj_type, PyObject *name, int *method)
|
||||
_super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *name)
|
||||
{
|
||||
PyObject *mro, *res;
|
||||
Py_ssize_t i, n;
|
||||
int temp_su = 0;
|
||||
|
||||
if (su_obj_type == NULL)
|
||||
goto skip;
|
||||
|
||||
mro = su_obj_type->tp_mro;
|
||||
if (mro == NULL)
|
||||
goto skip;
|
||||
return NULL;
|
||||
|
||||
assert(PyTuple_Check(mro));
|
||||
n = PyTuple_GET_SIZE(mro);
|
||||
|
@ -9407,7 +9404,7 @@ do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj,
|
|||
}
|
||||
i++; /* skip su->type (if any) */
|
||||
if (i >= n)
|
||||
goto skip;
|
||||
return NULL;
|
||||
|
||||
/* keep a strong reference to mro because su_obj_type->tp_mro can be
|
||||
replaced during PyDict_GetItemWithError(dict, name) */
|
||||
|
@ -9420,22 +9417,6 @@ do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj,
|
|||
res = PyDict_GetItemWithError(dict, name);
|
||||
if (res != NULL) {
|
||||
Py_INCREF(res);
|
||||
if (method && _PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
|
||||
*method = 1;
|
||||
}
|
||||
else {
|
||||
descrgetfunc f = Py_TYPE(res)->tp_descr_get;
|
||||
if (f != NULL) {
|
||||
PyObject *res2;
|
||||
res2 = f(res,
|
||||
/* Only pass 'obj' param if this is instance-mode super
|
||||
(See SF ID #743627) */
|
||||
(su_obj == (PyObject *)su_obj_type) ? NULL : su_obj,
|
||||
(PyObject *)su_obj_type);
|
||||
Py_SETREF(res, res2);
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(mro);
|
||||
return res;
|
||||
}
|
||||
|
@ -9447,6 +9428,45 @@ do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj,
|
|||
i++;
|
||||
} while (i < n);
|
||||
Py_DECREF(mro);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if `method` is non-NULL, we are looking for a method descriptor,
|
||||
// and setting `*method = 1` means we found one.
|
||||
static PyObject *
|
||||
do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj,
|
||||
PyTypeObject *su_obj_type, PyObject *name, int *method)
|
||||
{
|
||||
PyObject *res;
|
||||
int temp_su = 0;
|
||||
|
||||
if (su_obj_type == NULL) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
res = _super_lookup_descr(su_type, su_obj_type, name);
|
||||
if (res != NULL) {
|
||||
if (method && _PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
|
||||
*method = 1;
|
||||
}
|
||||
else {
|
||||
descrgetfunc f = Py_TYPE(res)->tp_descr_get;
|
||||
if (f != NULL) {
|
||||
PyObject *res2;
|
||||
res2 = f(res,
|
||||
/* Only pass 'obj' param if this is instance-mode super
|
||||
(See SF ID #743627) */
|
||||
(su_obj == (PyObject *)su_obj_type) ? NULL : su_obj,
|
||||
(PyObject *)su_obj_type);
|
||||
Py_SETREF(res, res2);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skip:
|
||||
if (su == NULL) {
|
||||
|
@ -9544,6 +9564,18 @@ _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *me
|
|||
return res;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PySuper_LookupDescr(PyTypeObject *su_type, PyObject *su_obj, PyObject *name)
|
||||
{
|
||||
PyTypeObject *su_obj_type = supercheck(su_type, su_obj);
|
||||
if (su_obj_type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject *res = _super_lookup_descr(su_type, su_obj_type, name);
|
||||
Py_DECREF(su_obj_type);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue