def from_name(cls, name): distribution = super().from_name(name) temp_dir = Path(cls._cachedir.name) dist_dir = None files = distribution.files or [] prep = importlib_metadata.Prepared(distribution.name) normalized = prep.normalized legacy_normalized = prep.legacy_normalized for file in files: # patch: the onionshare and onionshare_cli files are using absolute paths, which break everything if name in ["onionshare", "onionshare_cli"]: if ".dist-info" not in file.as_posix(): continue file = CustomPackagePath(file) if (not file.match(f"{name}-*.dist-info/*") and not file.match(f"{distribution.name}-*.dist-info/*") and not file.match(f"{normalized}-*.dist-info/*") and not file.match(f"{legacy_normalized}-*.dist-info/*")): continue src_path = file.locate() if not src_path.exists(): continue dst_path = temp_dir / file.as_posix() if dist_dir is None: dist_dir = dst_path.parent dist_dir.mkdir(exist_ok=True) shutil.copy2(src_path, dst_path) if dist_dir is None: raise importlib_metadata.PackageNotFoundError(name) return cls.at(dist_dir)
def from_name(cls, name): distribution = super().from_name(name) # Cache dist-info files in a temporary directory temp_dir = Path(cls._cachedir.name) dist_dir = None files = distribution.files or [] prep = importlib_metadata.Prepared(distribution.name) normalized = prep.normalized legacy_normalized = prep.legacy_normalized for file in files: # only existing dist-info files if (not file.match(f"{name}-*.dist-info/*") and not file.match(f"{distribution.name}-*.dist-info/*") and not file.match(f"{normalized}-*.dist-info/*") and not file.match(f"{legacy_normalized}-*.dist-info/*")): continue src_path = file.locate() if not src_path.exists(): continue dst_path = temp_dir / file.as_posix() if dist_dir is None: dist_dir = dst_path.parent dist_dir.mkdir(exist_ok=True) shutil.copy2(src_path, dst_path) if dist_dir is None: raise importlib_metadata.PackageNotFoundError(name) return cls.at(dist_dir)
def require_version(requirement: str, hint: Optional[str] = None) -> None: """ Perform a runtime check of the dependency versions, using the exact same syntax used by pip. The installed module version comes from the `site-packages` dir via `importlib_metadata`. Args: requirement (:obj:`str`): pip style definition, e.g., "tokenizers==0.9.4", "tqdm>=4.27", "numpy" hint (:obj:`str`, `optional`): what suggestion to print in case of requirements not being met """ hint = f"\n{hint}" if hint is not None else "" # non-versioned check if re.match(r"^[\w_\-\d]+$", requirement): pkg, op, want_ver = requirement, None, None else: match = re.findall(r"^([^!=<>\s]+)([\s!=<>]{1,2}.+)", requirement) if not match: raise ValueError( f"requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23, but got {requirement}" ) pkg, want_full = match[0] want_range = want_full.split( ",") # there could be multiple requirements wanted = {} for w in want_range: match = re.findall(r"^([\s!=<>]{1,2})(.+)", w) if not match: raise ValueError( f"requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23, but got {requirement}" ) op, want_ver = match[0] wanted[op] = want_ver if op not in ops: raise ValueError( f"{requirement}: need one of {list(ops.keys())}, but got {op}" ) # special case if pkg == "python": got_ver = ".".join([str(x) for x in sys.version_info[:3]]) for op, want_ver in wanted.items(): _compare_versions(op, got_ver, want_ver, requirement, pkg, hint) return # check if any version is installed try: got_ver = importlib_metadata.version(pkg) except importlib_metadata.PackageNotFoundError: raise importlib_metadata.PackageNotFoundError( f"The '{requirement}' distribution was not found and is required by this application. {hint}" ) # check that the right version is installed if version number or a range was provided if want_ver is not None: for op, want_ver in wanted.items(): _compare_versions(op, got_ver, want_ver, requirement, pkg, hint)
def require_version(requirement: str, hint: Optional[str] = None) -> None: """ Perform a runtime check of the dependency versions, using the exact same syntax used by pip. The installed module version comes from the `site-packages` dir via `importlib_metadata`. Args: requirement (:obj:`str`): pip style definition, e.g., "tokenizers==0.9.4", "tqdm>=4.27", "numpy" hint (:obj:`str`, `optional`): what suggestion to print in case of requirements not being met """ # note: while pkg_resources.require_version(requirement) is a much simpler way to do it, it # fails if some of the dependencies of the dependencies are not matching, which is not necessarily # bad, hence the more complicated check - which also should be faster, since it doesn't check # dependencies of dependencies. hint = f"\n{hint}" if hint is not None else "" # non-versioned check if re.match(r"^[\w_\-\d]+$", requirement): pkg, op, want_ver = requirement, None, None else: match = re.findall(r"^([^!=<>\s]+)([\s!=<>]{1,2})(.+)", requirement) if not match: raise ValueError( f"requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23, but got {requirement}" ) pkg, op, want_ver = match[0] if op not in ops: raise ValueError(f"need one of {list(ops.keys())}, but got {op}") # special case if pkg == "python": got_ver = ".".join([str(x) for x in sys.version_info[:3]]) if not ops[op](version.parse(got_ver), version.parse(want_ver)): raise ImportError( f"{requirement} is required for a normal functioning of this module, but found {pkg}=={got_ver}." ) return # check if any version is installed try: got_ver = importlib_metadata.version(pkg) except importlib_metadata.PackageNotFoundError: raise importlib_metadata.PackageNotFoundError( f"The '{requirement}' distribution was not found and is required by this application. {hint}" ) # check that the right version is installed if version number was provided if want_ver is not None and not ops[op](version.parse(got_ver), version.parse(want_ver)): raise ImportError( f"{requirement} is required for a normal functioning of this module, but found {pkg}=={got_ver}.{hint}" )