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