1212
1313from multiprocessing import util , process
1414
15- __all__ = ['Popen' , 'assert_spawning' , 'exit' , 'duplicate' , 'close' ]
15+ __all__ = ['Popen' , 'assert_spawning' , 'exit' , 'duplicate' , 'close' , 'ForkingPickler' ]
1616
1717#
1818# Check that the current thread is spawning a child process
@@ -25,6 +25,50 @@ def assert_spawning(self):
2525 ' through inheritance' % type (self ).__name__
2626 )
2727
28+ #
29+ # Try making some callable types picklable
30+ #
31+
32+ from pickle import _Pickler as Pickler
33+ class ForkingPickler (Pickler ):
34+ dispatch = Pickler .dispatch .copy ()
35+ @classmethod
36+ def register (cls , type , reduce ):
37+ def dispatcher (self , obj ):
38+ rv = reduce (obj )
39+ if isinstance (rv , str ):
40+ self .save_global (obj , rv )
41+ else :
42+ self .save_reduce (obj = obj , * rv )
43+ cls .dispatch [type ] = dispatcher
44+
45+ def _reduce_method (m ):
46+ if m .__self__ is None :
47+ return getattr , (m .__class__ , m .__func__ .__name__ )
48+ else :
49+ return getattr , (m .__self__ , m .__func__ .__name__ )
50+ class _C :
51+ def f (self ):
52+ pass
53+ ForkingPickler .register (type (_C ().f ), _reduce_method )
54+
55+
56+ def _reduce_method_descriptor (m ):
57+ return getattr , (m .__objclass__ , m .__name__ )
58+ ForkingPickler .register (type (list .append ), _reduce_method_descriptor )
59+ ForkingPickler .register (type (int .__add__ ), _reduce_method_descriptor )
60+
61+ try :
62+ from functools import partial
63+ except ImportError :
64+ pass
65+ else :
66+ def _reduce_partial (p ):
67+ return _rebuild_partial , (p .func , p .args , p .keywords or {})
68+ def _rebuild_partial (func , args , keywords ):
69+ return partial (func , * args , ** keywords )
70+ ForkingPickler .register (partial , _reduce_partial )
71+
2872#
2973# Unix
3074#
@@ -105,16 +149,18 @@ def thread_is_spawning():
105149 import _thread
106150 import msvcrt
107151 import _subprocess
108- import copyreg
109152 import time
110153
111154 from ._multiprocessing import win32 , Connection , PipeConnection
112155 from .util import Finalize
113156
114- try :
115- from cPickle import dump , load , HIGHEST_PROTOCOL
116- except ImportError :
117- from pickle import dump , load , HIGHEST_PROTOCOL
157+ #try:
158+ # from cPickle import dump, load, HIGHEST_PROTOCOL
159+ #except ImportError:
160+ from pickle import load , HIGHEST_PROTOCOL
161+
162+ def dump (obj , file , protocol = None ):
163+ ForkingPickler (file , protocol ).dump (obj )
118164
119165 #
120166 #
@@ -346,9 +392,8 @@ def reduce_connection(conn):
346392 return type (conn ), (Popen .duplicate_for_child (conn .fileno ()),
347393 conn .readable , conn .writable )
348394
349- copyreg .pickle (Connection , reduce_connection )
350- copyreg .pickle (PipeConnection , reduce_connection )
351-
395+ ForkingPickler .register (Connection , reduce_connection )
396+ ForkingPickler .register (PipeConnection , reduce_connection )
352397
353398#
354399# Prepare current process
0 commit comments