Author: Philip Jenvey <[email protected]>
Branch: stdlib-2.7.4
Changeset: r64953:de804d0c19b6
Date: 2013-06-20 17:01 -0700
http://bitbucket.org/pypy/pypy/changeset/de804d0c19b6/
Log: cpython issues #16029/16030: Fix pickling and repr of large xranges
diff --git a/pypy/module/__builtin__/functional.py
b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -2,6 +2,7 @@
Interp-level definition of frequently used functionals.
"""
+import sys
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError
@@ -367,13 +368,12 @@
return space.wrap(obj)
def descr_repr(self):
- stop = self.start + self.len * self.step
if self.start == 0 and self.step == 1:
- s = "xrange(%d)" % (stop,)
+ s = "xrange(%d)" % (self._get_stop(),)
elif self.step == 1:
- s = "xrange(%d, %d)" % (self.start, stop)
+ s = "xrange(%d, %d)" % (self.start, self._get_stop())
else:
- s = "xrange(%d, %d, %d)" %(self.start, stop, self.step)
+ s = "xrange(%d, %d, %d)" %(self.start, self._get_stop(), self.step)
return self.space.wrap(s)
def descr_len(self):
@@ -402,19 +402,29 @@
self.len, self.step))
def descr_reversed(self):
- lastitem = self.start + (self.len-1) * self.step
- return self.space.wrap(W_XRangeIterator(self.space, lastitem,
- self.len, -self.step))
+ last = self.start + (self.len - 1) * self.step
+ return self.space.wrap(W_XRangeIterator(self.space, last, self.len,
+ -self.step))
def descr_reduce(self):
space = self.space
return space.newtuple(
[space.type(self),
space.newtuple([space.wrap(self.start),
- space.wrap(self.start + self.len * self.step),
+ space.wrap(self._get_stop()),
space.wrap(self.step)])
])
+ def _get_stop(self):
+ if not self.len:
+ return self.start
+ step = self.step
+ last = self.start + (self.len - 1) * step
+ if step > 0:
+ return sys.maxint if last > sys.maxint - step else last + step
+ minint = -sys.maxint - 1
+ return minint if last < minint - step else last + step
+
def _toint(space, w_obj):
# this also supports float arguments. CPython still does, too.
# needs a bit more thinking in general...
diff --git a/pypy/module/__builtin__/test/test_functional.py
b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -188,6 +188,22 @@
x = xrange(1)
assert type(reversed(x)) == type(iter(x))
+ def test_cpython_issue16029(self):
+ import sys
+ M = min(sys.maxint, sys.maxsize)
+ x = xrange(0, M, M - 1)
+ assert x.__reduce__() == (xrange, (0, M, M - 1))
+ x = xrange(0, -M, 1 - M)
+ assert x.__reduce__() == (xrange, (0, -M - 1, 1 - M))
+
+ def test_cpython_issue16030(self):
+ import sys
+ M = min(sys.maxint, sys.maxsize)
+ x = xrange(0, M, M - 1)
+ assert repr(x) == 'xrange(0, %s, %s)' % (M, M - 1)
+ x = xrange(0, -M, 1 - M)
+ assert repr(x) == 'xrange(0, %s, %s)' % (-M - 1, 1 - M)
+
class AppTestReversed:
def test_reversed(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit