[pypy-svn] r27518 - in pypy/dist/pypy: interpreter/test module/_pickle_support objspace/std

tismer at codespeak.net tismer at codespeak.net
Sat May 20 21:48:09 CEST 2006


Author: tismer
Date: Sat May 20 21:48:07 2006
New Revision: 27518

Modified:
   pypy/dist/pypy/interpreter/test/test_pickle.py
   pypy/dist/pypy/module/_pickle_support/__init__.py
   pypy/dist/pypy/module/_pickle_support/maker.py
   pypy/dist/pypy/objspace/std/dicttype.py
Log:
implemented pickling of dict iterators. This is in fact a bit hairy since dicts are hairy. We use the same simple approach that Stackless did: pickke a list and build it's iter()

Modified: pypy/dist/pypy/interpreter/test/test_pickle.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_pickle.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_pickle.py	Sat May 20 21:48:07 2006
@@ -190,12 +190,14 @@
         assert liter == result
     
     def test_pickle_dictiter(self):
-        skip("work in progress")
         import pickle
-        diter  = iter({})
+        tdict = {'2':2, '3':3, '5':5}
+        diter  = iter(tdict)
+        diter.next()
         pckl   = pickle.dumps(diter)
         result = pickle.loads(pckl)
-        assert diter == result
+        assert len(diter) == 2
+        assert list(diter) == list(result)
     
     def test_pickle_enum(self):
         import pickle

Modified: pypy/dist/pypy/module/_pickle_support/__init__.py
==============================================================================
--- pypy/dist/pypy/module/_pickle_support/__init__.py	(original)
+++ pypy/dist/pypy/module/_pickle_support/__init__.py	Sat May 20 21:48:07 2006
@@ -12,6 +12,6 @@
         'func_new'     : 'maker.func_new',
         'module_new'   : 'maker.module_new',
         'method_new'   : 'maker.method_new',
-        'dictiter_new' : 'maker.dictiter_new',
+        'dictiter_surrogate_new' : 'maker.dictiter_surrogate_new',
         'seqiter_new'  : 'maker.seqiter_new',
     }

Modified: pypy/dist/pypy/module/_pickle_support/maker.py
==============================================================================
--- pypy/dist/pypy/module/_pickle_support/maker.py	(original)
+++ pypy/dist/pypy/module/_pickle_support/maker.py	Sat May 20 21:48:07 2006
@@ -35,17 +35,11 @@
     return space.call_args(w_type, __args__)
 method_new.unwrap_spec = [ObjSpace, Arguments]
 
-def dictiter_new(space, __args__):
-    from pypy.objspace.std.dictobject import W_DictIterObject
-    #print "dictiter_new here 1)", space, w_dictitertype, __args__
-    w_type = space.gettypeobject(dictiter_typedef)
-    w_obj = space.allocate_instance(W_DictIterObject, w_type)
-    #print "dictiter_new here 2)", w_obj
-    # XXX W_DictIterObject.__init__(w_obj, space)
-    # this is wrong, but we need to produce something different, anyway
-    #print "dictiter_new here 3)", w_obj
-    return w_obj
-dictiter_new.unwrap_spec = [ObjSpace, Arguments]
+def dictiter_surrogate_new(space, w_lis):
+    # we got a listobject.
+    # simply create an iterator and that's it.
+    return space.iter(w_lis)
+dictiter_surrogate_new.unwrap_spec = [ObjSpace, W_Root]
 
 #XXX this doesn't work yet
 def seqiter_new(space, w_seqitertype, __args__):

Modified: pypy/dist/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dicttype.py	(original)
+++ pypy/dist/pypy/objspace/std/dicttype.py	Sat May 20 21:48:07 2006
@@ -124,13 +124,63 @@
 
 # ____________________________________________________________
 
-def descr_dictiter__reduce__(space, w_subtype):
+def descr_dictiter__reduce__(w_self, space):
+    """
+    This is a slightly special case of pickling.
+    Since iteration over a dict is a bit hairy,
+    we do the following:
+    - create a clone of the dict iterator
+    - run it to the original position
+    - collect all remaining elements into a list
+    At unpickling time, we just use that list
+    and create an iterator on it.
+    This is of course not the standard way.
+
+    XXX to do: remove this __reduce__ method and do
+    a registration with copy_reg, instead.
+    """
     from pypy.interpreter.mixedmodule import MixedModule
+    from pypy.objspace.std.dictobject import \
+         W_DictIter_Keys, W_DictIter_Values, W_DictIter_Items
     w_mod    = space.getbuiltinmodule('_pickle_support')
     mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('dictiter_new')
-    w        = space.wrap
+    new_inst = mod.get('dictiter_surrogate_new')
+    w_typeobj = space.gettypeobject(dictiter_typedef)
+    if isinstance(w_self, W_DictIter_Keys):
+        w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj)
+    elif isinstance(w_self, W_DictIter_Values):
+        w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj)
+    elif isinstance(w_self, W_DictIter_Items):
+        w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj)
+    # we cannot call __init__ since we don't have the original dict
+    w_clone.space = space
+    w_clone.content = w_self.content
+    w_clone.len = w_self.len
+    w_clone.pos = 0
+    w_clone.setup_iterator()
+    # spool until we have the same pos
+    while w_clone.pos < w_self.pos:
+        w_obj = w_clone.next_entry()
+        w_clone.pos += 1
+    stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)]
+    w_res = space.newlist(stuff)
     tup      = [
+        w_res
+    ]
+    w_ret = space.newtuple([new_inst, space.newtuple(tup)])
+    return w_ret    
+
+# ____________________________________________________________
+
+
+dictiter_typedef = StdTypeDef("dictionaryiterator",
+    __reduce__ = gateway.interp2app(descr_dictiter__reduce__,
+                           unwrap_spec=[gateway.W_Root, gateway.ObjSpace]),
+    )
+#note: registering in dictobject.py
+
+
+### fragment for frame object left here
         #w(10),
         #w(self.co_argcount), 
         #w(self.co_nlocals), 
@@ -147,13 +197,4 @@
         #space.newtuple([w(v) for v in self.co_freevars]),
         #space.newtuple([w(v) for v in self.co_cellvars]),
         #hidden_applevel=False, magic = 62061 | 0x0a0d0000
-    ]
-    return space.newtuple([new_inst, space.newtuple(tup)])
-
-# ____________________________________________________________
 
-dictiter_typedef = StdTypeDef("dictionaryiterator",
-    __reduce__ = gateway.interp2app(descr_dictiter__reduce__,
-                           unwrap_spec=[gateway.ObjSpace, gateway.W_Root]),
-    )
-#note: registering in dictobject.py



More information about the Pypy-commit mailing list