[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