summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Objects/typeobject.c62
1 files changed, 20 insertions, 42 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 46fc2c6..c37e54f 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2905,16 +2905,6 @@ slot_sq_item(PyObject *self, int i)
}
func = _PyType_Lookup(self->ob_type, getitem_str);
if (func != NULL) {
- if (func->ob_type == &PyWrapperDescr_Type) {
- PyWrapperDescrObject *wrapper =
- (PyWrapperDescrObject *)func;
- if (wrapper->d_base->wrapper == wrap_sq_item &&
- PyType_IsSubtype(self->ob_type, wrapper->d_type)) {
- intargfunc f;
- f = (intargfunc)(wrapper->d_wrapped);
- return f(self, i);
- }
- }
if ((f = func->ob_type->tp_descr_get) == NULL)
Py_INCREF(func);
else
@@ -3313,26 +3303,23 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
return res;
}
+/* There are two slot dispatch functions for tp_getattro.
+
+ - slot_tp_getattro() is used when __getattribute__ is overridden
+ but no __getattr__ hook is present;
+
+ - slot_tp_getattr_hook() is used when a __getattr__ hook is present.
+
+ The code in update_slot() and fixup_slot_dispatchers() always installs
+ slot_tp_getattr_hook(); this detects the absence of __getattr__ and then
+ installs the simpler slot if necessary. */
+
static PyObject *
slot_tp_getattro(PyObject *self, PyObject *name)
{
- PyTypeObject *tp = self->ob_type;
- PyObject *getattr;
- static PyObject *getattr_str = NULL;
-
- if (getattr_str == NULL) {
- getattr_str = PyString_InternFromString("__getattribute__");
- if (getattr_str == NULL)
- return NULL;
- }
- getattr = _PyType_Lookup(tp, getattr_str);
- if (getattr == NULL) {
- /* Avoid further slowdowns */
- if (tp->tp_getattro == slot_tp_getattro)
- tp->tp_getattro = PyObject_GenericGetAttr;
- return PyObject_GenericGetAttr(self, name);
- }
- return PyObject_CallFunction(getattr, "OO", self, name);
+ static PyObject *getattribute_str = NULL;
+ return call_method(self, "__getattribute__", &getattribute_str,
+ "(O)", name);
}
static PyObject *
@@ -3355,29 +3342,20 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name)
return NULL;
}
getattr = _PyType_Lookup(tp, getattr_str);
- if (getattr == NULL && tp->tp_getattro == slot_tp_getattr_hook) {
+ if (getattr == NULL) {
/* No __getattr__ hook: use a simpler dispatcher */
tp->tp_getattro = slot_tp_getattro;
return slot_tp_getattro(self, name);
}
getattribute = _PyType_Lookup(tp, getattribute_str);
- if (getattribute != NULL &&
- getattribute->ob_type == &PyWrapperDescr_Type &&
- ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
- (void *)PyObject_GenericGetAttr)
- getattribute = NULL;
- if (getattr == NULL && getattribute == NULL) {
- /* Use the default dispatcher */
- if (tp->tp_getattro == slot_tp_getattr_hook)
- tp->tp_getattro = PyObject_GenericGetAttr;
- return PyObject_GenericGetAttr(self, name);
- }
- if (getattribute == NULL)
+ if (getattribute == NULL ||
+ (getattribute->ob_type == &PyWrapperDescr_Type &&
+ ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
+ (void *)PyObject_GenericGetAttr))
res = PyObject_GenericGetAttr(self, name);
else
res = PyObject_CallFunction(getattribute, "OO", self, name);
- if (getattr != NULL &&
- res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_Clear();
res = PyObject_CallFunction(getattr, "OO", self, name);
}