[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.119,2.120

Guido van Rossum gvanrossum@users.sourceforge.net
2001年12月03日 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);

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