[Python-checkins] python/dist/src/Objects typeobject.c,2.148,2.149

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Mon, 10 Jun 2002 07:30:45 -0700


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

Modified Files:
	typeobject.c 
Log Message:
Three's a charm: yet another fix for SF bug 551412.  Thinking again
about the test case, slot_nb_power gets called on behalf of its second
argument, but with a non-None modulus it wouldn't check this, and
believes it is called on behalf of its first argument.  Fix this
properly, and get rid of the code in _PyType_Lookup() that tries to
call _PyType_Ready().  But do leave a check for a NULL tp_mro there,
because this can still legitimately occur.

I'll fix this in 2.2.x too.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.148
retrieving revision 2.149
diff -C2 -d -r2.148 -r2.149
*** typeobject.c	4 Jun 2002 19:52:53 -0000	2.148
--- typeobject.c	10 Jun 2002 14:30:43 -0000	2.149
***************
*** 1310,1329 ****
  	/* Look in tp_dict of types in MRO */
  	mro = type->tp_mro;
! 	if (mro == NULL) {
! 		if (PyType_Ready(type) < 0) {
! 			/* It's not ideal to clear the error condition,
! 			   but this function is documented as not setting
! 			   an exception, and I don't want to change that.
! 			   When PyType_Ready() can't proceed, it won't
! 			   set the "ready" flag, so future attempts to ready
! 			   the same type will call it again -- hopefully
! 			   in a context that propagates the exception out.
! 			*/
! 			PyErr_Clear();
! 			return NULL;
! 		}
! 		mro = type->tp_mro;
! 		assert(mro != NULL);
! 	}
  	assert(PyTuple_Check(mro));
  	n = PyTuple_GET_SIZE(mro);
--- 1310,1320 ----
  	/* Look in tp_dict of types in MRO */
  	mro = type->tp_mro;
! 
! 	/* If mro is NULL, the type is either not yet initialized
! 	   by PyType_Ready(), or already cleared by type_clear().
! 	   Either way the safest thing to do is to return NULL. */
! 	if (mro == NULL)
! 		return NULL;
! 
  	assert(PyTuple_Check(mro));
  	n = PyTuple_GET_SIZE(mro);
***************
*** 3100,3106 ****
  	if (modulus == Py_None)
  		return slot_nb_power_binary(self, other);
! 	/* Three-arg power doesn't use __rpow__ */
! 	return call_method(self, "__pow__", &pow_str,
! 			   "(OO)", other, modulus);
  }
  
--- 3091,3104 ----
  	if (modulus == Py_None)
  		return slot_nb_power_binary(self, other);
! 	/* Three-arg power doesn't use __rpow__.  But ternary_op
! 	   can call this when the second argument's type uses
! 	   slot_nb_power, so check before calling self.__pow__. */
! 	if (self->ob_type->tp_as_number != NULL &&
! 	    self->ob_type->tp_as_number->nb_power == slot_nb_power) {
! 		return call_method(self, "__pow__", &pow_str,
! 				   "(OO)", other, modulus);
! 	}
! 	Py_INCREF(Py_NotImplemented);
! 	return Py_NotImplemented;
  }