Skip to content

pickling a dynamic module remove its __builtins__ as a side effect #425

@pierreglaser

Description

@pierreglaser

Reproducer below:

(test) ~/repos/cloudpickle (master)❯_ ipython
Python 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:00:30)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from types import ModuleType

In [2]: m = ModuleType('mod')

In [3]: exec("""
   ...: def f():
   ...:     import math
   ...:     return math.sqrt(4)
   ...: """, vars(m))

In [4]: m.f()
Out[4]: 2.0

In [5]: import cloudpickle

In [6]: roundtripped_m = cloudpickle.loads(cloudpickle.dumps(m))

In [7]: roundtripped_m.f()
Out[7]: 2.0

In [8]: m.f()
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-8-ada232509f74> in <module>
----> 1 m.f()

<string> in f()

ImportError: __import__ not found

The issue comes from the _module_reduce function, that removes the item corresponding to the __builtins__ key from the module being pickled (see #325). We should instead copy the module state before removing the item corresponding to the __builtins__ key.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions