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

Guido van Rossum gvanrossum@users.sourceforge.net
Fri, 17 Aug 2001 04:18:40 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv26582

Modified Files:
	typeobject.c 
Log Message:
type_new(): only defer to the winning metatype if it's different from
the metatype passed in as an argument.  This prevents infinite
recursion when a metatype written in Python calls type.__new__() as a
"super" call.

Also tweaked some comments.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.38
retrieving revision 2.39
diff -C2 -d -r2.38 -r2.39
*** typeobject.c	2001/08/16 18:52:43	2.38
--- typeobject.c	2001/08/17 11:18:38	2.39
***************
*** 498,510 ****
  	static char *kwlist[] = {"name", "bases", "dict", 0};
  	PyObject *slots, *tmp;
! 	PyTypeObject *type, *base, *tmptype;
  	etype *et;
  	struct memberlist *mp;
  	int i, nbases, nslots, slotoffset, dynamic;
  
  	if (metatype == &PyType_Type &&
  	    PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
  	    (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) {
- 		/* type(x) -> x.__class__ */
  		PyObject *x = PyTuple_GET_ITEM(args, 0);
  		Py_INCREF(x->ob_type);
--- 498,510 ----
  	static char *kwlist[] = {"name", "bases", "dict", 0};
  	PyObject *slots, *tmp;
! 	PyTypeObject *type, *base, *tmptype, *winner;
  	etype *et;
  	struct memberlist *mp;
  	int i, nbases, nslots, slotoffset, dynamic;
  
+ 	/* Special case: type(x) should return x->ob_type */
  	if (metatype == &PyType_Type &&
  	    PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
  	    (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) {
  		PyObject *x = PyTuple_GET_ITEM(args, 0);
  		Py_INCREF(x->ob_type);
***************
*** 512,516 ****
  	}
  
! 	/* Check arguments */
  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist,
  					 &name,
--- 512,516 ----
  	}
  
! 	/* Check arguments: (name, bases, dict) */
  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist,
  					 &name,
***************
*** 524,534 ****
  	   it's possible that its instances are not types. */
  	nbases = PyTuple_GET_SIZE(bases);
  	for (i = 0; i < nbases; i++) {
  		tmp = PyTuple_GET_ITEM(bases, i);
  		tmptype = tmp->ob_type;
! 		if (PyType_IsSubtype(metatype, tmptype))
  			continue;
! 		if (PyType_IsSubtype(tmptype, metatype)) {
! 			metatype = tmptype;
  			continue;
  		}
--- 524,535 ----
  	   it's possible that its instances are not types. */
  	nbases = PyTuple_GET_SIZE(bases);
+ 	winner = metatype;
  	for (i = 0; i < nbases; i++) {
  		tmp = PyTuple_GET_ITEM(bases, i);
  		tmptype = tmp->ob_type;
! 		if (PyType_IsSubtype(winner, tmptype))
  			continue;
! 		if (PyType_IsSubtype(tmptype, winner)) {
! 			winner = tmptype;
  			continue;
  		}
***************
*** 537,542 ****
  		return NULL;
  	}
! 	if (metatype->tp_new != type_new) /* Pass it to the winner */
! 		return metatype->tp_new(metatype, args, kwds);
  
  	/* Adjust for empty tuple bases */
--- 538,546 ----
  		return NULL;
  	}
! 	if (winner != metatype) {
! 		if (winner->tp_new != type_new) /* Pass it to the winner */
! 			return winner->tp_new(winner, args, kwds);
! 		metatype = winner;
! 	}
  
  	/* Adjust for empty tuple bases */