Exemple #1
0
        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)
Exemple #2
0
 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)
Exemple #3
0
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}"
        )