Author: stian
Branch: py3-bigint-to-int
Changeset: r96071:4e3d4c68bcde
Date: 2019-02-18 16:49 +0100
http://bitbucket.org/pypy/pypy/changeset/4e3d4c68bcde/

Log:    Reduce this to int_mod and int_and ops for now.

diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -234,23 +234,22 @@
     descr_gt = _make_descr_cmp('gt')
     descr_ge = _make_descr_cmp('ge')
 
-    def descr_sub(self, space, w_other):
-        if isinstance(w_other, W_IntObject):
-            res = self.num.int_sub(w_other.int_w(space))
-        elif not isinstance(w_other, W_AbstractLongObject):
-            return space.w_NotImplemented
-        res = self.num.sub(w_other.asbigint())
-        try:
-            return W_IntObject(res.toint())
-        except OverflowError:
-            return W_LongObject(res)
-    @delegate_other
-    def descr_rsub(self, space, w_other):
-        res = w_other.asbigint().sub(self.num)
-        try:
-            return W_IntObject(res.toint())
-        except OverflowError:
-            return W_LongObject(res)
+    def _make_generic_descr_binop_noncommutative(opname):
+        methname = opname + '_' if opname in ('and', 'or') else opname
+        descr_rname = 'descr_r' + opname
+        op = getattr(rbigint, methname)
+
+        @func_renamer('descr_' + opname)
+        @delegate_other
+        def descr_binop(self, space, w_other):
+            return W_LongObject(op(self.num, w_other.asbigint()))
+
+        @func_renamer(descr_rname)
+        @delegate_other
+        def descr_rbinop(self, space, w_other):
+            return W_LongObject(op(w_other.asbigint(), self.num))
+
+        return descr_binop, descr_rbinop
 
     def _make_generic_descr_binop(opname):
         if opname not in COMMUTATIVE_OPS:
@@ -264,49 +263,82 @@
         @func_renamer('descr_' + opname)
         def descr_binop(self, space, w_other):
             if isinstance(w_other, W_IntObject):
-                res = intop(self.num, w_other.int_w(space))
+                return W_LongObject(intop(self.num, w_other.int_w(space)))
             elif not isinstance(w_other, W_AbstractLongObject):
                 return space.w_NotImplemented
-            else:
-                res = op(self.num, w_other.asbigint())
-            try:
-                return W_IntObject(res.toint())
-            except OverflowError:
-                return W_LongObject(res)
+
+            return W_LongObject(op(self.num, w_other.asbigint()))
+
+        @func_renamer(descr_rname)
+        def descr_rbinop(self, space, w_other):
+            if isinstance(w_other, W_IntObject):
+                return W_LongObject(intop(self.num, w_other.int_w(space)))
+            elif not isinstance(w_other, W_AbstractLongObject):
+                return space.w_NotImplemented
+
+            return W_LongObject(op(w_other.asbigint(), self.num))
+
+        return descr_binop, descr_rbinop
+
+    def _make_generic_descr_binop_maybeint(opname):
+        if opname not in COMMUTATIVE_OPS:
+            raise Exception("Not supported")
+
+        methname = opname + '_' if opname in ('and', 'or') else opname
+        descr_rname = 'descr_r' + opname
+        op = getattr(rbigint, methname)
+        intop = getattr(rbigint, "int_" + methname)
+
+        @func_renamer('descr_' + opname)
+        def descr_binop(self, space, w_other):
+            if isinstance(w_other, W_IntObject):
+                res = intop(self.num, w_other.int_w(space))
+                try:
+                    return W_IntObject(res.toint())
+                except OverflowError:
+                    return W_LongObject(res)
+            elif not isinstance(w_other, W_AbstractLongObject):
+                return space.w_NotImplemented
+
+            return W_LongObject(op(self.num, w_other.asbigint()))
 
         @func_renamer(descr_rname)
         def descr_rbinop(self, space, w_other):
             if isinstance(w_other, W_IntObject):
                 res = intop(self.num, w_other.int_w(space))
+                try:
+                    return W_IntObject(res.toint())
+                except OverflowError:
+                    return W_LongObject(res)
             elif not isinstance(w_other, W_AbstractLongObject):
                 return space.w_NotImplemented
-            else:
-                res = op(w_other.asbigint(), self.num)
-            try:
-                return W_IntObject(res.toint())
-            except OverflowError:
-                return W_LongObject(res)
-                
+
+            return W_LongObject(op(w_other.asbigint(), self.num))
+
         return descr_binop, descr_rbinop
-
     descr_add, descr_radd = _make_generic_descr_binop('add')
-
+    descr_sub, descr_rsub = _make_generic_descr_binop_noncommutative('sub')
     descr_mul, descr_rmul = _make_generic_descr_binop('mul')
-    descr_and, descr_rand = _make_generic_descr_binop('and')
+    descr_and, descr_rand = _make_generic_descr_binop_maybeint('and')
     descr_or, descr_ror = _make_generic_descr_binop('or')
     descr_xor, descr_rxor = _make_generic_descr_binop('xor')
 
-    def _make_descr_binop(func, int_func):
+    def _make_descr_binop(func, int_func=None):
         opname = func.__name__[1:]
 
-        @func_renamer('descr_' + opname)
-        def descr_binop(self, space, w_other):
-            if isinstance(w_other, W_IntObject):
-                return int_func(self, space, w_other.int_w(space))
-            elif not isinstance(w_other, W_AbstractLongObject):
-                return space.w_NotImplemented
-            return func(self, space, w_other)
-
+        if int_func:
+            @func_renamer('descr_' + opname)
+            def descr_binop(self, space, w_other):
+                if isinstance(w_other, W_IntObject):
+                    return int_func(self, space, w_other.int_w(space))
+                elif not isinstance(w_other, W_AbstractLongObject):
+                    return space.w_NotImplemented
+                return func(self, space, w_other)
+        else:
+            @delegate_other
+            @func_renamer('descr_' + opname)
+            def descr_binop(self, space, w_other):
+                return func(self, space, w_other)
         @delegate_other
         @func_renamer('descr_r' + opname)
         def descr_rbinop(self, space, w_other):
@@ -324,20 +356,12 @@
             shift = w_other.asbigint().toint()
         except OverflowError:   # b too big
             raise oefmt(space.w_OverflowError, "shift count too large")
-        res = self.num.lshift(shift)
-        try:
-            return W_IntObject(res.toint())
-        except OverflowError:
-            return W_LongObject(res)
-            
-    def _int_lshift(self, space, other):
-        if other < 0:
+        return W_LongObject(self.num.lshift(shift))
+
+    def _int_lshift(self, space, w_other):
+        if w_other < 0:
             raise oefmt(space.w_ValueError, "negative shift count")
-        res = self.num.lshift(other)
-        try:
-            return W_IntObject(res.toint())
-        except OverflowError:
-            return W_LongObject(res)
+        return W_LongObject(self.num.lshift(w_other))
 
     descr_lshift, descr_rlshift = _make_descr_binop(_lshift, _int_lshift)
 
@@ -348,20 +372,13 @@
             shift = w_other.asbigint().toint()
         except OverflowError:   # b too big # XXX maybe just return 0L instead?
             raise oefmt(space.w_OverflowError, "shift count too large")
-        res = self.num.rshift(shift)
-        try:
-            return space.newint(res.toint())
-        except OverflowError:
-            return newlong(space, res)
+        return newlong(space, self.num.rshift(shift))
 
-    def _int_rshift(self, space, other):
-        if other < 0:
+    def _int_rshift(self, space, w_other):
+        if w_other < 0:
             raise oefmt(space.w_ValueError, "negative shift count")
-        res = self.num.rshift(other)
-        try:
-            return space.newint(res.toint())
-        except OverflowError:
-            return newlong(space, res)
+
+        return newlong(space, self.num.rshift(w_other))
     descr_rshift, descr_rrshift = _make_descr_binop(_rshift, _int_rshift)
 
     def _floordiv(self, space, w_other):
