[pypy-commit] pypy py3.5: iterobject.py:
arigo
pypy.commits at gmail.com
Fri Oct 14 10:27:44 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r87792:867628382da5
Date: 2016-10-14 16:27 +0200
http://bitbucket.org/pypy/pypy/changeset/867628382da5/
Log: iterobject.py:
* go systematically with self.w_seq = (w_iterable or None), never
space.w_None.
* follow more exactly what CPython 3.5 does in reduce/setstate
diff --git a/pypy/module/_pickle_support/maker.py b/pypy/module/_pickle_support/maker.py
--- a/pypy/module/_pickle_support/maker.py
+++ b/pypy/module/_pickle_support/maker.py
@@ -42,19 +42,6 @@
# simply create an iterator and that's it.
return space.iter(w_lis)
-def seqiter_new(space, w_seq, w_index):
- return W_SeqIterObject(w_seq, space.int_w(w_index))
-
-def reverseseqiter_new(space, w_seq, w_index):
- w_rev = instantiate(W_ReverseSeqIterObject)
- if space.is_w(w_seq, space.w_None):
- w_rev.w_seq = space.w_None
- w_rev.index = -1
- else:
- w_rev.w_seq = w_seq
- w_rev.index = space.int_w(w_index)
- return w_rev
-
def frame_new(space):
new_frame = instantiate(space.FrameClass) # XXX fish
return space.wrap(new_frame)
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -14,7 +14,7 @@
self.index = index
def getlength(self, space):
- if space.is_none(self.w_seq):
+ if self.w_seq is None:
return space.wrap(0)
index = self.index
w_length = space.len(self.w_seq)
@@ -30,17 +30,16 @@
raise NotImplementedError
def descr_reduce(self, space):
- from pypy.interpreter.mixedmodule import MixedModule
- w_mod = space.getbuiltinmodule('_pickle_support')
- mod = space.interp_w(MixedModule, w_mod)
- new_inst = mod.get('seqiter_new')
- tup = [self.w_seq, space.wrap(self.index)]
- # note that setstate is not called, because this setup already sets the index
- return space.newtuple([new_inst, space.newtuple(tup)])
+ w_seq = self.w_seq
+ if w_seq is None:
+ return _empty_iterable(space)
+ w_callable = space.builtin.get('iter')
+ items = [w_callable, space.newtuple([w_seq]), space.wrap(self.index)]
+ return space.newtuple(items)
def descr_setstate(self, space, w_state):
index = space.int_w(w_state)
- if self.w_seq is not space.w_None:
+ if self.w_seq is not None:
if index < 0:
index = 0
self.index = index
@@ -69,7 +68,7 @@
"""Sequence iterator implementation for general sequences."""
def descr_next(self, space):
- if space.is_none(self.w_seq):
+ if self.w_seq is None:
raise OperationError(space.w_StopIteration, space.w_None)
try:
w_item = space.getitem(self.w_seq, space.wrap(self.index))
@@ -88,7 +87,7 @@
def descr_next(self, space):
from pypy.objspace.std.listobject import W_ListObject
w_seq = self.w_seq
- if space.is_none(w_seq):
+ if w_seq is None:
raise OperationError(space.w_StopIteration, space.w_None)
assert isinstance(w_seq, W_ListObject)
index = self.index
@@ -150,24 +149,20 @@
class W_ReverseSeqIterObject(W_Root):
def __init__(self, space, w_seq, index=-1):
- # w_seq is normally a list object, but can be space.w_None after
- # the iterator is exhausted or after a reduce(). In that case,
- # self.index == -1.
self.w_seq = w_seq
self.index = space.len_w(w_seq) + index
def descr_reduce(self, space):
- from pypy.interpreter.mixedmodule import MixedModule
- w_mod = space.getbuiltinmodule('_pickle_support')
- mod = space.interp_w(MixedModule, w_mod)
- new_inst = mod.get('reverseseqiter_new')
- tup = [self.w_seq, space.wrap(self.index)]
- # note that setstate is not called, because this setup already sets the index
- return space.newtuple([new_inst, space.newtuple(tup)])
+ w_seq = self.w_seq
+ if w_seq is None:
+ return _empty_iterable(space)
+ w_callable = space.builtin.get('reversed')
+ items = [w_callable, space.newtuple([w_seq]), space.wrap(self.index)]
+ return space.newtuple(items)
def descr_setstate(self, space, w_state):
index = space.int_w(w_state)
- if self.w_seq is not space.w_None:
+ if self.w_seq is not None:
length = space.int_w(space.len(self.w_seq))
if index < 0: index = 0
if index >= length: index = length-1
@@ -175,7 +170,7 @@
def descr_length_hint(self, space):
length = self.index + 1
- if self.w_seq is space.w_None or space.len_w(self.w_seq) < length:
+ if self.w_seq is None or space.len_w(self.w_seq) < length:
length = 0
return space.wrap(length)
@@ -200,7 +195,7 @@
# Done
self.index = -1
- self.w_seq = space.w_None
+ self.w_seq = None
raise OperationError(space.w_StopIteration, space.w_None)
W_ReverseSeqIterObject.typedef = TypeDef(
@@ -212,3 +207,8 @@
__length_hint__ = interp2app(W_ReverseSeqIterObject.descr_length_hint),
)
W_ReverseSeqIterObject.typedef.acceptable_as_base_class = False
+
+
+def _empty_iterable(space):
+ w_callable = space.builtin.get('iter')
+ return space.newtuple([w_callable, space.newtuple([space.newtuple([])])])
diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py
--- a/pypy/objspace/std/test/test_iterobject.py
+++ b/pypy/objspace/std/test/test_iterobject.py
@@ -83,6 +83,36 @@
iterable.__setstate__(3)
assert next(iterable) == 4
+ def test_forward_iter_reduce(self):
+ T = "abc"
+ iterable = iter(T)
+ assert iterable.__reduce__() == (iter, (T, ), 0)
+ assert next(iterable) == "a"
+ assert iterable.__reduce__() == (iter, (T, ), 1)
+ assert next(iterable) == "b"
+ assert iterable.__reduce__() == (iter, (T, ), 2)
+ assert next(iterable) == "c"
+ assert iterable.__reduce__() == (iter, (T, ), 3)
+ raises(StopIteration, next, iterable)
+ assert (iterable.__reduce__() == (iter, ((), )) or # pypy
+ iterable.__reduce__() == (iter, ("", ))) # cpython
+
+ def test_reversed_iter_reduce(self):
+ T = [1, 2, 3, 4]
+ iterable = reversed(T)
+ assert iterable.__reduce__() == (reversed, (T, ), 3)
+ assert next(iterable) == 4
+ assert iterable.__reduce__() == (reversed, (T, ), 2)
+ assert next(iterable) == 3
+ assert iterable.__reduce__() == (reversed, (T, ), 1)
+ assert next(iterable) == 2
+ assert iterable.__reduce__() == (reversed, (T, ), 0)
+ assert next(iterable) == 1
+ assert iterable.__reduce__() == (reversed, (T, ), -1)
+ raises(StopIteration, next, iterable)
+ assert (iterable.__reduce__() == (iter, ((), )) or # pypy
+ iterable.__reduce__() == (iter, ([], ))) # cpython
+
def test_no_len_on_tuple_iter(self):
iterable = (1,2,3,4)
raises(TypeError, len, iter(iterable))
@@ -126,7 +156,7 @@
def test_reversed_frees_empty(self):
import gc
- for typ in list, unicode:
+ for typ in list, str:
free = [False]
class U(typ):
def __del__(self):
@@ -138,7 +168,7 @@
def test_reversed_mutation(self):
n = 10
- d = range(n)
+ d = list(range(n))
it = reversed(d)
next(it)
next(it)
@@ -148,7 +178,7 @@
d[1:] = []
assert it.__length_hint__() == 0
assert list(it) == []
- d.extend(xrange(20))
+ d.extend(range(20))
assert it.__length_hint__() == 0
def test_no_len_on_set_iter(self):
More information about the pypy-commit
mailing list