Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r63772:0b9904f7bb80
Date: 2013-04-30 11:53 -0700
http://bitbucket.org/pypy/pypy/changeset/0b9904f7bb80/

Log:    apply the function pickling extras from default, fixes all but 1 of
        the outstanding pickle py3k_skips

diff --git a/lib-python/3/pickle.py b/lib-python/3/pickle.py
--- a/lib-python/3/pickle.py
+++ b/lib-python/3/pickle.py
@@ -25,7 +25,7 @@
 
 __version__ = "$Revision$"       # Code version
 
-from types import FunctionType, BuiltinFunctionType
+from types import FunctionType, BuiltinFunctionType, ModuleType
 from copyreg import dispatch_table
 from copyreg import _extension_registry, _inverted_registry, _extension_cache
 import marshal
@@ -615,7 +615,27 @@
                 write(APPEND)
             # else tmp is empty, and we're done
 
+    def _pickle_maybe_moduledict(self, obj):
+        # save module dictionary as "getattr(module, '__dict__')"
+        try:
+            name = obj['__name__']
+            if type(name) is not str:
+                return None
+            themodule = sys.modules[name]
+            if type(themodule) is not ModuleType:
+                return None
+            if themodule.__dict__ is not obj:
+                return None
+        except (AttributeError, KeyError, TypeError):
+            return None
+
+        return getattr, (themodule, '__dict__')
+
     def save_dict(self, obj):
+        modict_saver = self._pickle_maybe_moduledict(obj)
+        if modict_saver is not None:
+            return self.save_reduce(*modict_saver)
+
         write = self.write
 
         if self.bin:
@@ -666,6 +686,35 @@
                 write(SETITEM)
             # else tmp is empty, and we're done
 
+    def save_function(self, obj):
+        lasterr = None
+        try:
+            return self.save_global(obj)
+        except PicklingError as e:
+            lasterr = e
+        try:
+            # Check copy_reg.dispatch_table
+            reduce = dispatch_table.get(type(obj))
+            if reduce:
+                rv = reduce(obj)
+            else:
+                # Check for a __reduce_ex__ method, fall back to
+                # __reduce__
+                reduce = getattr(obj, "__reduce_ex__", None)
+                if reduce:
+                    rv = reduce(self.proto)
+                else:
+                    reduce = getattr(obj, "__reduce__", None)
+                    if reduce:
+                        rv = reduce()
+                    else:
+                        raise last_exc
+            return self.save_reduce(obj=obj, *rv)
+        finally:
+            if lasterr is not None:
+                del lasterr
+    dispatch[FunctionType] = save_function
+
     def save_global(self, obj, name=None, pack=struct.pack):
         write = self.write
         memo = self.memo
@@ -722,7 +771,6 @@
 
         self.memoize(obj)
 
-    dispatch[FunctionType] = save_global
     dispatch[BuiltinFunctionType] = save_global
     dispatch[type] = save_global
 
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
@@ -125,7 +125,6 @@
         assert map is result
     
     def test_pickle_non_top_reachable_func(self):
-        py3k_skip("not supported yet")
         def func():
             return 42
         global a
@@ -157,7 +156,6 @@
         assert not (cell != result)
 
     def test_pickle_frame(self):
-        py3k_skip("not supported yet")
         #import sys
         # avoid creating a closure for now
         def f():
@@ -189,7 +187,6 @@
         assert f1.f_trace is f2.f_trace
 
     def test_pickle_frame_with_exc(self):
-        py3k_skip("not supported yet")
         #import sys
         # avoid creating a closure for now
         self = None
@@ -211,7 +208,6 @@
         assert read_exc_type(f2) is ValueError
 
     def test_pickle_frame_clos(self):
-        py3k_skip("not supported yet")
         # similar to above, therefore skipping the asserts.
         # we just want to see that the closure works
         import sys # this is the difference!
@@ -229,7 +225,6 @@
         f2     = pickle.loads(pckl)
 
     def test_pickle_traceback(self):
-        py3k_skip("not supported yet")
         def f():
             try:
                 raise Exception()
@@ -258,7 +253,6 @@
         assert mod is result
     
     def test_pickle_moduledict(self):
-        py3k_skip("not supported yet")
         import pickle
         moddict  = pickle.__dict__
         pckl     = pickle.dumps(moddict)
@@ -289,7 +283,6 @@
         assert a == result
     
     def test_pickle_method(self):
-        py3k_skip("not supported yet")
         class myclass(object):
             def f(self):
                 return 42
@@ -311,7 +304,6 @@
             del sys.modules['mod']
     
     def test_pickle_staticmethod(self):
-        py3k_skip("not supported yet")
         class myclass(object):
             def f():
                 return 42
@@ -323,7 +315,6 @@
         assert method() == result()
     
     def test_pickle_classmethod(self):
-        py3k_skip("not supported yet")
         class myclass(object):
             def f(cls):
                 return cls
@@ -404,9 +395,8 @@
         assert list(e) == list(result)
 
     def test_pickle_xrangeiter(self):
-        py3k_skip("not supported yet")
         import pickle
-        riter  = iter(xrange(5))
+        riter  = iter(range(5))
         next(riter)
         next(riter)
         pckl   = pickle.dumps(riter)
@@ -415,7 +405,6 @@
         assert list(result) == [2,3,4]
 
     def test_pickle_generator(self):
-        py3k_skip("not supported yet")
         import types
         mod = types.ModuleType('mod')
         import sys
@@ -439,7 +428,6 @@
             del sys.modules['mod']
 
     def test_pickle_generator_blk(self):
-        py3k_skip("not supported yet")
         # same as above but with the generator inside a block
         import types
         mod = types.ModuleType('mod')
diff --git a/pypy/module/_continuation/test/test_zpickle.py 
b/pypy/module/_continuation/test/test_zpickle.py
--- a/pypy/module/_continuation/test/test_zpickle.py
+++ b/pypy/module/_continuation/test/test_zpickle.py
@@ -6,9 +6,6 @@
                        continuation=True,
                        CALL_METHOD=True)
 
-    def setup_class(cls):
-        py.test.py3k_skip("_continuation not supported yet")
-
     def test_basic_setup(self):
         from _continuation import continulet
         lst = [4]
@@ -113,7 +110,6 @@
     }
 
     def setup_class(cls):
-        py.test.py3k_skip("_continuation not supported yet")
         cls.space.appexec([], """():
             global continulet, A, __name__
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to