def load_module()

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