Author: Philip Jenvey <pjen...@underboss.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit