[pypy-commit] pypy py3-bigint-to-int: Code and test for most ops

stian pypy.commits at gmail.com
Mon Feb 18 09:09:37 EST 2019


Author: stian
Branch: py3-bigint-to-int
Changeset: r96056:517a32bab8f7
Date: 2019-02-18 15:08 +0100
http://bitbucket.org/pypy/pypy/changeset/517a32bab8f7/

Log:	Code and test for most ops

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
@@ -236,11 +236,14 @@
 
     def descr_sub(self, space, w_other):
         if isinstance(w_other, W_IntObject):
-            return W_LongObject(self.num.int_sub(w_other.int_w(space)))
+            res = self.num.int_sub(w_other.int_w(space))
         elif not isinstance(w_other, W_AbstractLongObject):
             return space.w_NotImplemented
-        return W_LongObject(self.num.sub(w_other.asbigint()))
-
+        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):
         return W_LongObject(w_other.asbigint().sub(self.num))
@@ -257,21 +260,29 @@
         @func_renamer('descr_' + opname)
         def descr_binop(self, space, w_other):
             if isinstance(w_other, W_IntObject):
-                return W_LongObject(intop(self.num, w_other.int_w(space)))
+                res = intop(self.num, w_other.int_w(space))
             elif not isinstance(w_other, W_AbstractLongObject):
                 return space.w_NotImplemented
-
-            return W_LongObject(op(self.num, w_other.asbigint()))
+            else:
+                res = op(self.num, w_other.asbigint())
+            try:
+                return W_IntObject(res.toint())
+            except OverflowError:
+                return W_LongObject(res)
 
         @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)))
+                res = 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))
-
+            else:
+                res = op(w_other.asbigint(), self.num)
+            try:
+                return W_IntObject(res.toint())
+            except OverflowError:
+                return W_LongObject(res)
+                
         return descr_binop, descr_rbinop
 
     descr_add, descr_radd = _make_generic_descr_binop('add')
@@ -340,7 +351,11 @@
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
-        return newlong(space, z)
+                        
+        try:
+            return space.newint(z.toint())
+        except OverflowError:
+            return newlong(space, z)
 
     def _int_floordiv(self, space, other):
         try:
@@ -357,7 +372,10 @@
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "integer division or modulo by zero")
-        return newlong(space, z)
+        try:
+            return space.newint(z.toint())
+        except OverflowError:
+            return newlong(space, z)
 
     def _int_mod(self, space, other):
         try:
@@ -365,7 +383,10 @@
         except ZeroDivisionError:
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
-        return newlong(space, z)
+                        
+        # Int mod should always fit into an int.
+        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):
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
@@ -1,6 +1,7 @@
 # -*- encoding: utf-8 -*-
 import py
 from pypy.objspace.std import longobject as lobj
+from pypy.objspace.std import intobject as iobj
 from rpython.rlib.rbigint import rbigint
 
 class TestW_LongObject:
@@ -38,7 +39,21 @@
                 w_obj = space.newlong_from_rarith_int(r(x))
                 assert space.bigint_w(w_obj).eq(rbigint.fromlong(x))
 
-
+    def test_long_to_int(self):
+        a = lobj.W_LongObject.fromlong(8)
+        b = lobj.W_LongObject.fromlong(1)
+        
+        floordivres = a._floordiv(self.space, b)
+        assert type(floordivres) is iobj.W_IntObject
+        
+        modres = a._mod(self.space, b)
+        assert type(modres) is iobj.W_IntObject
+        
+        addres = a.descr_add(self.space, b)
+        assert type(addres) is iobj.W_IntObject
+        
+        subres = a.descr_sub(self.space, b)
+        assert type(subres) is iobj.W_IntObject
 class AppTestLong:
 
     def w__long(self, obj):


More information about the pypy-commit mailing list