Пример #1
0
    def create_dependencies(self, force=False):
        # type: (bool) -> "PackageInfo"
        """Create values for **self.dependencies**.

        :param bool force: Sets **self.dependencies** to an empty tuple if it would be
            None, defaults to False.
        :return: An updated instance of the current object with **self.dependencies**
            updated accordingly.
        :rtype: :class:`PackageInfo`
        """
        if not self.dependencies and not self.requires_dist:
            if force:
                return attr.evolve(self, dependencies=tuple())
            return self
        self_dependency = self.to_dependency()
        deps = set()
        self_dependencies = tuple() if not self.dependencies else self.dependencies
        for dep in self_dependencies:
            if dep is None:
                continue
            new_dep = dep.add_parent(self_dependency)
            deps.add(new_dep)
        created_deps = create_dependencies(self.requires_dist, parent=self_dependency)
        if created_deps is not None:
            for dep in created_deps:
                if dep is None:
                    continue
                deps.add(dep)
        return attr.evolve(self, dependencies=tuple(sorted(deps)))
Пример #2
0
 def get_dependencies(self):
     # type: () -> "Package"
     urls = []  # type: List[ReleaseUrl]
     deps = set()  # type: Set[str]
     info = self.info
     if info.dependencies is None:
         for url in self.urls:
             try:
                 url, dep_dict = url.get_dependencies()
             except (RuntimeError, TypeError):
                 # This happens if we are parsing `setup.py` and we fail
                 if url.is_sdist:
                     continue
                 else:
                     raise
             markers = url.markers
             dep_list = dep_dict.get("requires_dist", [])
             for dep in dep_list:
                 # XXX: We need to parse these as requirements and "and" the markers
                 # XXX: together because they may contain "extra" markers which we
                 # XXX: will need to parse and remove
                 deps.add(add_markers_to_dep(dep, markers))
             urls.append(url)
         if None in deps:
             deps.remove(None)
         info = attr.evolve(
             self.info, requires_dist=tuple(sorted(deps))
         ).create_dependencies(force=True)
     return attr.evolve(self, info=info, urls=urls)
Пример #3
0
    def _parse_fragment(self):
        # type: () -> URI
        subdirectory = self.subdirectory if self.subdirectory else ""
        fragment = self.fragment if self.fragment else ""
        if self.fragment is None:
            return self
        fragments = self.fragment.split("&")
        fragment_items = {}
        name = self.name if self.name else ""
        extras = self.extras
        for q in fragments:
            key, _, val = q.partition("=")
            val = unquote_plus(val)
            fragment_items[key] = val
            if key == "egg":
                from .utils import parse_extras

                name, stripped_extras = pip_shims.shims._strip_extras(val)
                if stripped_extras:
                    extras = tuple(parse_extras(stripped_extras))
            elif key == "subdirectory":
                subdirectory = val
        return attr.evolve(
            self,
            fragment_dict=fragment_items,
            subdirectory=subdirectory,
            fragment=fragment,
            extras=extras,
            name=name,
        )
 def create(cls, release_dict, name=None):
     # type: (TReleaseUrlDict, Optional[str]) -> "ReleaseUrl"
     valid_digest_keys = set("{0}_digest".format(k)
                             for k in VALID_ALGORITHMS.keys())
     digest_keys = set(release_dict.keys()) & valid_digest_keys
     creation_kwargs = {
     }  # type: Dict[str, Union[bool, int, str, Digest, TDigestDict]]
     creation_kwargs = {
         k: v
         for k, v in release_dict.items() if k not in digest_keys
     }
     if name is not None:
         creation_kwargs["name"] = name
     for k in digest_keys:
         digest = release_dict[k]
         if not isinstance(digest, six.string_types):
             raise TypeError(
                 "Digests must be strings, got {!r}".format(digest))
         creation_kwargs[k] = Digest.create(k.replace("_digest", ""),
                                            digest)
     release_url = cls(**filter_dict(creation_kwargs))  # type: ignore
     if release_url.is_wheel:
         supported_tags = [
             parse_tag(Tag(*tag))
             for tag in distlib.wheel.Wheel(release_url.url).tags
         ]
         release_url = attr.evolve(release_url, tags=supported_tags)
     return release_url
Пример #5
0
    def _setup_asdf(self):
        # type: () -> "SystemPath"
        if "asdf" in self.finders and self.asdf_finder is not None:
            return self
        from .python import PythonFinder

        os_path = os.environ["PATH"].split(os.pathsep)
        asdf_finder = PythonFinder.create(
            root=ASDF_DATA_DIR,
            ignore_unsupported=True,
            sort_function=parse_asdf_version_order,
            version_glob_path="installs/python/*",
        )
        asdf_index = None
        try:
            asdf_index = self._get_last_instance(ASDF_DATA_DIR)
        except ValueError:
            asdf_index = 0 if is_in_path(next(iter(os_path), ""), ASDF_DATA_DIR) else -1
        if asdf_index is None:
            # we are in a virtualenv without global pyenv on the path, so we should
            # not write pyenv to the path here
            return self
        # * These are the root paths for the finder
        _ = [p for p in asdf_finder.roots]
        new_instance = self._slice_in_paths(asdf_index, [asdf_finder.root])
        paths = self.paths.copy()
        paths[asdf_finder.root] = asdf_finder
        paths.update(asdf_finder.roots)
        return (
            attr.evolve(new_instance, paths=paths, asdf_finder=asdf_finder)
            ._remove_path(normalize_path(os.path.join(ASDF_DATA_DIR, "shims")))
            ._register_finder("asdf", asdf_finder)
        )
