def _patch_spec( fullname, spec: ModuleSpec): #loader_class, fullname, path, smsl, target): spec.name = fullname if isinstance(spec.loader, abc_FileLoader): spec.loader = spec.loader.__class__(fullname, spec.loader.path) return spec
def find_spec(self, fullname, path=None, target=None): module_info = self.module_sources.get(fullname) if module_info: if module_info[0] == "source": filename = _path_split(module_info[3])[1] assets = module_info[4] tmp_dir = tempfile.gettempdir() pkg_tmp_dir = os.path.join(tmp_dir, "magic_pack", fullname) if assets: restore_assets(pkg_tmp_dir, assets) if self.enabled: spec = ModuleSpec( name=fullname, loader=MagicPackSourceLoader(fullname, module_info, pkg_tmp_dir, path), is_package=is_package(fullname, filename)) else: spec = ModuleSpec( name=fullname, loader=SourceFileLoader(fullname, module_info[3]), is_package=is_package(fullname, filename)) return spec if module_info[0] == "version": default_spec = super(MagicPackImporter, self).find_spec(fullname, path, target) pypi_name, pypi_version = module_info[-2:] # this module is not installed if default_spec is None: result = os.environ.get("AUTOPIP") while self.auto_install is None and result not in ( "y", "n", "yes-all", "no-all"): result = input( f"Package {pypi_name}({pypi_version}) is not installed. " f"Do you want to pip install it now? (y/n/yes-all/no-all)" ) if result == "yes-all": self.auto_install = True elif result == "no-all": self.auto_install = False if self.auto_install is True or result == "y": # some error may occur if run pip in current interpreter subprocess.call([ sys.executable, "-m", "pip", "install", f"{pypi_name}=={pypi_version}", "--no-dependencies" ]) if self.auto_install is False or result == "n": return None default_spec = super(MagicPackImporter, self).find_spec( fullname, path, target) # sometimes installation failed if default_spec is None: return None if default_spec.loader is not None: loader = VersionPromptProxyLoader(fullname, default_spec.loader, *module_info[-2:]) default_spec.loader = loader return default_spec if module_info[0] == "cython_source": for importer in sys.meta_path: from pyximport import PyxImporter if isinstance(importer, PyxImporter): global pyxargs if fullname in sys.modules and not pyxargs.reload_support: return None # only here when reload() default_spec = ModuleSpec(name=fullname, loader=None) if self.pyx_loader_class is None: self.pyx_loader_class = get_pyx_loader() # noinspection PyCallingNonCallable loader = self.pyx_loader_class( fullname, module_info[1], module_info[2], inplace=importer.inplace, language_level=importer.language_level) default_spec.loader = loader return default_spec return None