[Python-checkins] python/dist/src/Objects typeobject.c,2.208,2.209
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Tue, 11 Feb 2003 19:58:40 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv1947/Objects
Modified Files:
typeobject.c
Log Message:
Implement another useful feature for proxies: in super(X, x), x may
now be a proxy for an X instance, as long as issubclass(x.__class__, X).
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.208
retrieving revision 2.209
diff -C2 -d -r2.208 -r2.209
*** typeobject.c 11 Feb 2003 20:38:29 -0000 2.208
--- typeobject.c 12 Feb 2003 03:58:38 -0000 2.209
***************
*** 5026,5029 ****
--- 5026,5030 ----
PyTypeObject *type;
PyObject *obj;
+ PyTypeObject *obj_type;
} superobject;
***************
*** 5033,5036 ****
--- 5034,5039 ----
{"__self__", T_OBJECT, offsetof(superobject, obj), READONLY,
"the instance invoking super(); may be None"},
+ {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY,
+ "the type of the the instance invoking super(); may be None"},
{0}
};
***************
*** 5044,5047 ****
--- 5047,5051 ----
Py_XDECREF(su->obj);
Py_XDECREF(su->type);
+ Py_XDECREF(su->obj_type);
self->ob_type->tp_free(self);
}
***************
*** 5052,5060 ****
superobject *su = (superobject *)self;
! if (su->obj)
return PyString_FromFormat(
"<super: <class '%s'>, <%s object>>",
su->type ? su->type->tp_name : "NULL",
! su->obj->ob_type->tp_name);
else
return PyString_FromFormat(
--- 5056,5064 ----
superobject *su = (superobject *)self;
! if (su->obj_type)
return PyString_FromFormat(
"<super: <class '%s'>, <%s object>>",
su->type ? su->type->tp_name : "NULL",
! su->obj_type->tp_name);
else
return PyString_FromFormat(
***************
*** 5068,5072 ****
superobject *su = (superobject *)self;
! if (su->obj != NULL) {
PyObject *mro, *res, *tmp, *dict;
PyTypeObject *starttype;
--- 5072,5076 ----
superobject *su = (superobject *)self;
! if (su->obj_type != NULL) {
PyObject *mro, *res, *tmp, *dict;
PyTypeObject *starttype;
***************
*** 5074,5078 ****
int i, n;
! starttype = su->obj->ob_type;
mro = starttype->tp_mro;
--- 5078,5082 ----
int i, n;
! starttype = su->obj_type;
mro = starttype->tp_mro;
***************
*** 5087,5090 ****
--- 5091,5095 ----
break;
}
+ #if 0
if (i >= n && PyType_Check(su->obj)) {
starttype = (PyTypeObject *)(su->obj);
***************
*** 5102,5105 ****
--- 5107,5111 ----
}
}
+ #endif
i++;
res = NULL;
***************
*** 5129,5145 ****
}
! 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;
}
--- 5135,5203 ----
}
! static PyTypeObject *
supercheck(PyTypeObject *type, PyObject *obj)
{
! /* Check that a super() call makes sense. Return a type object.
!
! obj can be a new-style class, or an instance of one:
!
! - If it is a class, it must be a subclass of 'type'. This case is
! used for class methods; the return value is obj.
!
! - If it is an instance, it must be an instance of 'type'. This is
! the normal case; the return value is obj.__class__.
!
! But... when obj is an instance, we want to allow for the case where
! obj->ob_type is not a subclass of type, but obj.__class__ is!
! This will allow using super() with a proxy for obj.
! */
!
! if (PyType_Check(obj)) {
! /* It's a new-style class */
! if (PyType_IsSubtype((PyTypeObject *)obj, type)) {
! Py_INCREF(obj);
! return (PyTypeObject *)obj;
! }
! else
! goto fail;
! }
! else if (PyType_IsSubtype(obj->ob_type, type)) {
! Py_INCREF(obj->ob_type);
! return obj->ob_type;
! }
! else {
! /* Try the slow way */
! static PyObject *class_str = NULL;
! PyObject *class_attr;
!
! if (class_str == NULL) {
! class_str = PyString_FromString("__class__");
! if (class_str == NULL)
! return NULL;
! }
!
! class_attr = PyObject_GetAttr(obj, class_str);
!
! if (class_attr != NULL &&
! PyType_Check(class_attr) &&
! (PyTypeObject *)class_attr != obj->ob_type)
! {
! int ok = PyType_IsSubtype(
! (PyTypeObject *)class_attr, type);
! if (ok)
! return (PyTypeObject *)class_attr;
! }
!
! if (class_attr == NULL)
! PyErr_Clear();
! else
! Py_DECREF(class_attr);
! }
!
! fail:
! PyErr_SetString(PyExc_TypeError,
"super(type, obj): "
"obj must be an instance or subtype of type");
! return NULL;
}
***************
*** 5162,5166 ****
else {
/* Inline the common case */
! if (supercheck(su->type, obj) < 0)
return NULL;
new = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
--- 5220,5225 ----
else {
/* Inline the common case */
! PyTypeObject *obj_type = supercheck(su->type, obj);
! if (obj_type == NULL)
return NULL;
new = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
***************
*** 5172,5175 ****
--- 5231,5235 ----
new->type = su->type;
new->obj = obj;
+ new->obj_type = obj_type;
return (PyObject *)new;
}
***************
*** 5182,5185 ****
--- 5242,5246 ----
PyTypeObject *type;
PyObject *obj = NULL;
+ PyTypeObject *obj_type = NULL;
if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj))
***************
*** 5187,5196 ****
if (obj == Py_None)
obj = NULL;
! if (obj != NULL && supercheck(type, obj) < 0)
! return -1;
Py_INCREF(type);
- Py_XINCREF(obj);
su->type = type;
su->obj = obj;
return 0;
}
--- 5248,5261 ----
if (obj == Py_None)
obj = NULL;
! if (obj != NULL) {
! obj_type = supercheck(type, obj);
! if (obj_type == NULL)
! return -1;
! Py_INCREF(obj);
! }
Py_INCREF(type);
su->type = type;
su->obj = obj;
+ su->obj_type = obj_type;
return 0;
}
***************
*** 5220,5223 ****
--- 5285,5289 ----
VISIT(su->obj);
VISIT(su->type);
+ VISIT(su->obj_type);
#undef VISIT