[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.119,2.120
Guido van Rossum
gvanrossum@users.sourceforge.net
Mon, 03 Dec 2001 07:36:30 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv7905
Modified Files:
typeobject.c
Log Message:
Address SF patch #480716 as well as related issues.
SF patch #480716 by Greg Chapman fixes the problem that super's
__get__ method always returns an instance of super, even when the
instance whose __get__ method is called is an instance of a subclass
of super.
Other issues fixed:
- super(C, C()).__class__ would return the __class__ attribute of C()
rather than the __class__ attribute of the super object. This is
confusing. To fix this, I decided to change the semantics of super
so that it only applies to code attributes, not to data attributes.
After all, overriding data attributes is not supported anyway.
- While super(C, x) carefully checked that x is an instance of C,
super(C).__get__(x) made no such check, allowing for a loophole.
This is now fixed.
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.119
retrieving revision 2.120
diff -C2 -d -r2.119 -r2.120
*** typeobject.c 2001/12/03 00:08:33 2.119
--- typeobject.c 2001/12/03 15:36:28 2.120
***************
*** 3930,3934 ****
continue;
res = PyDict_GetItem(dict, name);
! if (res != NULL) {
Py_INCREF(res);
f = res->ob_type->tp_descr_get;
--- 3930,3934 ----
continue;
res = PyDict_GetItem(dict, name);
! if (res != NULL && !PyDescr_IsData(res)) {
Py_INCREF(res);
f = res->ob_type->tp_descr_get;
***************
*** 3945,3948 ****
--- 3945,3963 ----
}
+ static int
+ supercheck(PyTypeObject *type, PyObject *obj)
+ {
+ if (!PyType_IsSubtype(obj->ob_type, type) &&
+ !(PyType_Check(obj) &&
+ PyType_IsSubtype((PyTypeObject *)obj, type))) {
+ PyErr_SetString(PyExc_TypeError,
+ "super(type, obj): "
+ "obj must be an instance or subtype of type");
+ return -1;
+ }
+ else
+ return 0;
+ }
+
static PyObject *
super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
***************
*** 3956,3967 ****
return self;
}
! new = (superobject *)PySuper_Type.tp_new(&PySuper_Type, NULL, NULL);
! if (new == NULL)
! return NULL;
! Py_INCREF(su->type);
! Py_INCREF(obj);
! new->type = su->type;
! new->obj = obj;
! return (PyObject *)new;
}
--- 3971,3993 ----
return self;
}
! if (su->ob_type != &PySuper_Type)
! /* If su is an instance of a subclass of super,
! call its type */
! return PyObject_CallFunction((PyObject *)su->ob_type,
! "OO", su->type, obj);
! else {
! /* Inline the common case */
! if (supercheck(su->type, obj) < 0)
! return NULL;
! new = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
! NULL, NULL);
! if (new == NULL)
! return NULL;
! Py_INCREF(su->type);
! Py_INCREF(obj);
! new->type = su->type;
! new->obj = obj;
! return (PyObject *)new;
! }
}
***************
*** 3977,3989 ****
if (obj == Py_None)
obj = NULL;
! if (obj != NULL &&
! !PyType_IsSubtype(obj->ob_type, type) &&
! !(PyType_Check(obj) &&
! PyType_IsSubtype((PyTypeObject *)obj, type))) {
! PyErr_SetString(PyExc_TypeError,
! "super(type, obj): "
! "obj must be an instance or subtype of type");
return -1;
- }
Py_INCREF(type);
Py_XINCREF(obj);
--- 4003,4008 ----
if (obj == Py_None)
obj = NULL;
! if (obj != NULL && supercheck(type, obj) < 0)
return -1;
Py_INCREF(type);
Py_XINCREF(obj);