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

        # FIXME: Implement constraints.
        if any(r.constraint for r in root_reqs):
            raise InstallationError("Constraints are not yet supported.")

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

        requirements = [
            self.factory.make_requirement_from_install_req(r)
            for r in root_reqs
        ]

        try:
            self._result = resolver.resolve(requirements)

        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(e)
            if not error:
                # TODO: This needs fixing, we need to look at the
                # factory.get_installation_error infrastructure, as that
                # doesn't really allow for the logger.critical calls I'm
                # using here.
                for req, parent in e.causes:
                    logger.critical(
                        "Could not find a version that satisfies " +
                        "the requirement " +
                        str(req) +
                        ("" if parent is None else " (from {})".format(
                            parent.name
                        ))
                    )
                raise InstallationError(
                    "No matching distribution found for " +
                    ", ".join([r.name for r, _ in e.causes])
                )
                raise
            six.raise_from(error, e)

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

        return req_set
Пример #2
0
def provider(factory):
    yield PipProvider(
        factory=factory,
        constraints={},
        ignore_dependencies=False,
        upgrade_strategy="to-satisfy-only",
        user_requested=set(),
    )
Пример #3
0
def provider(finder, preparer):
    make_install_req = partial(
        install_req_from_req_string,
        isolated=False,
        wheel_cache=None,
        use_pep517=None,
    )
    yield PipProvider(finder, preparer, make_install_req)
Пример #4
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet
        provider = PipProvider(
            factory=self.factory,
            ignore_dependencies=self.ignore_dependencies,
        )
        reporter = BaseReporter()
        resolver = RLResolver(provider, reporter)

        requirements = [self.factory.make_requirement(r) for r in root_reqs]
        self._result = resolver.resolve(requirements)

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

        return req_set
Пример #5
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet
        provider = PipProvider(
            self.finder,
            self.preparer,
            self.make_install_req,
        )
        reporter = BaseReporter()
        resolver = RLResolver(provider, reporter)

        requirements = [provider.make_requirement(r) for r in root_reqs]
        self._result = resolver.resolve(requirements)

        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
        for candidate in self._result.mapping.values():
            ireq = provider.get_install_requirement(candidate)
            req_set.add_named_requirement(ireq)

        return req_set
Пример #6
0
def provider(finder, preparer):
    make_install_req = partial(
        install_req_from_req_string,
        isolated=False,
        wheel_cache=None,
        use_pep517=None,
    )
    yield PipProvider(
        finder=finder,
        preparer=preparer,
        ignore_dependencies=False,
        make_install_req=make_install_req,
    )
Пример #7
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet

        # FIXME: Implement constraints.
        if any(r.constraint for r in root_reqs):
            raise InstallationError("Constraints are not yet supported.")

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

        requirements = [
            self.factory.make_requirement_from_install_req(r)
            for r in root_reqs
        ]

        try:
            self._result = resolver.resolve(requirements)
        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(e)
            if not error:
                raise
            six.raise_from(error, e)

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

        return req_set
Пример #8
0
def test_provider_known_depths(factory: Factory) -> None:
    # Root requirement is specified by the user
    # therefore has an infered depth of 1
    root_requirement_name = "my-package"
    provider = PipProvider(
        factory=factory,
        constraints={},
        ignore_dependencies=False,
        upgrade_strategy="to-satisfy-only",
        user_requested={root_requirement_name: 0},
    )

    root_requirement_information = build_requirement_information(
        name=root_requirement_name, parent=None)
    provider.get_preference(
        identifier=root_requirement_name,
        resolutions={},
        candidates={},
        information={root_requirement_name: root_requirement_information},
        backtrack_causes=[],
    )
    assert provider._known_depths == {root_requirement_name: 1.0}

    # Transative requirement is a dependency of root requirement
    # theforefore has an infered depth of 2
    root_package_candidate = InstallationCandidate(
        root_requirement_name,
        "1.0",
        Link("https://{root_requirement_name}.com"),
    )
    transative_requirement_name = "my-transitive-package"

    transative_package_information = build_requirement_information(
        name=transative_requirement_name, parent=root_package_candidate)
    provider.get_preference(
        identifier=transative_requirement_name,
        resolutions={},
        candidates={},
        information={
            root_requirement_name: root_requirement_information,
            transative_requirement_name: transative_package_information,
        },
        backtrack_causes=[],
    )
    assert provider._known_depths == {
        transative_requirement_name: 2.0,
        root_requirement_name: 1.0,
    }
Пример #9
0
def provider(factory):
    yield PipProvider(
        factory=factory,
        ignore_dependencies=False,
    )
Пример #10
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
Пример #11
0
    def resolve(
        self, root_reqs: List[InstallRequirement], check_supported_wheels: bool
    ) -> RequirementSet:
        collected = self.factory.collect_root_requirements(root_reqs)
        provider = PipProvider(
            factory=self.factory,
            constraints=collected.constraints,
            ignore_dependencies=self.ignore_dependencies,
            upgrade_strategy=self.upgrade_strategy,
            user_requested=collected.user_requested,
        )
        if "PIP_RESOLVER_DEBUG" in os.environ:
            reporter: BaseReporter = PipDebuggingReporter()
        else:
            reporter = PipReporter()
        resolver: RLResolver[Requirement, Candidate, str] = RLResolver(
            provider,
            reporter,
        )

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

        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(
                cast("ResolutionImpossible[Requirement, Candidate]", e),
                collected.constraints,
            )
            raise error from e

        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)
        for candidate in 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 parse_version(installed_dist.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 and 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.2",
                        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
Пример #12
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
Пример #13
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 not req.match_markers():
                continue
            if req.constraint:
                # Ensure we only accept valid constraints
                reject_invalid_constraint_types(req)

                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] = constraints[name] & req.specifier
                else:
                    constraints[name] = req.specifier
            else:
                if req.is_direct and req.name:
                    user_requested.add(canonicalize_name(req.name))
                requirements.append(
                    self.factory.make_requirement_from_install_req(req))

        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)
            if not error:
                # TODO: This needs fixing, we need to look at the
                # factory.get_installation_error infrastructure, as that
                # doesn't really allow for the logger.critical calls I'm
                # using here.
                for req, parent in e.causes:
                    logger.critical(
                        "Could not find a version that satisfies " +
                        "the requirement " + str(req) +
                        ("" if parent is None else " (from {})".format(parent.
                                                                       name)))
                raise DistributionNotFound(
                    "No matching distribution found for " +
                    ", ".join([r.name for r, _ in e.causes]))
            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
            ireq.should_reinstall = self.factory.should_reinstall(candidate)
            req_set.add_named_requirement(ireq)

        return req_set
Пример #14
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
                reject_invalid_constraint_types(req)

                name = canonicalize_name(req.name)
                if name in constraints:
                    constraints[name] = constraints[name] & req.specifier
                else:
                    constraints[name] = req.specifier
            else:
                if req.is_direct 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
Пример #15
0
    def resolve(self, root_reqs, check_supported_wheels):
        # type: (List[InstallRequirement], bool) -> RequirementSet

        # The factory should not have retained state from any previous usage.
        # In theory this could only happen if self was reused to do a second
        # resolve, which isn't something we do at the moment. We assert here
        # in order to catch the issue if that ever changes.
        # The persistent state that we care about is `root_reqs`.
        assert len(self.factory.root_reqs) == 0, "Factory is being re-used"

        # FIXME: Implement constraints.
        if any(r.constraint for r in root_reqs):
            raise InstallationError("Constraints are not yet supported.")

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

        requirements = [
            self.factory.make_requirement_from_install_req(r)
            for r in root_reqs
        ]

        try:
            self._result = resolver.resolve(requirements)

        except ResolutionImpossible as e:
            error = self.factory.get_installation_error(e)
            if not error:
                # TODO: This needs fixing, we need to look at the
                # factory.get_installation_error infrastructure, as that
                # doesn't really allow for the logger.critical calls I'm
                # using here.
                for req, parent in e.causes:
                    logger.critical(
                        "Could not find a version that satisfies " +
                        "the requirement " +
                        str(req) +
                        ("" if parent is None else " (from {})".format(
                            parent.name
                        ))
                    )
                raise InstallationError(
                    "No matching distribution found for " +
                    ", ".join([r.name for r, _ in e.causes])
                )
                raise
            six.raise_from(error, e)

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

        return req_set
Пример #16
0
def provider(factory):
    yield PipProvider(
        factory=factory,
        constraints={},
        ignore_dependencies=False,
    )