Пример #6
0
    def _setup_pyenv(self):
        # type: () -> "SystemPath"
        if "pyenv" in self.finders and self.pyenv_finder is not None:
            return self
        from .python import PythonFinder

        os_path = os.environ["PATH"].split(os.pathsep)

        pyenv_finder = PythonFinder.create(
            root=PYENV_ROOT,
            sort_function=parse_pyenv_version_order,
            version_glob_path="versions/*",
            ignore_unsupported=self.ignore_unsupported,
        )
        pyenv_index = None
        try:
            pyenv_index = self._get_last_instance(PYENV_ROOT)
        except ValueError:
            pyenv_index = 0 if is_in_path(next(iter(os_path), ""), PYENV_ROOT) else -1
        if pyenv_index is None:
            # we are in a virtualenv without global pyenv on the path, so we should
            # not write pyenv to the path here
            return self
        # * These are the root paths for the finder
        _ = [p for p in pyenv_finder.roots]
        new_instance = self._slice_in_paths(pyenv_index, [pyenv_finder.root])
        paths = new_instance.paths.copy()
        paths[pyenv_finder.root] = pyenv_finder
        paths.update(pyenv_finder.roots)
        return (
            attr.evolve(new_instance, paths=paths, pyenv_finder=pyenv_finder)
            ._remove_path(os.path.join(PYENV_ROOT, "shims"))
            ._register_finder("pyenv", pyenv_finder)
        )
Пример #7
0
 def add_dependency(self, dependency):
     # type: ("Dependency") -> "ExtrasCollection"
     if not isinstance(dependency, Dependency):
         raise TypeError(
             "Expected a Dependency instance, received {0!r}".format(dependency)
         )
     dependencies = self.dependencies.copy()
     dependencies.add(dependency)
     return attr.evolve(self, dependencies=dependencies)
Пример #8
0
def create_release_urls_from_list(urls, name=None):
    # type: (Union[TReleasesList, List[ReleaseUrl]], Optional[str]) -> List[ReleaseUrl]
    url_list = []
    for release_dict in urls:
        if isinstance(release_dict, ReleaseUrl):
            if name and not release_dict.name:
                release_dict = attr.evolve(release_dict, name=name)
            url_list.append(release_dict)
            continue
        url_list.append(ReleaseUrl.create(release_dict, name=name))
    return url_list
Пример #9
0
 def _remove_path(self, path):
     # type: (str) -> "SystemPath"
     path_copy = [p for p in reversed(self.path_order[:])]
     new_order = []
     target = normalize_path(path)
     path_map = {normalize_path(pth): pth for pth in self.paths.keys()}
     new_paths = self.paths.copy()
     if target in path_map:
         del new_paths[path_map[target]]
     for current_path in path_copy:
         normalized = normalize_path(current_path)
         if normalized != target:
             new_order.append(normalized)
     new_order = [ensure_path(p).as_posix() for p in reversed(new_order)]
     return attr.evolve(self, path_order=new_order, paths=new_paths)
Пример #10
0
 def _slice_in_paths(self, start_idx, paths):
     # type: (int, List[Path]) -> "SystemPath"
     before_path = []  # type: List[str]
     after_path = []  # type: List[str]
     if start_idx == 0:
         after_path = self.path_order[:]
     elif start_idx == -1:
         before_path = self.path_order[:]
     else:
         before_path = self.path_order[: start_idx + 1]
         after_path = self.path_order[start_idx + 2 :]
     path_order = before_path + [p.as_posix() for p in paths] + after_path
     if path_order == self.path_order:
         return self
     return attr.evolve(self, path_order=path_order)
Пример #11
0
    def _setup_windows(self):
        # type: () -> "SystemPath"
        if "windows" in self.finders and self.windows_finder is not None:
            return self
        from .windows import WindowsFinder

        windows_finder = WindowsFinder.create()
        root_paths = (p for p in windows_finder.paths if p.is_root)
        path_addition = [p.path.as_posix() for p in root_paths]
        new_path_order = self.path_order[:] + path_addition
        new_paths = self.paths.copy()
        new_paths.update({p.path: p for p in root_paths})
        return attr.evolve(
            self,
            windows_finder=windows_finder,
            path_order=new_path_order,
            paths=new_paths,
        )._register_finder("windows", windows_finder)
