[pypy-commit] pypy py3.5: redo the commit made for setstate, though it is not called by pickling (state is already set by load_reduce), this makes the api more compliant (we could of course invoke load_build now, but there is no point in doing so)

plan_rich pypy.commits at gmail.com
Mon Oct 10 04:12:51 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5
Changeset: r87686:05ed492ccc60
Date: 2016-10-10 10:07 +0200
http://bitbucket.org/pypy/pypy/changeset/05ed492ccc60/

Log:	redo the commit made for setstate, though it is not called by
	pickling (state is already set by load_reduce), this makes the api
	more compliant (we could of course invoke load_build now, but there
	is no point in doing so)

diff --git a/lib-python/3/test/test_iter.py b/lib-python/3/test/test_iter.py
--- a/lib-python/3/test/test_iter.py
+++ b/lib-python/3/test/test_iter.py
@@ -938,7 +938,6 @@
         with self.assertRaises(OverflowError):
             next(it)
 
-    @cpython_only
     def test_iter_neg_setstate(self):
         it = iter(UnlimitedSequenceClass())
         it.__setstate__(-42)
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
@@ -35,8 +35,16 @@
         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)])
 
+    def descr_setstate(self, space, w_state):
+        index = space.int_w(w_state)
+        if self.w_seq is not space.w_None:
+            if index < 0:
+                index = 0
+            self.index = index
+
     def descr_length_hint(self, space):
         return self.getlength(space)
 
@@ -52,6 +60,7 @@
     __next__ = interpindirect2app(W_AbstractSeqIterObject.descr_next),
     __reduce__ = interp2app(W_AbstractSeqIterObject.descr_reduce),
     __length_hint__ = interp2app(W_AbstractSeqIterObject.descr_length_hint),
+    __setstate__ = interp2app(W_AbstractSeqIterObject.descr_setstate),
 )
 W_AbstractSeqIterObject.typedef.acceptable_as_base_class = False
 
@@ -151,8 +160,17 @@
         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)])
 
+    def descr_setstate(self, space, w_state):
+        index = space.int_w(w_state)
+        if self.w_seq is not space.w_None:
+            length = space.int_w(space.len(self.w_seq))
+            if index < 0: index = 0
+            if index >= length: index = length-1
+            self.index = index
+
     def descr_length_hint(self, space):
         if space.is_none(self.w_seq):
             return space.wrap(0)
@@ -189,6 +207,7 @@
     __iter__ = interp2app(W_ReverseSeqIterObject.descr_iter),
     __next__ = interp2app(W_ReverseSeqIterObject.descr_next),
     __reduce__ = interp2app(W_ReverseSeqIterObject.descr_reduce),
+    __setstate__ = interp2app(W_ReverseSeqIterObject.descr_setstate),
     __length_hint__ = interp2app(W_ReverseSeqIterObject.descr_length_hint),
 )
 W_ReverseSeqIterObject.typedef.acceptable_as_base_class = False
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
@@ -72,6 +72,16 @@
         assert next(iterable) == 1
         raises(TypeError, iterable.__setstate__, '0')
 
+    def test_reversed_iter_setstate(self):
+        iterable = reversed([1,2,3,4])
+        assert next(iterable) == 4
+        iterable.__setstate__(0)
+        assert next(iterable) == 1
+        iterable.__setstate__(2)
+        next(iterable); next(iterable)
+        assert next(iterable) == 1
+        iterable.__setstate__(3)
+        assert next(iterable) == 4
 
     def test_no_len_on_tuple_iter(self):
         iterable = (1,2,3,4)


More information about the pypy-commit mailing list