@@ -161,11 +161,15 @@ class CloudPickleConfig:
161161 code changes: when a particular lambda function is slightly
162162 modified but the location of the function in the codebase has not
163163 changed, the pickled representation might stay the same.
164+
165+ pickle_main_by_ref: An optional boolean. If provided, cloudpickle will
166+ pickle main by reference instead of by value.
164167 """
165168 id_generator : typing .Optional [callable ] = uuid_generator
166169 skip_reset_dynamic_type_state : bool = False
167170 filepath_interceptor : typing .Optional [callable ] = None
168171 get_code_object_params : typing .Optional [GetCodeObjectParams ] = None
172+ pickle_main_by_ref : bool = False
169173
170174
171175DEFAULT_CONFIG = CloudPickleConfig ()
@@ -316,7 +320,7 @@ def _whichmodule(obj, name):
316320 return None
317321
318322
319- def _should_pickle_by_reference (obj , name = None ):
323+ def _should_pickle_by_reference (obj , name = None , config = DEFAULT_CONFIG ):
320324 """Test whether an function or a class should be pickled by reference
321325
322326 Pickling by reference means by that the object (typically a function or a
@@ -331,7 +335,7 @@ def _should_pickle_by_reference(obj, name=None):
331335 explicitly registered to be pickled by value.
332336 """
333337 if isinstance (obj , types .FunctionType ) or issubclass (type (obj ), type ):
334- module_and_name = _lookup_module_and_qualname (obj , name = name )
338+ module_and_name = _lookup_module_and_qualname (obj , name = name , config = config )
335339 if module_and_name is None :
336340 return False
337341 module , name = module_and_name
@@ -351,7 +355,7 @@ def _should_pickle_by_reference(obj, name=None):
351355 "cannot check importability of {} instances" .format (type (obj ).__name__ ))
352356
353357
354- def _lookup_module_and_qualname (obj , name = None ):
358+ def _lookup_module_and_qualname (obj , name = None , config = DEFAULT_CONFIG ):
355359 if name is None :
356360 name = getattr (obj , "__qualname__" , None )
357361 if name is None : # pragma: no cover
@@ -367,7 +371,7 @@ def _lookup_module_and_qualname(obj, name=None):
367371 # imported module. obj is thus treated as dynamic.
368372 return None
369373
370- if module_name == "__main__" :
374+ if module_name == "__main__" and not config . pickle_main_by_ref :
371375 return None
372376
373377 # Note: if module_name is in sys.modules, the corresponding module is
@@ -718,7 +722,8 @@ def _decompose_typevar(obj, config: CloudPickleConfig):
718722def _typevar_reduce (obj , config : CloudPickleConfig ):
719723 # TypeVar instances require the module information hence why we
720724 # are not using the _should_pickle_by_reference directly
721- module_and_name = _lookup_module_and_qualname (obj , name = obj .__name__ )
725+ module_and_name = _lookup_module_and_qualname (
726+ obj , name = obj .__name__ , config = config )
722727
723728 if module_and_name is None :
724729 return (_make_typevar , _decompose_typevar (obj , config ))
@@ -1185,7 +1190,7 @@ def _class_reduce(obj, config: CloudPickleConfig):
11851190 return type , (NotImplemented , )
11861191 elif obj in _BUILTIN_TYPE_NAMES :
11871192 return _builtin_type , (_BUILTIN_TYPE_NAMES [obj ], )
1188- elif not _should_pickle_by_reference (obj ):
1193+ elif not _should_pickle_by_reference (obj , config = config ):
11891194 return _dynamic_class_reduce (obj , config )
11901195 return NotImplemented
11911196
@@ -1410,7 +1415,7 @@ def _function_reduce(self, obj):
14101415 obj using a custom cloudpickle reducer designed specifically to handle
14111416 dynamic functions.
14121417 """
1413- if _should_pickle_by_reference (obj ):
1418+ if _should_pickle_by_reference (obj , config = self . config ):
14141419 return NotImplemented
14151420 elif self .config .get_code_object_params is not None :
14161421 return self ._stable_identifier_function_reduce (obj )
@@ -1617,7 +1622,7 @@ def save_global(self, obj, name=None, pack=struct.pack):
16171622
16181623 if name is not None :
16191624 super ().save_global (obj , name = name )
1620- elif not _should_pickle_by_reference (obj , name = name ):
1625+ elif not _should_pickle_by_reference (obj , name = name , config = self . config ):
16211626 self ._save_reduce_pickle5 (
16221627 * _dynamic_class_reduce (obj , self .config ), obj = obj )
16231628 else :
@@ -1642,7 +1647,7 @@ def save_function(self, obj, name=None):
16421647 Determines what kind of function obj is (e.g. lambda, defined at
16431648 interactive prompt, etc) and handles the pickling appropriately.
16441649 """
1645- if _should_pickle_by_reference (obj , name = name ):
1650+ if _should_pickle_by_reference (obj , name = name , config = self . config ):
16461651 return super ().save_global (obj , name = name )
16471652 elif PYPY and isinstance (obj .__code__ , builtin_code_type ):
16481653 return self .save_pypy_builtin_func (obj )
0 commit comments