Operator overloading inconsistency (bug or feature?)
Suppose that a new-style class wants to overload "*" and it defines two methods like this: class Foo(object): def __mul__(self,other): print "__mul__" def __rmul__(self,other): print "__rmul__" Python-2.2.1, if you try this, you get the following behavior:
f = Foo() f*1.0 __mul__ 1.0*f __rmul__ f*1 __mul__ 1*f __mul__
So here is the question: Why does the last statement in this example not invoke __rmul__? In other words, why do "1.0*f" and "1*f" produce different behavior. Is this intentional? Is this documented someplace? Is there a workaround? Or are we just missing something obvious? Cheers, Dave
Suppose that a new-style class wants to overload "*" and it defines two methods like this:
class Foo(object): def __mul__(self,other): print "__mul__" def __rmul__(self,other): print "__rmul__"
Python-2.2.1, if you try this, you get the following behavior:
f = Foo() f*1.0 __mul__ 1.0*f __rmul__ f*1 __mul__ 1*f __mul__
So here is the question: Why does the last statement in this example not invoke __rmul__? In other words, why do "1.0*f" and "1*f" produce different behavior. Is this intentional? Is this documented someplace? Is there a workaround? Or are we just missing something obvious?
Aargh. I *think* this may have to do with the hacks for sequence repetition. But I'm not sure. A debug session tracing carefully through the code is in order. --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
Suppose that a new-style class wants to overload "*" and it defines two methods like this:
class Foo(object): def __mul__(self,other): print "__mul__" def __rmul__(self,other): print "__rmul__"
Python-2.2.1, if you try this, you get the following behavior:
f = Foo() f*1.0
__mul__
1.0*f
__rmul__
f*1
__mul__
1*f
__mul__
So here is the question: Why does the last statement in this example not invoke __rmul__? In other words, why do "1.0*f" and "1*f" produce different behavior. Is this intentional? Is this documented someplace? Is there a workaround? Or are we just missing something obvious?
Aargh. I *think* this may have to do with the hacks for sequence repetition. But I'm not sure. A debug session tracing carefully through the code is in order.
--Guido van Rossum (home page: http://www.python.org/~guido/)
I guess the problem arise from here: intobject.c(340): ======================== static PyObject * int_mul(PyObject *v, PyObject *w) { long a, b; long longprod; /* a*b in native long arithmetic */ double doubled_longprod; /* (double)longprod */ double doubleprod; /* (double)a * (double)b */ if (!PyInt_Check(v) && v->ob_type->tp_as_sequence && v->ob_type->tp_as_sequence->sq_repeat) { /* sequence * int */ a = PyInt_AsLong(w); return (*v->ob_type->tp_as_sequence->sq_repeat)(v, a); } if (!PyInt_Check(w) && w->ob_type->tp_as_sequence && w->ob_type->tp_as_sequence->sq_repeat) { /* int * sequence */ a = PyInt_AsLong(v); return (*w->ob_type->tp_as_sequence->sq_repeat)(w, a); } ............. ================== and the facts that: 1.- there is only one 'sq_repeat' method, and not an addittional 'sq_rrepeat' one, so, n*x and x*n call the same method sq_repeat. 2.- in typeobect.c, sq_repeat is associated with __mul__ line 2775: SLOT1(slot_sq_repeat, "__mul__", int, "i") line 3497: SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc, "x.__mul__(n) <==> x*n"), 3.- the 'object' class by default enable the "tp_as_sequence" attribute, triggering the call of sq_repeat in the case 1*c but not in 1.0*c Marcelo
[me]
Aargh. I *think* this may have to do with the hacks for sequence repetition. But I'm not sure. A debug session tracing carefully through the code is in order.
[Marcelo Matus]
I guess the problem arise from here: [...]
Good sleuthing, Marcelo! Neil S. came up with a fix that I believe is correct, and I recommend that we'll check that in for 2.3 as well as on the 2.2 maintenance branch. Thanks again, Neil! --Guido van Rossum (home page: http://www.python.org/~guido/)
Yes, it wokrs here, thanks very much for your promptly answer Marcelo Neil Schemenauer wrote:
See python.org/sf/592646 for a possible fix.
Neil _______________________________________________ Swig-dev mailing list - Swig-dev@cs.uchicago.edu http://mailman.cs.uchicago.edu/mailman/listinfo/swig-dev
participants (4)
-
David Beazley
-
Guido van Rossum
-
Marcelo Matus
-
Neil Schemenauer