[pypy-commit] pypy py3k: fix for test_pickle_frame_with_exc, simply support W_OperationError to be

pjenvey noreply at buildbot.pypy.org
Sat May 11 03:53:16 CEST 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r63973:e687186619a8
Date: 2013-05-10 18:50 -0700
http://bitbucket.org/pypy/pypy/changeset/e687186619a8/

Log:	fix for test_pickle_frame_with_exc, simply support W_OperationError
	to be pickled for now. add another test for its __setstate__

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1365,7 +1365,8 @@
             unroller.operr.normalize_exception(frame.space)
         return FinallyBlock.handle(self, frame, unroller)
 
-block_classes = {'SETUP_LOOP': LoopBlock,
+block_classes = {'EXCEPT_HANDLER_BLOCK': ExceptHandlerBlock,
+                 'SETUP_LOOP': LoopBlock,
                  'SETUP_EXCEPT': ExceptBlock,
                  'SETUP_FINALLY': FinallyBlock,
                  'SETUP_WITH': WithBlock,
@@ -1380,6 +1381,21 @@
     def __init__(self, operr):
         self.operr = operr
 
+    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('operationerror_new')
+        w_args = space.newtuple([])
+        operr = self.operr
+        if operr is None:
+            return space.newtuple([w_new_inst, w_args])
+        w_state = space.newtuple([operr.w_type, operr.get_w_value(space),
+                                  operr.get_traceback()])
+        return space.newtuple([w_new_inst, w_args, w_state])
+
+    def descr_setstate(self, space, w_state):
+        self.operr = OperationError(*space.fixedview(w_state, 3))
 
 def source_as_str(space, w_source, funcname, what, flags):
     """Return source code as str0 with adjusted compiler flags
diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py
--- a/pypy/interpreter/test/test_zzpickle_and_slow.py
+++ b/pypy/interpreter/test/test_zzpickle_and_slow.py
@@ -207,6 +207,29 @@
 
         assert read_exc_type(f2) is ValueError
 
+    def test_pickle_frame_with_exc_nested(self):
+        # avoid creating a closure for now
+        self = None
+        def f():
+            try:
+                1/0
+            except:
+                try:
+                    raise ValueError
+                except:
+                    import sys, pickle
+                    f = sys._getframe()
+                    saved = hide_top_frame(f)
+                    pckl = pickle.dumps(f)
+                    restore_top_frame(f, saved)
+                    return pckl
+
+        import pickle
+        pckl   = f()
+        f2     = pickle.loads(pckl)
+
+        assert read_exc_type(f2) is ValueError
+
     def test_pickle_frame_clos(self):
         # similar to above, therefore skipping the asserts.
         # we just want to see that the closure works
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -968,4 +968,8 @@
 SuspendedUnroller.typedef = TypeDef("SuspendedUnroller")
 SuspendedUnroller.typedef.acceptable_as_base_class = False
 
-W_OperationError.typedef = TypeDef("OperationError")
+W_OperationError.typedef = TypeDef("OperationError",
+    __reduce__ = interp2app(W_OperationError.descr_reduce),
+    __setstate__ = interp2app(W_OperationError.descr_setstate),
+)
+W_OperationError.typedef.acceptable_as_base_class = False
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,5 +23,6 @@
         'builtin_code': 'maker.builtin_code',
         'builtin_function' : 'maker.builtin_function',
         'enumerate_new': 'maker.enumerate_new',
-        'reversed_new': 'maker.reversed_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
@@ -68,6 +68,10 @@
     new_iter = W_RangeIterator(space, w_start, w_step, w_len, w_index)
     return space.wrap(new_iter)
 
+def operationerror_new(space):
+    from pypy.interpreter.pyopcode import W_OperationError
+    return W_OperationError(None)
+
 @unwrap_spec(identifier=str)
 def builtin_code(space, identifier):
     from pypy.interpreter import gateway


More information about the pypy-commit mailing list