From 7e35d57c0cd94b136d613129cb22a2b4252aa008 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 15 Sep 2001 03:14:32 +0000 Subject: [PATCH] A fix for SF bug #461546 (bug in long_mul). 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 | 13 +++++++++++++ Objects/intobject.c | 10 ++++++---- Objects/longobject.c | 24 ++++++++++++++---------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 06631dc17a..3b3a34e54d 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -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..." diff --git a/Objects/intobject.c b/Objects/intobject.c index c93b3840ab..16e4336bbf 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -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); diff --git a/Objects/longobject.c b/Objects/longobject.c index 7c4f75dc6e..1e01bf074b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -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); -- 2.40.0