]> granicus.if.org Git - python/commitdiff
A fix for SF bug #461546 (bug in long_mul).
authorGuido van Rossum <guido@python.org>
Sat, 15 Sep 2001 03:14:32 +0000 (03:14 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 15 Sep 2001 03:14:32 +0000 (03:14 +0000)
Both int and long multiplication are changed to be more careful in
their assumptions about when one of the arguments is a sequence: the
assumption that at least one of the arguments must be an int (or long,
respectively) is still held, but the assumption that these don't smell
like sequences is no longer true: a subtype of int or long may well
have a sequence-repeat thingie!

Lib/test/test_descr.py
Objects/intobject.c
Objects/longobject.c

index 06631dc17a6d84a39d0d017da02cd3deaceac721..3b3a34e54de4feff95443697ed90775023e7db34 100644 (file)
@@ -896,6 +896,19 @@ def dynamics():
     d.foo = 1
     verify(d.foo == 1)
 
+    # Test handling of int*seq and seq*int
+    class I(int):
+        __dynamic__ = 1
+    verify("a"*I(2) == "aa")
+    verify(I(2)*"a" == "aa")
+
+    # Test handling of long*seq and seq*long
+    class L(long):
+        __dynamic__ = 1
+    verify("a"*L(2L) == "aa")
+    verify(L(2L)*"a" == "aa")
+    
+
 def errors():
     if verbose: print "Testing errors..."
 
index c93b3840ab28ddb1df65c184f6d83bd605e58e7b..16e4336bbf66d92982ddad952b964cba7db547d4 100644 (file)
@@ -344,14 +344,16 @@ int_mul(PyObject *v, PyObject *w)
        long a, b, ah, bh, x, y;
        int s = 1;
 
-       if (v->ob_type->tp_as_sequence &&
-                       v->ob_type->tp_as_sequence->sq_repeat) {
+       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);
        }
-       else if (w->ob_type->tp_as_sequence &&
-                       w->ob_type->tp_as_sequence->sq_repeat) {
+       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);
index 7c4f75dc6e46cbaced413377cb402168f0fb9a0a..1e01bf074b60874fb730ba9b64579dadc7810e0b 100644 (file)
@@ -183,6 +183,8 @@ PyLong_AsLong(PyObject *vv)
        int i, sign;
 
        if (vv == NULL || !PyLong_Check(vv)) {
+               if (vv != NULL && PyInt_Check(vv))
+                       return PyInt_AsLong(vv);
                PyErr_BadInternalCall();
                return -1;
        }
@@ -1448,17 +1450,19 @@ long_mul(PyLongObject *v, PyLongObject *w)
        int size_a;
        int size_b;
        int i;
-       
-       if (v->ob_type->tp_as_sequence &&
-                       v->ob_type->tp_as_sequence->sq_repeat) {
-               return long_repeat((PyObject *)v, w);
-       }
-       else if (w->ob_type->tp_as_sequence &&
-                       w->ob_type->tp_as_sequence->sq_repeat) {
-               return long_repeat((PyObject *)w, v);
-       }
 
-       CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+       if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
+               if (!PyLong_Check(v) &&
+                   v->ob_type->tp_as_sequence &&
+                   v->ob_type->tp_as_sequence->sq_repeat)
+                       return long_repeat((PyObject *)v, w);
+               if (!PyLong_Check(w) &&
+                        w->ob_type->tp_as_sequence &&
+                        w->ob_type->tp_as_sequence->sq_repeat)
+                       return long_repeat((PyObject *)w, v);
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
 
        size_a = ABS(a->ob_size);
        size_b = ABS(b->ob_size);