[pypy-svn] r28284 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support

tismer at codespeak.net tismer at codespeak.net
Sun Jun 4 19:13:25 CEST 2006


Author: tismer
Date: Sun Jun  4 19:13:24 2006
New Revision: 28284

Modified:
   pypy/dist/pypy/interpreter/pyframe.py
   pypy/dist/pypy/interpreter/test/test_pickle.py
   pypy/dist/pypy/interpreter/typedef.py
   pypy/dist/pypy/module/_pickle_support/maker.py
Log:
partially working frame pickling. missing is pickling of blockstack and correct handling of closures

Modified: pypy/dist/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyframe.py	(original)
+++ pypy/dist/pypy/interpreter/pyframe.py	Sun Jun  4 19:13:24 2006
@@ -69,6 +69,7 @@
 
     def descr__reduce__(self, space):
         from pypy.interpreter.mixedmodule import MixedModule
+        from pypy.module._pickle_support import maker # helper fns
         w_mod    = space.getbuiltinmodule('_pickle_support')
         mod      = space.interp_w(MixedModule, w_mod)
         new_inst = mod.get('frame_new')
@@ -79,34 +80,71 @@
         else:
             f_lineno = self.f_lineno
 
-        valuestack = [w(item) for item in self.valuestack.items]
-        blockstack = [w(item) for item in self.blockstack.items]
-
-        tup = [
+#        valuestack = [w(item) for item in self.valuestack.items]
+ #       blockstack = [w(item) for item in self.blockstack.items]
+        w_valuestack = maker.slp_into_tuple_with_nulls(space, self.valuestack.items)
+        w_blockstack = space.w_None ##
+        w_fastlocals = maker.slp_into_tuple_with_nulls(space, self.fastlocals_w)
+        tup_base = [
+            w(self.pycode),
+            ]
+        tup_state = [
             w(self.f_back),
             w(self.builtin),
             w(self.pycode),
-            space.w_None, #space.newtuple(valuestack),  #XXX <pypy.interpreter.nestedscope.PyNestedScopeFrame object at 0x25545d0> causes AttributeError: 'NoneType' object has no attribute 'getclass'
-            space.w_None, #space.newtuple(blockstack),
-            w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value
+            w_valuestack,
+            space.w_None, ## w_blockstack,
+            space.w_None, ## w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value
             self.w_globals,
             w(self.last_instr),
-            w(self.next_instr),     #not in PyFrame.typedef!
-            w(f_lineno),            #why not w(self.f_lineno)? something with self.w_f_trace?
-
-            #space.newtuple(self.fastlocals_w), #XXX (application-level) PicklingError: Can't pickle <type 'AppTestInterpObjectPickling'>: it's not found as __builtin__.AppTestInterpObjectPickling
-            #self.getdictscope(),               #XXX (application-level) PicklingError: Can't pickle <type 'AppTestInterpObjectPickling'>: it's not found as __builtin__.AppTestInterpObjectPickling
+            w(self.next_instr),
+            w(f_lineno),
+            w_fastlocals,
             space.w_None,           #XXX placeholder for f_locals
             
             #f_restricted requires no additional data!
-            self.w_f_trace,
+            space.w_None, ## self.w_f_trace,  ignore for now
 
             w(self.instr_lb), #do we need these three (that are for tracing)
             w(self.instr_ub),
             w(self.instr_prev),
             ]
 
-        return space.newtuple([new_inst, space.newtuple(tup)])
+        return space.newtuple([new_inst, space.newtuple(tup_base), space.newtuple(tup_state)])
+
+    def descr__setstate__(self, space, w_args):
+        from pypy.module._pickle_support import maker # helper fns
+        args_w = space.unpackiterable(w_args)
+        w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_last_exception,\
+            w_globals, w_last_instr, w_next_instr, w_f_lineno, w_fastlocals, w_f_locals, \
+            w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev = args_w
+        w = space.wrap
+        u = space.unwrap
+
+        #new_frame = PyFrame(space, pycode, w(globals), None)
+        # let the code object create the right kind of frame
+        # the distinction is a little over-done but computable
+        new_frame = self
+        pycode = space.unwrap(w_pycode)
+        new_frame.__init__(space, pycode, w_globals, None)
+        new_frame.f_back = u(w_f_back)
+        new_frame.builtin = u(w_builtin)
+        #new_frame.blockstack = blockstack
+        new_frame.valuestack.items = maker.slp_from_tuple_with_nulls(space, w_valuestack)
+        new_frame.last_exception = u(w_last_exception)
+        new_frame.last_instr = space.int_w(w_last_instr)
+        new_frame.next_instr = space.int_w(w_next_instr)
+        new_frame.f_lineno = space.int_w(w_f_lineno)
+        new_frame.fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals)
+
+        if space.is_w(w_f_trace, space.w_None):
+            new_frame.w_f_trace = None
+        else:
+            new_frame.w_f_trace = w_f_trace
+
+        new_frame.instr_lb = space.int_w(w_instr_lb)   #the three for tracing
+        new_frame.instr_ub = space.int_w(w_instr_ub)
+        new_frame.instr_prev = space.int_w(w_instr_prev)
 
     def hide(self):
         return self.pycode.hidden_applevel

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	Sun Jun  4 19:13:24 2006
@@ -95,18 +95,8 @@
         assert f1.f_exc_traceback is f2.f_exc_traceback
         assert f1.f_exc_type is f2.f_exc_type
         assert f1.f_exc_value is f2.f_exc_value
