Author: Philip Jenvey <pjen...@underboss.org>
Branch: stdlib-2.7.12
Changeset: r87524:a2d8b4680ef9
Date: 2016-10-02 12:15 -0700
http://bitbucket.org/pypy/pypy/changeset/a2d8b4680ef9/

Log:    pass thru numeric subclasses returned from __int/long/trunc__

diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -393,9 +393,7 @@
         return space.newtuple([self, w_other])
 
     def descr_long(self, space):
-        # XXX: should try smalllong
-        from pypy.objspace.std.longobject import W_LongObject
-        return W_LongObject.fromint(space, self.intval)
+        return space.newlong(self.intval)
 
     def descr_nonzero(self, space):
         return space.newbool(self.intval != 0)
@@ -684,7 +682,11 @@
             w_obj = w_value
             if space.lookup(w_obj, '__int__') is None:
                 w_obj = space.trunc(w_obj)
-            w_obj = space.int(w_obj)
+                if not (space.isinstance_w(w_obj, space.w_int) or
+                        space.isinstance_w(w_obj, space.w_long)):
+                    w_obj = space.int(w_obj)
+            else:
+                w_obj = space.int(w_obj)
             # 'int(x)' should return what x.__int__() returned, which should
             # be an int or long or a subclass thereof.
             if space.is_w(w_inttype, space.w_int):
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
@@ -564,9 +564,15 @@
         elif (space.lookup(w_value, '__long__') is not None or
               space.lookup(w_value, '__int__') is not None):
             w_obj = space.long(w_value)
+            if (space.is_w(w_longtype, space.w_long) and
+                space.isinstance_w(w_obj, space.w_long)):
+                return w_obj
             return newbigint(space, w_longtype, space.bigint_w(w_obj))
         elif space.lookup(w_value, '__trunc__') is not None:
             w_obj = space.trunc(w_value)
+            if (space.is_w(w_longtype, space.w_long) and
+                space.isinstance_w(w_obj, space.w_long)):
+                return w_obj
             # :-(  blame CPython 2.7
             if space.lookup(w_obj, '__long__') is not None:
                 w_obj = space.long(w_obj)
diff --git a/pypy/objspace/std/test/test_intobject.py 
b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -501,6 +501,14 @@
                 return Integral()
         assert int(TruncReturnsNonInt()) == 42
 
+    def test_trunc_returns_int_subclass(self):
+        class TruncReturnsNonInt(object):
+            def __trunc__(self):
+                return True
+        n = int(TruncReturnsNonInt())
+        assert n == 1
+        assert type(n) is bool
+
     def test_int_before_string(self):
         class Integral(str):
             def __int__(self):
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
@@ -285,6 +285,17 @@
             def __int__(self):
                 return 42
         raises(TypeError, long, B())
+
+        class LongSubclass(long):
+            pass
+        class ReturnsLongSubclass(object):
+            def __long__(self):
+                return LongSubclass(42L)
+        n = long(ReturnsLongSubclass())
+        assert n == 42
+        assert type(n) is LongSubclass
+
+    def test_trunc_returns(self):
         # but!: (blame CPython 2.7)
         class Integral(object):
             def __int__(self):
@@ -292,7 +303,18 @@
         class TruncReturnsNonLong(object):
             def __trunc__(self):
                 return Integral()
-        assert long(TruncReturnsNonLong()) == 42
+        n = long(TruncReturnsNonLong())
+        assert type(n) is long
+        assert n == 42
+
+        class LongSubclass(long):
+            pass
+        class TruncReturnsNonInt(object):
+            def __trunc__(self):
+                return LongSubclass(42)
+        n = long(TruncReturnsNonInt())
+        assert n == 42
+        assert type(n) is LongSubclass
 
     def test_long_before_string(self):
         class A(str):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to