diff options
author | Jesse Noller <jnoller@gmail.com> | 2008-07-16 14:32:36 +0000 |
---|---|---|
committer | Jesse Noller <jnoller@gmail.com> | 2008-07-16 14:32:36 +0000 |
commit | 13e9d582fd55c3f680cbe9d3d4c219722a484d92 (patch) | |
tree | 8fd06a37d7646bdb48d3699ac38d3c35d1a8857c /Lib/multiprocessing/forking.py | |
parent | a6c5dc07f46c21f3fab81ce44321239378c09548 (diff) | |
download | cpython-git-13e9d582fd55c3f680cbe9d3d4c219722a484d92.tar.gz |
Apply Amaury's patch to multiprocessing for issue 3125, removes the copy_reg and replaces it with ForkingPickler.register(), which should resolve the conflict with the global registry/ctypes
Diffstat (limited to 'Lib/multiprocessing/forking.py')
-rw-r--r-- | Lib/multiprocessing/forking.py | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py index 43e3e83055..cb7f323fec 100644 --- a/Lib/multiprocessing/forking.py +++ b/Lib/multiprocessing/forking.py @@ -12,7 +12,7 @@ import signal from multiprocessing import util, process -__all__ = ['Popen', 'assert_spawning', 'exit', 'duplicate', 'close'] +__all__ = ['Popen', 'assert_spawning', 'exit', 'duplicate', 'close', 'ForkingPickler'] # # Check that the current thread is spawning a child process @@ -26,6 +26,49 @@ def assert_spawning(self): ) # +# Try making some callable types picklable +# + +from pickle import Pickler +class ForkingPickler(Pickler): + dispatch = Pickler.dispatch.copy() + + @classmethod + def register(cls, type, reduce): + def dispatcher(self, obj): + rv = reduce(obj) + self.save_reduce(obj=obj, *rv) + cls.dispatch[type] = dispatcher + +def _reduce_method(m): + if m.im_self is None: + return getattr, (m.im_class, m.im_func.func_name) + else: + return getattr, (m.im_self, m.im_func.func_name) +ForkingPickler.register(type(ForkingPickler.save), _reduce_method) + +def _reduce_method_descriptor(m): + return getattr, (m.__objclass__, m.__name__) +ForkingPickler.register(type(list.append), _reduce_method_descriptor) +ForkingPickler.register(type(int.__add__), _reduce_method_descriptor) + +#def _reduce_builtin_function_or_method(m): +# return getattr, (m.__self__, m.__name__) +#ForkingPickler.register(type(list().append), _reduce_builtin_function_or_method) +#ForkingPickler.register(type(int().__add__), _reduce_builtin_function_or_method) + +try: + from functools import partial +except ImportError: + pass +else: + def _reduce_partial(p): + return _rebuild_partial, (p.func, p.args, p.keywords or {}) + def _rebuild_partial(func, args, keywords): + return partial(func, *args, **keywords) + ForkingPickler.register(partial, _reduce_partial) + +# # Unix # @@ -105,16 +148,18 @@ else: import thread import msvcrt import _subprocess - import copy_reg import time from ._multiprocessing import win32, Connection, PipeConnection from .util import Finalize - try: - from cPickle import dump, load, HIGHEST_PROTOCOL - except ImportError: - from pickle import dump, load, HIGHEST_PROTOCOL + #try: + # from cPickle import dump, load, HIGHEST_PROTOCOL + #except ImportError: + from pickle import load, HIGHEST_PROTOCOL + + def dump(obj, file, protocol=None): + ForkingPickler(file, protocol).dump(obj) # # @@ -346,9 +391,8 @@ else: return type(conn), (Popen.duplicate_for_child(conn.fileno()), conn.readable, conn.writable) - copy_reg.pickle(Connection, reduce_connection) - copy_reg.pickle(PipeConnection, reduce_connection) - + ForkingPickler.register(Connection, reduce_connection) + ForkingPickler.register(PipeConnection, reduce_connection) # # Prepare current process |