[Python-checkins] python/dist/src/Objects typeobject.c,2.208,2.209

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
2003年2月11日 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

AltStyle によって変換されたページ (->オリジナル) /