[pypy-commit] pypy stdlib-2.7.12: pass thru numeric subclasses returned from __int/long/trunc__
pjenvey
pypy.commits at gmail.com
Sun Oct 2 15:24:44 EDT 2016
Author: Philip Jenvey <pjenvey at 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):
More information about the pypy-commit
mailing list