1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Add --use-deprecated=backtrack-on-build-failures

This serves as an opt-out from build failures causing the entire
installation to abort.
This commit is contained in:
Pradyun Gedam 2021-12-12 13:00:51 +00:00
parent ca78aba456
commit 9d0db8839f
No known key found for this signature in database
GPG key ID: FF99710C4332258E
7 changed files with 68 additions and 1 deletions

View file

@ -964,7 +964,7 @@ use_deprecated_feature: Callable[..., Option] = partial(
metavar="feature",
action="append",
default=[],
choices=["legacy-resolver", "out-of-tree-build"],
choices=["legacy-resolver", "out-of-tree-build", "backtrack-on-build-failures"],
help=("Enable deprecated functionality, that will be removed in the future."),
)

View file

@ -227,6 +227,31 @@ class RequirementCommand(IndexGroupCommand):
return "2020-resolver"
@staticmethod
def determine_build_failure_suppression(options: Values) -> bool:
"""Determines whether build failures should be suppressed and backtracked on."""
if "backtrack-on-build-failures" not in options.deprecated_features_enabled:
return False
if "legacy-resolver" in options.deprecated_features_enabled:
raise CommandError("Cannot backtrack with legacy resolver.")
deprecated(
reason=(
"Backtracking on build failures can mask issues related to how "
"a package generates metadata or builds a wheel. This flag will "
"be removed in pip 22.2."
),
gone_in=None,
replacement=(
"avoiding known-bad versions by explicitly telling pip to ignore them "
"(either directly as requirements, or via a constraints file)"
),
feature_flag=None,
issue=10655,
)
return True
@classmethod
def make_requirement_preparer(
cls,
@ -323,6 +348,7 @@ class RequirementCommand(IndexGroupCommand):
isolated=options.isolated_mode,
use_pep517=use_pep517,
)
suppress_build_failures = cls.determine_build_failure_suppression(options)
resolver_variant = cls.determine_resolver_variant(options)
# The long import name and duplicated invocation is needed to convince
# Mypy into correctly typechecking. Otherwise it would complain the
@ -342,6 +368,7 @@ class RequirementCommand(IndexGroupCommand):
force_reinstall=force_reinstall,
upgrade_strategy=upgrade_strategy,
py_version_info=py_version_info,
suppress_build_failures=suppress_build_failures,
)
import pip._internal.resolution.legacy.resolver

View file

@ -27,6 +27,7 @@ from pip._internal.cache import CacheEntry, WheelCache
from pip._internal.exceptions import (
DistributionNotFound,
InstallationError,
InstallationSubprocessError,
MetadataInconsistent,
UnsupportedPythonVersion,
UnsupportedWheel,
@ -96,6 +97,7 @@ class Factory:
force_reinstall: bool,
ignore_installed: bool,
ignore_requires_python: bool,
suppress_build_failures: bool,
py_version_info: Optional[Tuple[int, ...]] = None,
) -> None:
self._finder = finder
@ -106,6 +108,7 @@ class Factory:
self._use_user_site = use_user_site
self._force_reinstall = force_reinstall
self._ignore_requires_python = ignore_requires_python
self._suppress_build_failures = suppress_build_failures
self._build_failures: Cache[InstallationError] = {}
self._link_candidate_cache: Cache[LinkCandidate] = {}
@ -198,6 +201,13 @@ class Factory:
)
self._build_failures[link] = e
return None
except InstallationSubprocessError as e:
if not self._suppress_build_failures:
raise
logger.warning("Discarding %s due to build failure: %s", link, e)
self._build_failures[link] = e
return None
base: BaseCandidate = self._editable_candidate_cache[link]
else:
if link not in self._link_candidate_cache:
@ -218,6 +228,12 @@ class Factory:
)
self._build_failures[link] = e
return None
except InstallationSubprocessError as e:
if not self._suppress_build_failures:
raise
logger.warning("Discarding %s due to build failure: %s", link, e)
self._build_failures[link] = e
return None
base = self._link_candidate_cache[link]
if not extras:

View file

@ -47,6 +47,7 @@ class Resolver(BaseResolver):
ignore_requires_python: bool,
force_reinstall: bool,
upgrade_strategy: str,
suppress_build_failures: bool,
py_version_info: Optional[Tuple[int, ...]] = None,
):
super().__init__()
@ -61,6 +62,7 @@ class Resolver(BaseResolver):
force_reinstall=force_reinstall,
ignore_installed=ignore_installed,
ignore_requires_python=ignore_requires_python,
suppress_build_failures=suppress_build_failures,
py_version_info=py_version_info,
)
self.ignore_dependencies = ignore_dependencies

View file

@ -2329,6 +2329,26 @@ def test_new_resolver_do_not_backtrack_on_build_failure(
assert "egg_info" in result.stderr
def test_new_resolver_flag_permits_backtracking_on_build_failure(
script: PipTestEnvironment,
) -> None:
create_basic_sdist_for_package(script, "pkg1", "2.0", fails_egg_info=True)
create_basic_wheel_for_package(script, "pkg1", "1.0")
script.pip(
"install",
"--use-deprecated=backtrack-on-build-failures",
"--no-cache-dir",
"--no-index",
"--find-links",
script.scratch_path,
"pkg1",
allow_stderr_warning=True,
)
script.assert_installed(pkg1="1.0")
def test_new_resolver_works_when_failing_package_builds_are_disallowed(
script: PipTestEnvironment,
) -> None:

View file

@ -63,6 +63,7 @@ def factory(finder: PackageFinder, preparer: RequirementPreparer) -> Iterator[Fa
force_reinstall=False,
ignore_installed=False,
ignore_requires_python=False,
suppress_build_failures=False,
py_version_info=None,
)

View file

@ -29,6 +29,7 @@ def resolver(preparer: RequirementPreparer, finder: PackageFinder) -> Resolver:
ignore_requires_python=False,
force_reinstall=False,
upgrade_strategy="to-satisfy-only",
suppress_build_failures=False,
)
return resolver