-
-        #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': <module object at 0x0167dc70>, '__name__': '__builtin__', 'test_pickle_frame': <function test_pickle_frame at 0x0237adb0>}
-        #print 'f2.f_globals=', f2.f_globals  #f2.f_globals= {'__builtins__': <module object at 0x0167dc70>, '__name__': '__builtin__', 'test_pickle_frame': <function test_pickle_frame at 0x02c346f0>}
-        #assert f1.f_globals == f2.f_globals  #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)?
-
         assert f1.f_lasti == f2.f_lasti
         assert f1.f_lineno == f2.f_lineno
-
-        #print 'f1.f_locals=', f1.f_locals     #['exc_info', 'tb', 'exc_type', 'exc']
-        #print 'f2.f_locals=', f2.f_locals   #[]
-        #assert list(f1.f_locals) == list(f2.f_locals)
-
         assert f1.f_restricted is f2.f_restricted
         assert f1.f_trace is f2.f_trace
 
@@ -302,44 +292,24 @@
         assert list(result) == [2,3,4]
     
     def test_pickle_generator(self):
-        import pickle
-        def giveme(n):
-            x = 0
-            while x < n:
-                yield x
-        g1   = giveme(10)
-        #print 'g1=', g1, dir(g1)
-        pckl = pickle.dumps(g1)
-        g2   = pickle.loads(pckl)
-        #print 'g2=', g2, dir(g2)
-
-        assert type(g1) is type(g2)
-        assert g1.gi_running == g2.gi_running
-        #assert g1.gi_exhausted == g2.gi_exhausted  #not exported!
-
-        #XXX silly code duplication from frame pickling test
-        f1 = g1.gi_frame
-        f2 = g2.gi_frame
-        assert type(f1) is type(f2)
-        assert dir(f1) == dir(f2)
-        assert f1.__doc__ == f2.__doc__
-        assert type(f1.f_back) is type(f2.f_back)
-        assert f1.f_builtins is f2.f_builtins
-        assert f1.f_code == f2.f_code
-        assert f1.f_exc_traceback is f2.f_exc_traceback
-        assert f1.f_exc_type is f2.f_exc_type
-        assert f1.f_exc_value is f2.f_exc_value
-
-        #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': <module object at 0x0167dc70>, '__name__': '__builtin__', 'test_pickle_frame': <function test_pickle_frame at 0x0237adb0>}
-        #print 'f2.f_globals=', f2.f_globals  #f2.f_globals= {'__builtins__': <module object at 0x0167dc70>, '__name__': '__builtin__', 'test_pickle_frame': <function test_pickle_frame at 0x02c346f0>}
-        #assert f1.f_globals == f2.f_globals  #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)?
-
-        assert f1.f_lasti == f2.f_lasti
-        assert f1.f_lineno == f2.f_lineno
-
-        #print 'f1.f_locals=', f1.f_locals     #['exc_info', 'tb', 'exc_type', 'exc']
-        #print 'f2.f_locals=', f2.f_locals   #[]
-        #assert list(f1.f_locals) == list(f2.f_locals)
-
-        assert f1.f_restricted is f2.f_restricted
-        assert f1.f_trace is f2.f_trace
+        import new
+        mod = new.module('mod')
+        import sys
+        sys.modules['mod'] = mod
+        try:
+            def giveme(n):
+                x = 0
+                while x < n:
+                    yield x
+                    x += 1
+            import pickle
+            mod.giveme = giveme
+            giveme.__module__ = mod
+            g1   = mod.giveme(10)
+            #g1.next()
+            #g1.next()
+            pckl = pickle.dumps(g1)
+            g2   = pickle.loads(pckl)
+            assert list(g1) == list(g2)
+        finally:
+            del sys.modules['mod']

Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py	(original)
+++ pypy/dist/pypy/interpreter/typedef.py	Sun Jun  4 19:13:24 2006
@@ -521,8 +521,10 @@
     )
 
 PyFrame.typedef = TypeDef('frame',
-    #__reduce__   = interp2app(PyFrame.descr__reduce__,
-    #                          unwrap_spec=['self', ObjSpace]),
+    __reduce__   = interp2app(PyFrame.descr__reduce__,
+                              unwrap_spec=['self', ObjSpace]),
+    __setstate__ = interp2app(PyFrame.descr__setstate__,
+                              unwrap_spec=['self', ObjSpace, W_Root]),
     f_builtins = GetSetProperty(PyFrame.fget_f_builtins),
     f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno),
     f_back = GetSetProperty(PyFrame.fget_f_back),
