[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