[pypy-commit] pypy default: Broke some pre-translated case (r_int64 + r_int32). Fix and tests
arigo
pypy.commits at gmail.com
Fri Nov 11 03:20:01 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r88311:1be7f6327a03
Date: 2016-11-11 09:19 +0100
http://bitbucket.org/pypy/pypy/changeset/1be7f6327a03/
Log: Broke some pre-translated case (r_int64 + r_int32). Fix and tests
diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -323,96 +323,165 @@
def __add__(self, other):
x = long(self)
- y = other # may be a float
+ if not isinstance(other, (int, long)):
+ return x + other
+ y = long(other)
return self._widen(other, x + y)
- __radd__ = __add__
+
+ def __radd__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return other + x
+ y = long(other)
+ return self._widen(other, x + y)
def __sub__(self, other):
x = long(self)
- y = other # may be a float
+ if not isinstance(other, (int, long)):
+ return x - other
+ y = long(other)
return self._widen(other, x - y)
def __rsub__(self, other):
y = long(self)
- x = other # may be a float
+ if not isinstance(other, (int, long)):
+ return other - y
+ x = long(other)
return self._widen(other, x - y)
def __mul__(self, other):
x = long(self)
- y = other # may be a float
- z = x * y
- if isinstance(z, (int, long)):
- z = self._widen(other, z)
- return z
- __rmul__ = __mul__
+ if not isinstance(other, (int, long)):
+ return x * other
+ y = long(other)
+ return self._widen(other, x * y)
+
+ def __rmul__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return other * x
+ y = long(other)
+ return self._widen(other, x * y)
def __div__(self, other):
x = long(self)
- y = other # may be a float
- return self._widen(other, x / y)
-
- __floordiv__ = __div__
+ if not isinstance(other, (int, long)):
+ return x / other
+ y = long(other)
+ return self._widen(other, x // y)
def __rdiv__(self, other):
y = long(self)
- x = other # may be a float
- return self._widen(other, x / y)
+ if not isinstance(other, (int, long)):
+ return other / y
+ x = long(other)
+ return self._widen(other, x // y)
- __rfloordiv__ = __rdiv__
+ def __floordiv__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return x // other
+ y = long(other)
+ return self._widen(other, x // y)
+
+ def __rfloordiv__(self, other):
+ y = long(self)
+ if not isinstance(other, (int, long)):
+ return other // y
+ x = long(other)
+ return self._widen(other, x // y)
def __mod__(self, other):
x = long(self)
- y = other # not rpython if it is a float
+ if not isinstance(other, (int, long)):
+ return x % other
+ y = long(other)
return self._widen(other, x % y)
def __rmod__(self, other):
y = long(self)
- x = other # not rpython if it is a float
+ if not isinstance(other, (int, long)):
+ return other % y
+ x = long(other)
return self._widen(other, x % y)
def __divmod__(self, other):
x = long(self)
+ if not isinstance(other, (int, long)):
+ return divmod(x, other)
y = long(other)
res = divmod(x, y)
- return (self.__class__(res[0]), self.__class__(res[1]))
+ return (self._widen(other, res[0]), self._widen(other, res[1]))
def __lshift__(self, n):
x = long(self)
+ if not isinstance(n, (int, long)):
+ raise TypeError
y = long(n)
return self.__class__(x << y)
def __rlshift__(self, n):
y = long(self)
+ if not isinstance(n, (int, long)):
+ raise TypeError
x = long(n)
- return self._widen(n, x << y)
+ return n.__class__(x << y)
def __rshift__(self, n):
x = long(self)
+ if not isinstance(n, (int, long)):
+ raise TypeError
y = long(n)
- return self._widen(n, x >> y)
+ return self.__class__(x >> y)
def __rrshift__(self, n):
y = long(self)
+ if not isinstance(n, (int, long)):
+ raise TypeError
x = long(n)
- return self._widen(n, x >> y)
+ return n.__class__(x >> y)
def __or__(self, other):
x = long(self)
+ if not isinstance(other, (int, long)):
+ return x | other
y = long(other)
return self._widen(other, x | y)
- __ror__ = __or__
+
+ def __ror__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return other | x
+ y = long(other)
+ return self._widen(other, x | y)
def __and__(self, other):
x = long(self)
+ if not isinstance(other, (int, long)):
+ return x & other
y = long(other)
return self._widen(other, x & y)
- __rand__ = __and__
+
+ def __rand__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return other & x
+ y = long(other)
+ return self._widen(other, x & y)
def __xor__(self, other):
x = long(self)
+ if not isinstance(other, (int, long)):
+ return x ^ other
y = long(other)
return self._widen(other, x ^ y)
- __rxor__ = __xor__
+
+ def __rxor__(self, other):
+ x = long(self)
+ if not isinstance(other, (int, long)):
+ return other ^ x
+ y = long(other)
+ return self._widen(other, x ^ y)
def __neg__(self):
x = long(self)
@@ -431,12 +500,16 @@
def __pow__(self, other, m=None):
x = long(self)
+ if not isinstance(other, (int, long)):
+ return pow(x, other, m)
y = long(other)
res = pow(x, y, m)
return self._widen(other, res)
def __rpow__(self, other, m=None):
y = long(self)
+ if not isinstance(other, (int, long)):
+ return pow(other, y, m)
x = long(other)
res = pow(x, y, m)
return self._widen(other, res)
diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py
--- a/rpython/rlib/test/test_rarithmetic.py
+++ b/rpython/rlib/test/test_rarithmetic.py
@@ -603,11 +603,75 @@
assert r_uint64(self._64_umax) + r_uint64(1) == r_uint64(0)
assert r_uint64(0) - r_uint64(1) == r_uint64(self._64_umax)
- def test_operation_with_float(self):
- def f(x):
- assert r_longlong(x) + 0.5 == 43.5
- assert r_longlong(x) - 0.5 == 42.5
- assert r_longlong(x) * 0.5 == 21.5
- assert r_longlong(x) / 0.8 == 53.75
- f(43)
- interpret(f, [43])
+
+def test_operation_with_float():
+ def f(x):
+ assert r_longlong(x) + 0.5 == 43.5
+ assert r_longlong(x) - 0.5 == 42.5
+ assert r_longlong(x) * 0.5 == 21.5
+ assert r_longlong(x) / 0.8 == 53.75
+ f(43)
+ interpret(f, [43])
+
+def test_int64_plus_int32():
+ assert r_uint64(1234567891234) + r_uint32(1) == r_uint64(1234567891235)
+
+def test_fallback_paths():
+
+ def make(pattern):
+ def method(self, other, *extra):
+ if extra:
+ assert extra == (None,) # for 'pow'
+ if type(other) is long:
+ return pattern % other
+ else:
+ return NotImplemented
+ return method
+
+ class A(object):
+ __add__ = make("a+%d")
+ __radd__ = make("%d+a")
+ __sub__ = make("a-%d")
+ __rsub__ = make("%d-a")
+ __mul__ = make("a*%d")
+ __rmul__ = make("%d*a")
+ __div__ = make("a/%d")
+ __rdiv__ = make("%d/a")
+ __floordiv__ = make("a//%d")
+ __rfloordiv__ = make("%d//a")
+ __mod__ = make("a%%%d")
+ __rmod__ = make("%d%%a")
+ __and__ = make("a&%d")
+ __rand__ = make("%d&a")
+ __or__ = make("a|%d")
+ __ror__ = make("%d|a")
+ __xor__ = make("a^%d")
+ __rxor__ = make("%d^a")
+ __pow__ = make("a**%d")
+ __rpow__ = make("%d**a")
+
+ a = A()
+ assert r_uint32(42) + a == "42+a"
+ assert a + r_uint32(42) == "a+42"
+ assert r_uint32(42) - a == "42-a"
+ assert a - r_uint32(42) == "a-42"
+ assert r_uint32(42) * a == "42*a"
+ assert a * r_uint32(42) == "a*42"
+ assert r_uint32(42) / a == "42/a"
+ assert a / r_uint32(42) == "a/42"
+ assert r_uint32(42) // a == "42//a"
+ assert a // r_uint32(42) == "a//42"
+ assert r_uint32(42) % a == "42%a"
+ assert a % r_uint32(42) == "a%42"
+ py.test.raises(TypeError, "a << r_uint32(42)")
+ py.test.raises(TypeError, "r_uint32(42) << a")
+ py.test.raises(TypeError, "a >> r_uint32(42)")
+ py.test.raises(TypeError, "r_uint32(42) >> a")
+ assert r_uint32(42) & a == "42&a"
+ assert a & r_uint32(42) == "a&42"
+ assert r_uint32(42) | a == "42|a"
+ assert a | r_uint32(42) == "a|42"
+ assert r_uint32(42) ^ a == "42^a"
+ assert a ^ r_uint32(42) == "a^42"
+ assert r_uint32(42) ** a == "42**a"
+ assert a ** r_uint32(42) == "a**42"
More information about the pypy-commit
mailing list