@@ -623,8 +625,8 @@
 del BuiltinFunction.typedef.rawdict['__get__']
 
 PyTraceback.typedef = TypeDef("traceback",
-    #__reduce__   = interp2app(PyTraceback.descr__reduce__,
-    #                          unwrap_spec=['self', ObjSpace]),
+    __reduce__   = interp2app(PyTraceback.descr__reduce__,
+                              unwrap_spec=['self', ObjSpace]),
     tb_frame  = interp_attrproperty('frame', cls=PyTraceback),
     tb_lasti  = interp_attrproperty('lasti', cls=PyTraceback),
     tb_lineno = interp_attrproperty('lineno', cls=PyTraceback),
@@ -632,8 +634,8 @@
     )
 
 GeneratorIterator.typedef = TypeDef("generator",
-    #__reduce__   = interp2app(GeneratorIterator.descr__reduce__,
-    #                          unwrap_spec=['self', ObjSpace]),
+    __reduce__   = interp2app(GeneratorIterator.descr__reduce__,
+                              unwrap_spec=['self', ObjSpace]),
     next       = interp2app(GeneratorIterator.descr_next),
     __iter__   = interp2app(GeneratorIterator.descr__iter__),
     gi_running = interp_attrproperty('running', cls=GeneratorIterator),

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	Sun Jun  4 19:13:24 2006
@@ -53,52 +53,66 @@
     return W_ReverseSeqIterObject(space, w_seq, index)
     
 def frame_new(space, __args__):
-    return None
-##     args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
-##     args = [space.unwrap(w_arg) for w_arg in args_w]
-##     f_back, builtin, pycode, valuestack, blockstack, last_exception,\
-##         globals, last_instr, next_instr, f_lineno, fastlocals, f_trace,\
-##         instr_lb, instr_ub, instr_prev = args
-##     w = space.wrap
-
-##     new_frame = PyFrame(space, pycode, w(globals), None)
-##     new_frame.f_back = f_back
-##     new_frame.builtin = builtin
-##     #new_frame.blockstack = blockstack
-##     #new_frame.valuestack = valuestack
-##     new_frame.last_exception = last_exception
-##     new_frame.last_instr = last_instr
-##     new_frame.next_instr = next_instr
-##     new_frame.f_lineno = f_lineno
-##     #new_frame.fastlocals_w = w(fastlocals)
-
-##     if space.is_w(f_trace, space.w_None):
-##         new_frame.w_f_trace = None
-##     else:
-##         new_frame.w_f_trace = w(f_trace)
-
-##     new_frame.instr_lb = instr_lb   #the three for tracing
-##     new_frame.instr_ub = instr_ub
-##     new_frame.instr_prev = instr_prev
-
-##     return space.wrap(new_frame)
+    args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
+    w_pycode, = args_w
+    pycode = space.interp_w(PyCode, w_pycode)
+    w = space.wrap
+
+    # let the code object create the right kind of frame
+    # the distinction is a littleover-done but computable
+    Klass = pycode.get_frame_class()
+    new_frame = instantiate(Klass)
+    return space.wrap(new_frame)
 frame_new.unwrap_spec = [ObjSpace, Arguments]
 
 def traceback_new(space, __args__):
-    return None
-##     args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
-##     args = [space.unwrap(w_arg) for w_arg in args_w]
-##     frame, lasti, lineno, next = args
-##     return PyTraceback(space, frame, lasti, lineno, next)
+    args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
+    w_frame, w_lasti, w_lineno, w_next = args_w
+    frame = space.interp_w(PyFrame, w_frame)
+    lasti = space.int_w(w_lasti)
+    lineno = space.int_w(w_lineno)
+    next = space.interp_w(PyTraceback, w_next, can_be_None=True)
+    return space.wrap(PyTraceback(space, frame, lasti, lineno, next))
 traceback_new.unwrap_spec = [ObjSpace, Arguments]
 
 def generator_new(space, __args__):
-    return None
-##     args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
-##     args = [space.unwrap(w_arg) for w_arg in args_w]
-##     frame, running, exhausted = args
-##     new_generator = GeneratorIterator(frame)
-##     new_generator.running = running
-##     new_generator.exhausted = exhausted
-##     return new_generator
+    args_w, kwds_w = __args__.unpack()  #stolen from std/fake.py
+    w_frame, w_running, w_exhausted = args_w
+    frame = space.interp_w(PyFrame, w_frame)
+    running = space.int_w(w_running)
+    exhausted = space.int_w(w_exhausted)
+    new_generator = GeneratorIterator(frame)
+    new_generator.running = running
+    new_generator.exhausted = exhausted
+    return space.wrap(new_generator)
 generator_new.unwrap_spec = [ObjSpace, Arguments]
+
+# ___________________________________________________________________
+# Helper functions for internal use
+
+# adopted from prickelpit.c  (but almost completely different)
+
+def slp_into_tuple_with_nulls(space, seq_w):
+    """
+    create a tuple with the object and store
+    a tuple with the positions of NULLs as first element.
+    """
+    nulls = []
+    tup = [space.w_None]
+    w = space.wrap
+
+    for w_obj in seq_w:
+        if w_obj is None:
+            nulls.append(w(len(tup)-1))
+            w_obj = space.w_None
+        tup.append(w_obj)
+    tup[0] = space.newtuple(nulls)
+    return space.newtuple(tup)
+
+def slp_from_tuple_with_nulls(space, w_tup):
+    tup_w = space.unpackiterable(w_tup)
+    nulls = space.unpackiterable(tup_w.pop(0))
+    for w_p in nulls:
+        p = space.int_w(w_p)
+        tup_w[p] = None
+    return tup_w
\ No newline at end of file



More information about the Pypy-commit mailing list