Пример #12
0
 def clear_caches(self):
     for key in ["executables", "python_executables", "version_dict", "path_entries"]:
         if key in self.__dict__:
             del self.__dict__[key]
     for finder in list(self.__finders.keys()):
         del self.__finders[finder]
     self.__finders = {}
     return attr.evolve(
         self,
         executables=[],
         python_executables={},
         python_version_dict=defaultdict(list),
         version_dict=defaultdict(list),
         pyenv_finder=None,
         windows_finder=None,
         asdf_finder=None,
         path_order=[],
         paths=defaultdict(PathEntry),
     )
Пример #13
0
 def _parse_query(self):
     # type: () -> URI
     query = self.query if self.query is not None else ""
     query_dict = omdict()
     queries = query.split("&")
     query_items = []
     subdirectory = self.subdirectory if self.subdirectory else None
     for q in queries:
         key, _, val = q.partition("=")
         val = unquote_plus(val)
         if key == "subdirectory" and not subdirectory:
             subdirectory = val
         else:
             query_items.append((key, val))
     query_dict.load(query_items)
     return attr.evolve(self,
                        query_dict=query_dict,
                        subdirectory=subdirectory,
                        query=query)
Пример #14
0
 def _parse_auth(self):
     # type: () -> URI
     if self._auth:
         username, _, password = self._auth.partition(":")
         username_is_quoted, password_is_quoted = False, False
         quoted_username, quoted_password = "", ""
         if password:
             quoted_password = quote(password)
             password_is_quoted = quoted_password != password
         if username:
             quoted_username = quote(username)
             username_is_quoted = quoted_username != username
         return attr.evolve(
             self,
             username=quoted_username,
             password=quoted_password,
             username_is_quoted=username_is_quoted,
             password_is_quoted=password_is_quoted,
         )
     return self
Пример #15
0
 def get_dependencies(self):
     # type: () -> Tuple["ReleaseUrl", Dict[str, Union[List[str], str]]]
     results = {"requires_python": None}
     requires_dist = []  # type: List[str]
     if self.is_wheel:
         metadata = get_remote_wheel_metadata(self.url)
         if metadata is not None:
             requires_dist = metadata.run_requires
             if not self.requires_python:
                 results["requires_python"] = metadata._legacy.get("Requires-Python")
     else:
         try:
             metadata = get_remote_sdist_metadata(self.pep508_url)
         except Exception:
             requires_dist = []
         else:
             requires_dist = [str(v) for v in metadata.requires.values()]
     results["requires_dist"] = requires_dist
     requires_python = getattr(self, "requires_python", results["requires_python"])
     return attr.evolve(self, requires_python=requires_python), results
Пример #16
0
 def _run_setup(self):
     # type: () -> "SystemPath"
     if not self.__class__ == SystemPath:
         return self
     new_instance = self
     path_order = new_instance.path_order[:]
     path_entries = self.paths.copy()
     if self.global_search and "PATH" in os.environ:
         path_order = path_order + os.environ["PATH"].split(os.pathsep)
     path_order = list(dedup(path_order))
     path_instances = [
         ensure_path(p.strip('"'))
         for p in path_order
         if not any(
             is_in_path(normalize_path(str(p)), normalize_path(shim))
             for shim in SHIM_PATHS
         )
     ]
     path_entries.update(
         {
             p.as_posix(): PathEntry.create(
                 path=p.absolute(), is_root=True, only_python=self.only_python
             )
             for p in path_instances
             if p.exists()
         }
     )
     new_instance = attr.evolve(
         new_instance,
         path_order=[p.as_posix() for p in path_instances if p.exists()],
         paths=path_entries,
     )
     if os.name == "nt" and "windows" not in self.finders:
         new_instance = new_instance._setup_windows()
     #: slice in pyenv
     if self.check_for_pyenv() and "pyenv" not in self.finders:
         new_instance = new_instance._setup_pyenv()
     #: slice in asdf
     if self.check_for_asdf() and "asdf" not in self.finders:
         new_instance = new_instance._setup_asdf()
     venv = os.environ.get("VIRTUAL_ENV")
     if os.name == "nt":
         bin_dir = "Scripts"
     else:
         bin_dir = "bin"
     if venv and (new_instance.system or new_instance.global_search):
         p = ensure_path(venv)
         path_order = [(p / bin_dir).as_posix()] + new_instance.path_order
         new_instance = attr.evolve(new_instance, path_order=path_order)
         paths = new_instance.paths.copy()
         paths[p] = new_instance.get_path(p.joinpath(bin_dir))
         new_instance = attr.evolve(new_instance, paths=paths)
     if new_instance.system:
         syspath = Path(sys.executable)
         syspath_bin = syspath.parent
         if syspath_bin.name != bin_dir and syspath_bin.joinpath(bin_dir).exists():
             syspath_bin = syspath_bin / bin_dir
         path_order = [syspath_bin.as_posix()] + new_instance.path_order
         paths = new_instance.paths.copy()
         paths[syspath_bin] = PathEntry.create(
             path=syspath_bin, is_root=True, only_python=False
         )
         new_instance = attr.evolve(new_instance, path_order=path_order, paths=paths)
     return new_instance
Пример #17
0
 def add_parent(self, parent):
     # type: ("Dependency") -> "Dependency"
     return attr.evolve(self, parent=parent)