mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
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!
This commit is contained in:
parent
0891ac017d
commit
7e35d57c0c
3 changed files with 33 additions and 14 deletions
|
@ -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..."
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue