[Python-bugs-list] [ python-Bugs-544647 ] Inplace multiply by float

noreply@sourceforge.net noreply@sourceforge.net
Tue, 16 Apr 2002 06:01:18 -0700


Bugs item #544647, was opened at 2002-04-16 09:01
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=544647&group_id=5470

Category: Type/class unification
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Jay T Miller (jaytmiller)
Assigned to: Nobody/Anonymous (nobody)
Summary: Inplace multiply by float

Initial Comment:
When I import the following from "example.py":

class test1(object):
   def __init__(self):
        object.__init__(self)

   def __imul__(self, other):
       print "no luck here!"

class test2:
   def __imul__(self, other):
       print "cool!"

t = test1()
u = test2()
t *= 1.0
u *= 1.0

The following happens:

Python 2.3a0 (#6, Apr 15 2002, 17:34:04)
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-98)] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> import example
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
 File "example.py", line 18, in ?
   t *= 1.0
TypeError: can't multiply sequence to non-int
>>>

I take this to mean that python does not (currently)
support inplace multiply by
floats for new style classes.  Is this a bug?  A
permanent limitation?

<speculation>
Looking into this a little, my impression was that the
problem is a result of two things:

1. PyNumber_InPlaceMultiply gives "priority" to
sequence behavior if it is defined (the slot is filled
in) in a C type.

PyObject *
PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
{
        PyObject * (*g)(PyObject *, int) = NULL;
        if (HASINPLACE(v) && v->ob_type->tp_as_sequence &&
                (g =
v->ob_type->tp_as_sequence->sq_inplace_repeat)) {
                long n;
                if (PyInt_Check(w)) {
                        n  = PyInt_AsLong(w);
                }
                else if (PyLong_Check(w)) {
                        n = PyLong_AsLong(w);
                        if (n == -1 && PyErr_Occurred())
                                return NULL;
                }
                else {
                        return type_error("can't
multiply sequence to non-int");
                }
                return (*g)(v, (int)n);
        }
        return binary_iop(v, w,
NB_SLOT(nb_inplace_multiply),
                                NB_SLOT(nb_multiply),
"*=");
}


2. New style classes define all or nearly all slots.  
This means that a new style class is both a sequence
and a number.
</speculation>

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=544647&group_id=5470