@@ -2905,16 +2905,6 @@ slot_sq_item(PyObject *self, int i)
29052905 }
29062906 func = _PyType_Lookup (self -> ob_type , getitem_str );
29072907 if (func != NULL ) {
2908- if (func -> ob_type == & PyWrapperDescr_Type ) {
2909- PyWrapperDescrObject * wrapper =
2910- (PyWrapperDescrObject * )func ;
2911- if (wrapper -> d_base -> wrapper == wrap_sq_item &&
2912- PyType_IsSubtype (self -> ob_type , wrapper -> d_type )) {
2913- intargfunc f ;
2914- f = (intargfunc )(wrapper -> d_wrapped );
2915- return f (self , i );
2916- }
2917- }
29182908 if ((f = func -> ob_type -> tp_descr_get ) == NULL )
29192909 Py_INCREF (func );
29202910 else
@@ -3313,26 +3303,23 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
33133303 return res ;
33143304}
33153305
3306+ /* There are two slot dispatch functions for tp_getattro.
3307+
3308+ - slot_tp_getattro() is used when __getattribute__ is overridden
3309+ but no __getattr__ hook is present;
3310+
3311+ - slot_tp_getattr_hook() is used when a __getattr__ hook is present.
3312+
3313+ The code in update_slot() and fixup_slot_dispatchers() always installs
3314+ slot_tp_getattr_hook(); this detects the absence of __getattr__ and then
3315+ installs the simpler slot if necessary. */
3316+
33163317static PyObject *
33173318slot_tp_getattro (PyObject * self , PyObject * name )
33183319{
3319- PyTypeObject * tp = self -> ob_type ;
3320- PyObject * getattr ;
3321- static PyObject * getattr_str = NULL ;
3322-
3323- if (getattr_str == NULL ) {
3324- getattr_str = PyString_InternFromString ("__getattribute__" );
3325- if (getattr_str == NULL )
3326- return NULL ;
3327- }
3328- getattr = _PyType_Lookup (tp , getattr_str );
3329- if (getattr == NULL ) {
3330- /* Avoid further slowdowns */
3331- if (tp -> tp_getattro == slot_tp_getattro )
3332- tp -> tp_getattro = PyObject_GenericGetAttr ;
3333- return PyObject_GenericGetAttr (self , name );
3334- }
3335- return PyObject_CallFunction (getattr , "OO" , self , name );
3320+ static PyObject * getattribute_str = NULL ;
3321+ return call_method (self , "__getattribute__" , & getattribute_str ,
3322+ "(O)" , name );
33363323}
33373324
33383325static PyObject *
@@ -3355,29 +3342,20 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name)
33553342 return NULL ;
33563343 }
33573344 getattr = _PyType_Lookup (tp , getattr_str );
3358- if (getattr == NULL && tp -> tp_getattro == slot_tp_getattr_hook ) {
3345+ if (getattr == NULL ) {
33593346 /* No __getattr__ hook: use a simpler dispatcher */
33603347 tp -> tp_getattro = slot_tp_getattro ;
33613348 return slot_tp_getattro (self , name );
33623349 }
33633350 getattribute = _PyType_Lookup (tp , getattribute_str );
3364- if (getattribute != NULL &&
3365- getattribute -> ob_type == & PyWrapperDescr_Type &&
3366- ((PyWrapperDescrObject * )getattribute )-> d_wrapped ==
3367- (void * )PyObject_GenericGetAttr )
3368- getattribute = NULL ;
3369- if (getattr == NULL && getattribute == NULL ) {
3370- /* Use the default dispatcher */
3371- if (tp -> tp_getattro == slot_tp_getattr_hook )
3372- tp -> tp_getattro = PyObject_GenericGetAttr ;
3373- return PyObject_GenericGetAttr (self , name );
3374- }
3375- if (getattribute == NULL )
3351+ if (getattribute == NULL ||
3352+ (getattribute -> ob_type == & PyWrapperDescr_Type &&
3353+ ((PyWrapperDescrObject * )getattribute )-> d_wrapped ==
3354+ (void * )PyObject_GenericGetAttr ))
33763355 res = PyObject_GenericGetAttr (self , name );
33773356 else
33783357 res = PyObject_CallFunction (getattribute , "OO" , self , name );
3379- if (getattr != NULL &&
3380- res == NULL && PyErr_ExceptionMatches (PyExc_AttributeError )) {
3358+ if (res == NULL && PyErr_ExceptionMatches (PyExc_AttributeError )) {
33813359 PyErr_Clear ();
33823360 res = PyObject_CallFunction (getattr , "OO" , self , name );
33833361 }
0 commit comments