Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to treat resources from specific modules as dynamic #391

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 32 additions & 0 deletions cloudpickle/cloudpickle.py
Expand Up @@ -44,6 +44,7 @@

import builtins
import dis
import inspect
import opcode
import platform
import sys
Expand Down Expand Up @@ -87,6 +88,9 @@ def g():
# communication speed over compatibility:
DEFAULT_PROTOCOL = pickle.HIGHEST_PROTOCOL

# Names of modules whose resources should be treated as dynamic.
_CUSTOM_DYNAMIC_MODULES_BY_NAME = set()

# Track the provenance of reconstructed dynamic classes to make it possible to
# recontruct instances from the matching singleton class definition when
# appropriate and preserve the usual "isinstance" semantics of Python objects.
Expand Down Expand Up @@ -123,6 +127,31 @@ def _lookup_class_or_track(class_tracker_id, class_def):
return class_def


def register_dynamic_module(module):
module_name = module.__name__ if inspect.ismodule(module) else module
_CUSTOM_DYNAMIC_MODULES_BY_NAME.add(module_name)


def unregister_dynamic_module(module):
module_name = module.__name__ if inspect.ismodule(module) else module
_CUSTOM_DYNAMIC_MODULES_BY_NAME.remove(module_name)


def _is_dynamic_module(module, submodules=True):
module_name = module.__name__ if inspect.ismodule(module) else module
if module_name in _CUSTOM_DYNAMIC_MODULES_BY_NAME:
return True
if submodules:
while True:
parent_name = module_name.rsplit(".", 1)[0]
if parent_name == module_name:
break
if parent_name in _CUSTOM_DYNAMIC_MODULES_BY_NAME:
return True
module_name = parent_name
return False


def _whichmodule(obj, name):
"""Find the module an object belongs to.

Expand Down Expand Up @@ -205,6 +234,9 @@ def _lookup_module_and_qualname(obj, name=None):
if module_name == "__main__":
return None

if _is_dynamic_module(module_name):
return None

# Note: if module_name is in sys.modules, the corresponding module is
# assumed importable at unpickling time. See #357
module = sys.modules.get(module_name, None)
Expand Down