Skip to content

Commit 2a79b69

Browse files
authored
Don't alter a module when reducing it (#426)
1 parent eddd327 commit 2a79b69

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

Diff for: CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
dev
55
===
66

7+
- Fix a side effect altering dynamic modules at pickling time.
8+
([PR #426](https://github.com/cloudpipe/cloudpickle/pull/426))
9+
710
- Support for pickling type annotations on Python 3.10 as per [PEP 563](
811
https://www.python.org/dev/peps/pep-0563/)
912
([PR #400](https://github.com/cloudpipe/cloudpickle/pull/400))

Diff for: cloudpickle/cloudpickle_fast.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,13 @@ def _module_reduce(obj):
342342
if _is_importable(obj):
343343
return subimport, (obj.__name__,)
344344
else:
345-
obj.__dict__.pop('__builtins__', None)
346-
return dynamic_subimport, (obj.__name__, vars(obj))
345+
# Some external libraries can populate the "__builtins__" entry of a
346+
# module's `__dict__` with unpicklable objects (see #316). For that
347+
# reason, we do not attempt to pickle the "__builtins__" entry, and
348+
# restore a default value for it at unpickling time.
349+
state = obj.__dict__.copy()
350+
state.pop('__builtins__', None)
351+
return dynamic_subimport, (obj.__name__, state)
347352

348353

349354
def _method_reduce(obj):

Diff for: tests/cloudpickle_test.py

+6
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,12 @@ def __reduce__(self):
604604
assert hasattr(depickled_mod.__builtins__, "abs")
605605
assert depickled_mod.f(-1) == 1
606606

607+
# Additional check testing that the issue #425 is fixed: without the
608+
# fix for #425, `mod.f` would not have access to `__builtins__`, and
609+
# thus calling `mod.f(-1)` (which relies on the `abs` builtin) would
610+
# fail.
611+
assert mod.f(-1) == 1
612+
607613
def test_load_dynamic_module_in_grandchild_process(self):
608614
# Make sure that when loaded, a dynamic module preserves its dynamic
609615
# property. Otherwise, this will lead to an ImportError if pickled in

0 commit comments

Comments
 (0)