[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 ----