[pypy-commit] pypy py3.3: Improve pickling of "reversed" and "enumerate" objects.

amauryfa noreply at buildbot.pypy.org
Thu Jan 8 22:21:24 CET 2015


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r75257:4c0fc2915173
Date: 2015-01-08 17:27 +0100
http://bitbucket.org/pypy/pypy/changeset/4c0fc2915173/

Log:	Improve pickling of "reversed" and "enumerate" objects. In addition,
	reversed is now a type.

diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -70,7 +70,7 @@
         'zip'           : 'functional.W_Zip',
         'min'           : 'functional.min',
         'max'           : 'functional.max',
-        'reversed'      : 'functional.reversed',
+        'reversed'      : 'functional.W_ReversedIterator',
         'super'         : 'descriptor.W_Super',
         'staticmethod'  : 'descriptor.StaticMethod',
         'classmethod'   : 'descriptor.ClassMethod',
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
@@ -203,6 +203,7 @@
         self.w_iter = w_iter
         self.w_index = w_start
 
+    @staticmethod
     def descr___new__(space, w_subtype, w_iterable, w_start=None):
         self = space.allocate_instance(W_Enumerate, w_subtype)
         if w_start is None:
@@ -222,35 +223,20 @@
         return space.newtuple([w_index, w_item])
 
     def descr___reduce__(self, space):
-        from pypy.interpreter.mixedmodule import MixedModule
-        w_mod    = space.getbuiltinmodule('_pickle_support')
-        mod      = space.interp_w(MixedModule, w_mod)
-        w_new_inst = mod.get('enumerate_new')
-        w_info = space.newtuple([self.w_iter, self.w_index])
-        return space.newtuple([w_new_inst, w_info])
-
-# exported through _pickle_support
-def _make_enumerate(space, w_iter, w_index):
-    return space.wrap(W_Enumerate(w_iter, w_index))
+        return space.newtuple([space.type(self),
+                               space.newtuple([self.w_iter, self.w_index])])
 
 W_Enumerate.typedef = TypeDef("enumerate",
-    __new__=interp2app(W_Enumerate.descr___new__.im_func),
+    __new__=interp2app(W_Enumerate.descr___new__),
     __iter__=interp2app(W_Enumerate.descr___iter__),
     __next__=interp2app(W_Enumerate.descr_next),
     __reduce__=interp2app(W_Enumerate.descr___reduce__),
 )
 
 
-def reversed(space, w_sequence):
-    """Return a iterator that yields items of sequence in reverse."""
-    w_reversed_descr = space.lookup(w_sequence, "__reversed__")
-    if w_reversed_descr is not None:
-        w_reversed = space.get(w_reversed_descr, w_sequence)
-        return space.call_function(w_reversed)
-    return space.wrap(W_ReversedIterator(space, w_sequence))
+class W_ReversedIterator(W_Root):
+    """reverse iterator over values of the sequence."""
 
-
-class W_ReversedIterator(W_Root):
     def __init__(self, space, w_sequence):
         self.remaining = space.len_w(w_sequence) - 1
         if space.lookup(w_sequence, "__getitem__") is None:
@@ -258,6 +244,16 @@
             raise OperationError(space.w_TypeError, space.wrap(msg))
         self.w_sequence = w_sequence
 
+    @staticmethod
+    def descr___new__(space, w_subtype, w_sequence):
+        w_reversed_descr = space.lookup(w_sequence, "__reversed__")
+        if w_reversed_descr is not None:
+            w_reversed = space.get(w_reversed_descr, w_sequence)
+            return space.call_function(w_reversed)
+        self = space.allocate_instance(W_ReversedIterator, w_subtype)
+        self.__init__(space, w_sequence)
+        return space.wrap(self)
+
     def descr___iter__(self, space):
         return space.wrap(self)
 
@@ -281,30 +277,33 @@
         raise OperationError(space.w_StopIteration, space.w_None)
 
     def descr___reduce__(self, space):
-        from pypy.interpreter.mixedmodule import MixedModule
-        w_mod    = space.getbuiltinmodule('_pickle_support')
-        mod      = space.interp_w(MixedModule, w_mod)
-        w_new_inst = mod.get('reversed_new')
-        info_w = [self.w_sequence, space.wrap(self.remaining)]
-        w_info = space.newtuple(info_w)
-        return space.newtuple([w_new_inst, w_info])
+        if self.w_sequence:
+            w_state = space.wrap(self.remaining)
+            return space.newtuple([
+                space.type(self),
+                space.newtuple([self.w_sequence]),
+                w_state])
+        else:
+            return space.newtuple([
+                space.type(self),
+                space.newtuple([])])
+
+    def descr___setstate__(self, space, w_state):
+        self.remaining = space.int_w(wstate)
+        n = space.len_w(self.w_sequence)
+        if self.remaining < -1:
+            self.remaining = -1
+        elif self.remaining > n - 1:
+            self.remaining = n - 1
 
 W_ReversedIterator.typedef = TypeDef("reversed",
+    __new__         = interp2app(W_ReversedIterator.descr___new__),
     __iter__        = interp2app(W_ReversedIterator.descr___iter__),
     __length_hint__ = interp2app(W_ReversedIterator.descr_length),
     __next__        = interp2app(W_ReversedIterator.descr_next),
     __reduce__      = interp2app(W_ReversedIterator.descr___reduce__),
+    __setstate__      = interp2app(W_ReversedIterator.descr___setstate__),
 )
-W_ReversedIterator.typedef.acceptable_as_base_class = False
-
-# exported through _pickle_support
-def _make_reversed(space, w_seq, w_remaining):
-    w_type = space.gettypeobject(W_ReversedIterator.typedef)
-    iterator = space.allocate_instance(W_ReversedIterator, w_type)
-    iterator.w_sequence = w_seq
-    iterator.remaining = space.int_w(w_remaining)
-    return space.wrap(iterator)
-
 
 
 class W_Range(W_Root):
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
@@ -510,6 +510,7 @@
 
 class AppTestReversed:
     def test_reversed(self):
+        assert isinstance(reversed, type)
         r = reversed("hello")
         assert iter(r) is r
         assert r.__next__() == "o"
diff --git a/pypy/module/_pickle_support/__init__.py b/pypy/module/_pickle_support/__init__.py
--- a/pypy/module/_pickle_support/__init__.py
+++ b/pypy/module/_pickle_support/__init__.py
@@ -23,7 +23,5 @@
         'intrangeiter_new': 'maker.intrangeiter_new',
         'builtin_code': 'maker.builtin_code',
         'builtin_function' : 'maker.builtin_function',
-        'enumerate_new': 'maker.enumerate_new',
-        'reversed_new': 'maker.reversed_new',
         'operationerror_new': 'maker.operationerror_new',
     }
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
@@ -98,15 +98,6 @@
                                         identifier))
 
 
-def enumerate_new(space, w_iter, w_index):
-    from pypy.module.__builtin__.functional import _make_enumerate
-    return _make_enumerate(space, w_iter, w_index)
-
-def reversed_new(space, w_seq, w_remaining):
-    from pypy.module.__builtin__.functional import _make_reversed
-    return _make_reversed(space, w_seq, w_remaining)
-
-
 # ___________________________________________________________________
 # Helper functions for internal use
 


More information about the pypy-commit mailing list