Пример #1
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet
        """Resolve what operations need to be done

        As a side-effect of this method, the packages (and their dependencies)
        are downloaded, unpacked and prepared for installation. This
        preparation is done by ``pip.operations.prepare``.

        Once PyPI has static dependency metadata available, it would be
        possible to move the preparation to become a step separated from
        dependency resolution.
        """
        requirement_set = RequirementSet(check_supported_wheels=check_supported_wheels)
        for req in root_reqs:
            if req.constraint:
                check_invalid_constraint_type(req)
            requirement_set.add_requirement(req)

        # Actually prepare the files, and collect any exceptions. Most hash
        # exceptions cannot be checked ahead of time, because
        # _populate_link() needs to be called before we can make decisions
        # based on link type.
        discovered_reqs = []  # type: List[InstallRequirement]
        hash_errors = HashErrors()
        for req in chain(requirement_set.all_requirements, discovered_reqs):
            try:
                discovered_reqs.extend(self._resolve_one(requirement_set, req))
            except HashError as exc:
                exc.req = req
                hash_errors.append(exc)

        if hash_errors:
            raise hash_errors

        return requirement_set
Пример #2
0
 def collect_root_requirements(
         self,
         root_ireqs: List[InstallRequirement]) -> CollectedRootRequirements:
     collected = CollectedRootRequirements([], {}, {})
     for i, ireq in enumerate(root_ireqs):
         if ireq.constraint:
             # Ensure we only accept valid constraints
             problem = check_invalid_constraint_type(ireq)
             if problem:
                 raise InstallationError(problem)
             if not ireq.match_markers():
                 continue
             assert ireq.name, "Constraint must be named"
             name = canonicalize_name(ireq.name)
             if name in collected.constraints:
                 collected.constraints[name] &= ireq
             else:
                 collected.constraints[name] = Constraint.from_ireq(ireq)
         else:
             req = self._make_requirement_from_install_req(
                 ireq,
                 requested_extras=(),
             )
             if req is None:
                 continue
             if ireq.user_supplied and req.name not in collected.user_requested:
                 collected.user_requested[req.name] = i
             collected.requirements.append(req)
     return collected
Пример #3
0
    def resolve(self, root_reqs, check_supported_wheels):

        # type: (List[InstallRequirement], bool) -> RequirementSet

        constraints = {}  # type: Dict[str, Constraint]

        user_requested = set()  # type: Set[str]

        requirements = []

        for req in root_reqs:

            if req.constraint:

                # Ensure we only accept valid constraints

                problem = check_invalid_constraint_type(req)

                if problem:

                    raise InstallationError(problem)

                if not req.match_markers():

                    continue

                name = canonicalize_name(req.name)

                if name in constraints:

                    constraints[name] &= req

                else:

                    constraints[name] = Constraint.from_ireq(req)

            else:

                if req.user_supplied and req.name:

                    user_requested.add(canonicalize_name(req.name))

                r = self.factory.make_requirement_from_install_req(
                    req,
                    requested_extras=(),
                )

                if r is not None:

                    requirements.append(r)

        provider = PipProvider(
            factory=self.factory,
            constraints=constraints,
            ignore_dependencies=self.ignore_dependencies,
            upgrade_strategy=self.upgrade_strategy,
            user_requested=user_requested,
        )

        if "PIP_RESOLVER_DEBUG" in os.environ:

            reporter = PipDebuggingReporter()

        else:

            reporter = PipReporter()

        resolver = RLResolver(provider, reporter)

        try:

            try_to_avoid_resolution_too_deep = 2000000

            self._result = resolver.resolve(
                requirements,
                max_rounds=try_to_avoid_resolution_too_deep,
            )

        except ResolutionImpossible as e:

            error = self.factory.get_installation_error(e)

            six.raise_from(error, e)

        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)

        for candidate in self._result.mapping.values():

            ireq = candidate.get_install_requirement()

            if ireq is None:

                continue

            # Check if there is already an installation under the same name,

            # and set a flag for later stages to uninstall it, if needed.

            installed_dist = self.factory.get_dist_to_uninstall(candidate)

            if installed_dist is None:

                # There is no existing installation -- nothing to uninstall.

                ireq.should_reinstall = False

            elif self.factory.force_reinstall:

                # The --force-reinstall flag is set -- reinstall.

                ireq.should_reinstall = True

            elif installed_dist.parsed_version != candidate.version:

                # The installation is different in version -- reinstall.

                ireq.should_reinstall = True

            elif candidate.is_editable or dist_is_editable(installed_dist):

                # The incoming distribution is editable, or different in

                # editable-ness to installation -- reinstall.

                ireq.should_reinstall = True

            elif candidate.source_link.is_file:

                # The incoming distribution is under file://

                if candidate.source_link.is_wheel:

                    # is a local wheel -- do nothing.

                    logger.info(
                        "%s is already installed with the same version as the "
                        "provided wheel. Use --force-reinstall to force an "
                        "installation of the wheel.",
                        ireq.name,
                    )

                    continue

                looks_like_sdist = (is_archive_file(
                    candidate.source_link.file_path)
                                    and candidate.source_link.ext != ".zip")

                if looks_like_sdist:

                    # is a local sdist -- show a deprecation warning!

                    reason = (
                        "Source distribution is being reinstalled despite an "
                        "installed package having the same name and version as "
                        "the installed package.")

                    replacement = "use --force-reinstall"

                    deprecated(
                        reason=reason,
                        replacement=replacement,
                        gone_in="21.1",
                        issue=8711,
                    )

                # is a local sdist or path -- reinstall

                ireq.should_reinstall = True

            else:

                continue

            link = candidate.source_link

            if link and link.is_yanked:

                # The reason can contain non-ASCII characters, Unicode

                # is required for Python 2.

                msg = ('The candidate selected for download or install is a '
                       'yanked version: {name!r} candidate (version {version} '
                       'at {link})\nReason for being yanked: {reason}').format(
                           name=candidate.name,
                           version=candidate.version,
                           link=link,
                           reason=link.yanked_reason or '<none given>',
                       )

                logger.warning(msg)

            req_set.add_named_requirement(ireq)

        reqs = req_set.all_requirements

        self.factory.preparer.prepare_linked_requirements_more(reqs)

        return req_set
Пример #4
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet

        constraints = {}  # type: Dict[str, SpecifierSet]
        user_requested = set()  # type: Set[str]
        requirements = []
        for req in root_reqs:
            if req.constraint:
                # Ensure we only accept valid constraints
                problem = check_invalid_constraint_type(req)
                if problem:
                    raise InstallationError(problem)
                if not req.match_markers():
                    continue
                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] = constraints[name] & req.specifier
                else:
                    constraints[name] = req.specifier
            else:
                if req.user_supplied and req.name:
                    user_requested.add(canonicalize_name(req.name))
                r = self.factory.make_requirement_from_install_req(
                    req,
                    requested_extras=(),
                )
                if r is not None:
                    requirements.append(r)

        provider = PipProvider(
            factory=self.factory,
            constraints=constraints,
            ignore_dependencies=self.ignore_dependencies,
            upgrade_strategy=self.upgrade_strategy,
            user_requested=user_requested,
        )
        reporter = BaseReporter()
        resolver = RLResolver(provider, reporter)

        try:
            try_to_avoid_resolution_too_deep = 2000000
            self._result = resolver.resolve(
                requirements,
                max_rounds=try_to_avoid_resolution_too_deep,
            )

        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(e)
            six.raise_from(error, e)

        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
        for candidate in self._result.mapping.values():
            ireq = candidate.get_install_requirement()
            if ireq is None:
                continue

            # Check if there is already an installation under the same name,
            # and set a flag for later stages to uninstall it, if needed.
            # * There isn't, good -- no uninstalltion needed.
            # * The --force-reinstall flag is set. Always reinstall.
            # * The installation is different in version or editable-ness, so
            #   we need to uninstall it to install the new distribution.
            # * The installed version is the same as the pending distribution.
            #   Skip this distrubiton altogether to save work.
            installed_dist = self.factory.get_dist_to_uninstall(candidate)
            if installed_dist is None:
                ireq.should_reinstall = False
            elif self.factory.force_reinstall:
                ireq.should_reinstall = True
            elif installed_dist.parsed_version != candidate.version:
                ireq.should_reinstall = True
            elif dist_is_editable(installed_dist) != candidate.is_editable:
                ireq.should_reinstall = True
            else:
                continue

            link = candidate.source_link
            if link and link.is_yanked:
                # The reason can contain non-ASCII characters, Unicode
                # is required for Python 2.
                msg = (
                    u'The candidate selected for download or install is a '
                    u'yanked version: {name!r} candidate (version {version} '
                    u'at {link})\nReason for being yanked: {reason}').format(
                        name=candidate.name,
                        version=candidate.version,
                        link=link,
                        reason=link.yanked_reason or u'<none given>',
                    )
                logger.warning(msg)

            req_set.add_named_requirement(ireq)

        return req_set
Пример #5
0
        self._result = None  # type: Optional[Result]

    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet

<<<<<<< HEAD
        constraints = {}  # type: Dict[str, Constraint]
=======
        constraints = {}  # type: Dict[str, SpecifierSet]
>>>>>>> 74c061954d5e927be4caafbd793e96a50563c265
        user_requested = set()  # type: Set[str]
        requirements = []
        for req in root_reqs:
            if req.constraint:
                # Ensure we only accept valid constraints
                problem = check_invalid_constraint_type(req)
                if problem:
                    raise InstallationError(problem)
<<<<<<< HEAD
                if not req.match_markers():
                    continue
                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] &= req
                else:
                    constraints[name] = Constraint.from_ireq(req)
=======

                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] = constraints[name] & req.specifier
Пример #6
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet

        constraints = {}  # type: Dict[str, SpecifierSet]
        user_requested = set()  # type: Set[str]
        requirements = []
        for req in root_reqs:
            if req.constraint:
                # Ensure we only accept valid constraints
                problem = check_invalid_constraint_type(req)
                if problem:
                    raise InstallationError(problem)

                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] = constraints[name] & req.specifier
                else:
                    constraints[name] = req.specifier
            else:
                if req.user_supplied and req.name:
                    user_requested.add(canonicalize_name(req.name))
                r = self.factory.make_requirement_from_install_req(
                    req, requested_extras=(),
                )
                if r is not None:
                    requirements.append(r)

        provider = PipProvider(
            factory=self.factory,
            constraints=constraints,
            ignore_dependencies=self.ignore_dependencies,
            upgrade_strategy=self.upgrade_strategy,
            user_requested=user_requested,
        )
        reporter = BaseReporter()
        resolver = RLResolver(provider, reporter)

        try:
            try_to_avoid_resolution_too_deep = 2000000
            self._result = resolver.resolve(
                requirements, max_rounds=try_to_avoid_resolution_too_deep,
            )

        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(e)
            six.raise_from(error, e)

        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
        for candidate in self._result.mapping.values():
            ireq = candidate.get_install_requirement()
            if ireq is None:
                continue
            link = candidate.source_link
            if link and link.is_yanked:
                # The reason can contain non-ASCII characters, Unicode
                # is required for Python 2.
                msg = (
                    u'The candidate selected for download or install is a '
                    u'yanked version: {name!r} candidate (version {version} '
                    u'at {link})\nReason for being yanked: {reason}'
                ).format(
                    name=candidate.name,
                    version=candidate.version,
                    link=link,
                    reason=link.yanked_reason or u'<none given>',
                )
                logger.warning(msg)
            ireq.should_reinstall = self.factory.should_reinstall(candidate)
            req_set.add_named_requirement(ireq)

        return req_set
Пример #7
0
        As a side-effect of this method, the packages (and their dependencies)
        are downloaded, unpacked and prepared for installation. This
        preparation is done by ``pip.operations.prepare``.

        Once PyPI has static dependency metadata available, it would be
        possible to move the preparation to become a step separated from
        dependency resolution.
        """
        requirement_set = RequirementSet(
            check_supported_wheels=check_supported_wheels
        )
        for req in root_reqs:
<<<<<<< HEAD
            if req.constraint:
                check_invalid_constraint_type(req)
=======
>>>>>>> b66a76afa15ab74019740676a52a071b85ed8f71
            requirement_set.add_requirement(req)

        # Actually prepare the files, and collect any exceptions. Most hash
        # exceptions cannot be checked ahead of time, because
        # _populate_link() needs to be called before we can make decisions
        # based on link type.
        discovered_reqs = []  # type: List[InstallRequirement]
        hash_errors = HashErrors()
<<<<<<< HEAD
        for req in chain(requirement_set.all_requirements, discovered_reqs):
=======
        for req in chain(root_reqs, discovered_reqs):
>>>>>>> b66a76afa15ab74019740676a52a071b85ed8f71