Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r46240:cfe2dcf79e90 Date: 2011-08-03 10:35 +0200 http://bitbucket.org/pypy/pypy/changeset/cfe2dcf79e90/
Log: Fix. diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -339,16 +339,21 @@ start = 0 else: start = space.int_w(w_startstop) + if start < 0: + raise OperationError(space.w_ValueError, space.wrap( + "Indicies for islice() must be non-negative integers.")) w_stop = args_w[0] else: raise OperationError(space.w_TypeError, space.wrap("islice() takes at most 4 arguments (" + str(num_args) + " given)")) if space.is_w(w_stop, space.w_None): stop = -1 - stoppable = False else: stop = space.int_w(w_stop) - stoppable = True + if stop < 0: + raise OperationError(space.w_ValueError, space.wrap( + "Stop argument must be a non-negative integer or None.")) + stop = max(start, stop) # for obscure CPython compatibility if num_args == 2: w_step = args_w[1] @@ -356,38 +361,37 @@ step = 1 else: step = space.int_w(w_step) + if step < 1: + raise OperationError(space.w_ValueError, space.wrap( + "Step must be one or lager for islice().")) else: step = 1 - if start < 0: - raise OperationError(space.w_ValueError, space.wrap("Indicies for islice() must be non-negative integers.")) - if stoppable and stop < 0: - raise OperationError(space.w_ValueError, space.wrap("Stop argument must be a non-negative integer or None.")) - if step < 1: - raise OperationError(space.w_ValueError, space.wrap("Step must be one or lager for islice().")) - + self.ignore = step - 1 self.start = start self.stop = stop - self.step = step def iter_w(self): return self.space.wrap(self) def next_w(self): if self.start >= 0: # first call only - consume = self.start + 1 + ignore = self.start self.start = -1 else: # all following calls - consume = self.step - if consume > 1: - self._ignore_items(consume-1) - if self.stop >= 0: - if self.stop < consume: + ignore = self.ignore + stop = self.stop + if stop >= 0: + if stop <= ignore: self.stop = 0 # reset the state so that a following next_w() - self.step = 1 # has no effect any more + # has no effect any more + if stop > 0: + self._ignore_items(stop) raise OperationError(self.space.w_StopIteration, self.space.w_None) - self.stop -= consume + self.stop = stop - (ignore + 1) + if ignore > 0: + self._ignore_items(ignore) return self.space.next(self.iterable) def _ignore_items(self, num): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit