in metaflow/plugins/env_escape/client_modules.py [0:0]
def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[fullname]
if self._client is None:
if sys.version_info[0] < 3:
raise NotImplementedError(
"Environment escape imports are not supported in Python 2"
)
# We initialize a client and query the modules we handle
# The max_pickle_version is the pickle version that the server (so
# the underlying interpreter we call into) supports; we determine
# what version the current environment support and take the minimum
# of those two
max_pickle_version = min(self._max_pickle_version, pickle.HIGHEST_PROTOCOL)
self._client = Client(
self._module_prefixes,
self._python_executable,
self._pythonpath,
max_pickle_version,
self._config_dir,
)
atexit.register(_clean_client, self._client)
# Get information about overrides and what the server knows about
exports = self._client.get_exports()
prefixes = set()
export_classes = exports.get("classes", [])
export_functions = exports.get("functions", [])
export_values = exports.get("values", [])
export_exceptions = exports.get("exceptions", [])
self._aliases = exports.get("aliases", {})
for name in itertools.chain(
export_classes,
export_functions,
export_values,
(e[0] for e in export_exceptions),
):
splits = name.rsplit(".", 1)
prefixes.add(splits[0])
# We will make sure that we create modules even for "empty" prefixes
# because packages are always loaded hierarchically so if we have
# something in `a.b.c` but nothing directly in `a`, we still need to
# create a module named `a`. There is probably a better way of doing this
all_prefixes = list(prefixes)
for prefix in all_prefixes:
parts = prefix.split(".")
cur = parts[0]
for i in range(1, len(parts)):
prefixes.add(cur)
cur = ".".join([cur, parts[i]])
# We now know all the modules that we can handle. We update
# handled_module and return the module if we have it or raise ImportError
self._handled_modules = {}
for prefix in prefixes:
self._handled_modules[prefix] = _WrappedModule(
self, prefix, exports, self._client
)
canonical_fullname = get_canonical_name(fullname, self._aliases)
# Modules are created canonically but we need to return something for any
# of the aliases.
module = self._handled_modules.get(canonical_fullname)
if module is None:
raise ImportError
sys.modules[fullname] = module
return module