@@ -370,20 +387,16 @@
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
-                        
+        return newlong(space, z)
+
+    def _floordiv(self, space, w_other):
         try:
-            return space.newint(z.toint())
-        except OverflowError:
-            return newlong(space, z)
-
-    def _int_floordiv(self, space, other):
-        try:
-            z = self.num.int_floordiv(other)
+            z = self.num.floordiv(w_other.asbigint())
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "integer division or modulo by zero")
         return newlong(space, z)
-    descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv, 
_int_floordiv)
+    descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
 
     def _mod(self, space, w_other):
         try:
@@ -391,21 +404,17 @@
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "integer division or modulo by zero")
+        return newlong(space, z)
+
+    def _int_mod(self, space, w_other):
         try:
-            return space.newint(z.toint())
-        except OverflowError:
-            return newlong(space, z)
-
-    def _int_mod(self, space, other):
-        try:
-            z = self.num.int_mod(other)
+            z = self.num.int_mod(w_other)
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
-                        
-        # Int mod should always fit into an int.
+        #return newlong(space, z)
+        # Should always fit.
         return space.newint(z.toint())
-        #return newlong(space, z)
     descr_mod, descr_rmod = _make_descr_binop(_mod, _int_mod)
 
     def _divmod(self, space, w_other):
@@ -415,16 +424,7 @@
             raise oefmt(space.w_ZeroDivisionError,
                         "integer division or modulo by zero")
         return space.newtuple([newlong(space, div), newlong(space, mod)])
-
-    def _int_divmod(self, space, other):
-        try:
-            div, mod = self.num.int_divmod(other)
-        except ZeroDivisionError:
-            raise oefmt(space.w_ZeroDivisionError,
-                        "long division or modulo by zero")
-        return space.newtuple([newlong(space, div), newlong(space, mod)])
-
-    descr_divmod, descr_rdivmod = _make_descr_binop(_divmod, _int_divmod)
+    descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
 
 
 def _hash_long(space, v):
diff --git a/pypy/objspace/std/test/test_longobject.py 
b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -42,29 +42,24 @@
     def test_long_to_int(self):
         a = lobj.W_LongObject.fromlong(8)
         b = lobj.W_LongObject.fromlong(1)
+        c = iobj.W_IntObject(1)
+
+        modres = a.descr_mod(self.space, b)
+        assert type(modres) is lobj.W_LongObject
         
-        floordivres = a._floordiv(self.space, b)
-        assert type(floordivres) is iobj.W_IntObject
+        intmodres = a.descr_mod(self.space, c)
+        assert type(intmodres) is iobj.W_IntObject
         
-        modres = a._mod(self.space, b)
-        assert type(modres) is iobj.W_IntObject
+        andres = a.descr_and(self.space, b)
+        assert type(andres) is lobj.W_LongObject
         
-        # Covers all of descr_binop?
-        addres = a.descr_add(self.space, b)
-        assert type(addres) is iobj.W_IntObject
+        intandres = a.descr_and(self.space, c)
+        assert type(intandres) is iobj.W_IntObject
         
-        # Covers all of descr_rbinop?
-        raddres = a.descr_radd(self.space, b)
-        assert type(raddres) is iobj.W_IntObject
+        # Maybe in next round.
+        #intdivlongres = a.descr_rfloordiv(self.space, c)
+        #assert type(intdivlongres) is iobj.W_IntObject
         
-        subres = a.descr_sub(self.space, b)
-        assert type(subres) is iobj.W_IntObject
-        
-        lshiftres = a._lshift(self.space, b)
-        assert type(lshiftres) is iobj.W_IntObject
-        
-        rshiftres = a._rshift(self.space, b)
-        assert type(rshiftres) is iobj.W_IntObject
 class AppTestLong:
 
     def w__long(self, obj):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to