Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r89021:e47c8f353a9e
Date: 2016-12-12 14:54 +0100
http://bitbucket.org/pypy/pypy/changeset/e47c8f353a9e/
Log: fix pickling deque_iterator and deque_reverse_iterator
diff --git a/pypy/module/_collections/interp_deque.py
b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -610,6 +610,14 @@
self.lock = deque.getlock()
check_nonneg(self.index)
+ def _move_to(self, index):
+ if index < 0:
+ return
+ self.counter = self.deque.len - index
+ if self.counter <= 0:
+ return
+ self.block, self.index = self.deque.locate(index)
+
def iter(self):
return self.space.wrap(self)
@@ -621,7 +629,7 @@
if self.lock is not self.deque.lock:
self.counter = 0
raise oefmt(space.w_RuntimeError, "deque mutated during iteration")
- if self.counter == 0:
+ if self.counter <= 0:
raise OperationError(space.w_StopIteration, space.w_None)
self.counter -= 1
ri = self.index
@@ -634,15 +642,19 @@
return w_x
def reduce(self):
+ w_i = self.space.wrap(self.deque.len - self.counter)
return self.space.newtuple([self.space.gettypefor(W_DequeIter),
- self.space.newtuple([self.deque])])
+ self.space.newtuple([self.deque, w_i])])
-def W_DequeIter__new__(space, w_subtype, w_deque):
+@unwrap_spec(index=int)
+def W_DequeIter__new__(space, w_subtype, w_deque, index=0):
w_self = space.allocate_instance(W_DequeIter, w_subtype)
if not isinstance(w_deque, W_Deque):
raise oefmt(space.w_TypeError, "must be collections.deque, not %T",
w_deque)
- W_DequeIter.__init__(space.interp_w(W_DequeIter, w_self), w_deque)
+ self = space.interp_w(W_DequeIter, w_self)
+ W_DequeIter.__init__(self, w_deque)
+ self._move_to(index)
return w_self
W_DequeIter.typedef = TypeDef("_collections.deque_iterator",
@@ -666,6 +678,14 @@
self.lock = deque.getlock()
check_nonneg(self.index)
+ def _move_to(self, index):
+ if index < 0:
+ return
+ self.counter = self.deque.len - index
+ if self.counter <= 0:
+ return
+ self.block, self.index = self.deque.locate(self.counter - 1)
+
def iter(self):
return self.space.wrap(self)
@@ -677,7 +697,7 @@
if self.lock is not self.deque.lock:
self.counter = 0
raise oefmt(space.w_RuntimeError, "deque mutated during iteration")
- if self.counter == 0:
+ if self.counter <= 0:
raise OperationError(space.w_StopIteration, space.w_None)
self.counter -= 1
ri = self.index
@@ -690,15 +710,19 @@
return w_x
def reduce(self):
+ w_i = self.space.wrap(self.deque.len - self.counter)
return self.space.newtuple([self.space.gettypefor(W_DequeRevIter),
- self.space.newtuple([self.deque])])
+ self.space.newtuple([self.deque, w_i])])
-def W_DequeRevIter__new__(space, w_subtype, w_deque):
+@unwrap_spec(index=int)
+def W_DequeRevIter__new__(space, w_subtype, w_deque, index=0):
w_self = space.allocate_instance(W_DequeRevIter, w_subtype)
if not isinstance(w_deque, W_Deque):
raise oefmt(space.w_TypeError, "must be collections.deque, not %T",
w_deque)
- W_DequeRevIter.__init__(space.interp_w(W_DequeRevIter, w_self), w_deque)
+ self = space.interp_w(W_DequeRevIter, w_self)
+ W_DequeRevIter.__init__(self, w_deque)
+ self._move_to(index)
return w_self
W_DequeRevIter.typedef = TypeDef("_collections.deque_reverse_iterator",
diff --git a/pypy/module/_collections/test/test_deque.py
b/pypy/module/_collections/test/test_deque.py
--- a/pypy/module/_collections/test/test_deque.py
+++ b/pypy/module/_collections/test/test_deque.py
@@ -331,18 +331,28 @@
def test_DequeIter_pickle(self):
from _collections import deque
import pickle
- d = deque([1,2,3])
- iterator = iter(d)
- copy = pickle.loads(pickle.dumps(iterator))
- assert list(iterator) == list(copy)
+ for i in range(4):
+ d = deque([1,2,3])
+ iterator = iter(d)
+ assert iterator.__reduce__() == (type(iterator), (d, 0))
+ for j in range(i):
+ next(iterator)
+ assert iterator.__reduce__() == (type(iterator), (d, i))
+ copy = pickle.loads(pickle.dumps(iterator))
+ assert list(iterator) == list(copy)
def test_DequeRevIter_pickle(self):
from _collections import deque
import pickle
- d = deque([1,2,3])
- iterator = reversed(d)
- copy = pickle.loads(pickle.dumps(iterator))
- assert list(iterator) == list(copy)
+ for i in range(4):
+ d = deque([1,2,3])
+ iterator = reversed(d)
+ assert iterator.__reduce__() == (type(iterator), (d, 0))
+ for j in range(i):
+ assert next(iterator)
+ assert iterator.__reduce__() == (type(iterator), (d, i))
+ copy = pickle.loads(pickle.dumps(iterator))
+ assert list(iterator) == list(copy)
def test_deque_mul(self):
from _collections import deque
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit