[Python-checkins] CVS: python/dist/src/Objects abstract.c,2.79,2.80

Guido van Rossum gvanrossum@users.sourceforge.net
Fri, 28 Sep 2001 16:49:51 -0700


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

Modified Files:
	abstract.c 
Log Message:
It's a fact: for binary operators, *under certain circumstances*,
__rop__ now takes precendence over __op__.  Those circumstances are:

  - Both arguments are new-style classes
  - Both arguments are new-style numbers
  - Their implementation slots for tp_op differ
  - Their types differ
  - The right argument's type is a subtype of the left argument's type

Also did this for the ternary operator (pow) -- only the binary case
is dealt with properly though, since __rpow__ is not supported anyway.



Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.79
retrieving revision 2.80
diff -C2 -d -r2.79 -r2.80
*** abstract.c	2001/09/14 16:47:50	2.79
--- abstract.c	2001/09/28 23:49:48	2.80
***************
*** 301,309 ****
    v	w	Action
    -------------------------------------------------------------------
!   new	new	v.op(v,w), w.op(v,w)
    new	old	v.op(v,w), coerce(v,w), v.op(v,w)
    old	new	w.op(v,w), coerce(v,w), v.op(v,w)
    old	old	coerce(v,w), v.op(v,w)
  
    Legend:
    -------
--- 301,312 ----
    v	w	Action
    -------------------------------------------------------------------
!   new	new	w.op(v,w)[*], v.op(v,w), w.op(v,w)
    new	old	v.op(v,w), coerce(v,w), v.op(v,w)
    old	new	w.op(v,w), coerce(v,w), v.op(v,w)
    old	old	coerce(v,w), v.op(v,w)
  
+   [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
+       v->ob_type
+ 
    Legend:
    -------
***************
*** 319,346 ****
  {
  	PyObject *x;
! 	binaryfunc *slot;
! 	if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v)) {
! 		slot = NB_BINOP(v->ob_type->tp_as_number, op_slot);
! 		if (*slot) {
! 			x = (*slot)(v, w);
! 			if (x != Py_NotImplemented) {
! 				return x;
! 			}
! 			Py_DECREF(x); /* can't do it */
! 		}
! 		if (v->ob_type == w->ob_type) {
! 			goto binop_error;
! 		}
  	}
! 	if (w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
! 		slot = NB_BINOP(w->ob_type->tp_as_number, op_slot);
! 		if (*slot) {
! 			x = (*slot)(v, w);
! 			if (x != Py_NotImplemented) {
! 				return x;
! 			}
! 			Py_DECREF(x); /* can't do it */
! 		}
  	}
  	if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
  		int err = PyNumber_CoerceEx(&v, &w);
--- 322,355 ----
  {
  	PyObject *x;
! 	binaryfunc slotv = NULL;
! 	binaryfunc slotw = NULL;
! 
! 	if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v))
! 		slotv = *NB_BINOP(v->ob_type->tp_as_number, op_slot);
! 	if (w->ob_type != v->ob_type &&
! 	    w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
! 		slotw = *NB_BINOP(w->ob_type->tp_as_number, op_slot);
! 		if (slotw == slotv)
! 			slotw = NULL;
  	}
! 	if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
! 		x = slotw(v, w);
! 		if (x != Py_NotImplemented)
! 			return x;
! 		Py_DECREF(x); /* can't do it */
! 		slotw = NULL;
  	}
+ 	if (slotv) {
+ 		x = slotv(v, w);
+ 		if (x != Py_NotImplemented)
+ 			return x;
+ 		Py_DECREF(x); /* can't do it */
+ 	}
+ 	if (slotw) {
+ 		x = slotw(v, w);
+ 		if (x != Py_NotImplemented)
+ 			return x;
+ 		Py_DECREF(x); /* can't do it */
+ 	}
  	if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
  		int err = PyNumber_CoerceEx(&v, &w);
***************
*** 351,357 ****
  			PyNumberMethods *mv = v->ob_type->tp_as_number;
  			if (mv) {
! 				slot = NB_BINOP(mv, op_slot);
! 				if (*slot) {
! 					PyObject *x = (*slot)(v, w);
  					Py_DECREF(v);
  					Py_DECREF(w);
--- 360,367 ----
  			PyNumberMethods *mv = v->ob_type->tp_as_number;
  			if (mv) {
! 				binaryfunc slot;
! 				slot = *NB_BINOP(mv, op_slot);
! 				if (slot) {
! 					PyObject *x = slot(v, w);
  					Py_DECREF(v);
  					Py_DECREF(w);
***************
*** 364,368 ****
  		}
  	}
- binop_error:
  	Py_INCREF(Py_NotImplemented);
  	return Py_NotImplemented;
--- 374,377 ----
***************
*** 421,424 ****
--- 430,445 ----
  	
  	mv = v->ob_type->tp_as_number;
+ 	mw = w->ob_type->tp_as_number;
+ 	if (v->ob_type != w->ob_type && mw && NEW_STYLE_NUMBER(w)) {
+ 		slot = NB_TERNOP(mw, op_slot);
+ 		if (*slot && *slot != *NB_TERNOP(mv, op_slot) &&
+ 		    PyType_IsSubtype(w->ob_type, v->ob_type)) {
+ 			x = (*slot)(v, w, z);
+ 			if (x != Py_NotImplemented)
+ 				return x;
+ 			/* Can't do it... fall through */
+ 			Py_DECREF(x);
+ 		}
+ 	}
  	if (mv != NULL && NEW_STYLE_NUMBER(v)) {
  		/* try v.op(v,w,z) */
***************
*** 436,440 ****
  		}
  	}
- 	mw = w->ob_type->tp_as_number;
  	if (mw != NULL && NEW_STYLE_NUMBER(w)) {
  		/* try w.op(v,w,z) */
--- 457,460 ----