summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzu-ping Chung <uranusjr@gmail.com>2020-12-12 18:49:14 +0800
committerTzu-ping Chung <uranusjr@gmail.com>2020-12-12 18:49:14 +0800
commitd869e0cbfda75bc63b0e77d6549f7d7c77478d0f (patch)
treee672e91d915cce4798417273c20dbdc91067de7d
parentb2c04877fa145894579af423f3088b300f74877c (diff)
parent0aee48ff1fbc0d60cd973c6929d9afb2bc32b839 (diff)
downloadpip-d869e0cbfda75bc63b0e77d6549f7d7c77478d0f.tar.gz
Merge master
-rw-r--r--news/9117.bugfix.rst2
-rw-r--r--news/9249.feature.rst1
-rw-r--r--src/pip/_internal/resolution/resolvelib/factory.py10
-rw-r--r--src/pip/_internal/resolution/resolvelib/provider.py13
4 files changed, 23 insertions, 3 deletions
diff --git a/news/9117.bugfix.rst b/news/9117.bugfix.rst
new file mode 100644
index 000000000..7991dac7d
--- /dev/null
+++ b/news/9117.bugfix.rst
@@ -0,0 +1,2 @@
+New resolver: The "Requirement already satisfied" log is not printed only once
+for each package during resolution.
diff --git a/news/9249.feature.rst b/news/9249.feature.rst
new file mode 100644
index 000000000..1c56b39ef
--- /dev/null
+++ b/news/9249.feature.rst
@@ -0,0 +1 @@
+Add a mechanism to delay resolving certain packages, and use it for setuptools.
diff --git a/src/pip/_internal/resolution/resolvelib/factory.py b/src/pip/_internal/resolution/resolvelib/factory.py
index c7fb4f3f0..35345c5f0 100644
--- a/src/pip/_internal/resolution/resolvelib/factory.py
+++ b/src/pip/_internal/resolution/resolvelib/factory.py
@@ -97,9 +97,11 @@ class Factory(object):
self._force_reinstall = force_reinstall
self._ignore_requires_python = ignore_requires_python
+ self._build_failures = {} # type: Cache[InstallationError]
self._link_candidate_cache = {} # type: Cache[LinkCandidate]
self._editable_candidate_cache = {} # type: Cache[EditableCandidate]
- self._build_failures = {} # type: Cache[InstallationError]
+ self._installed_candidate_cache = {
+ } # type: Dict[str, AlreadyInstalledCandidate]
if not ignore_installed:
self._installed_dists = {
@@ -121,7 +123,11 @@ class Factory(object):
template, # type: InstallRequirement
):
# type: (...) -> Candidate
- base = AlreadyInstalledCandidate(dist, template, factory=self)
+ try:
+ base = self._installed_candidate_cache[dist.key]
+ except KeyError:
+ base = AlreadyInstalledCandidate(dist, template, factory=self)
+ self._installed_candidate_cache[dist.key] = base
if extras:
return ExtrasCandidate(base, extras)
return base
diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py
index 3883135f1..40a641a2a 100644
--- a/src/pip/_internal/resolution/resolvelib/provider.py
+++ b/src/pip/_internal/resolution/resolvelib/provider.py
@@ -117,7 +117,18 @@ class PipProvider(AbstractProvider):
restrictive = _get_restrictive_rating(req for req, _ in information)
transitive = all(parent is not None for _, parent in information)
key = next(iter(candidates)).name if candidates else ""
- return (restrictive, transitive, key)
+
+ # HACK: Setuptools have a very long and solid backward compatibility
+ # track record, and extremely few projects would request a narrow,
+ # non-recent version range of it since that would break a lot things.
+ # (Most projects specify it only to request for an installer feature,
+ # which does not work, but that's another topic.) Intentionally
+ # delaying Setuptools helps reduce branches the resolver has to check.
+ # This serves as a temporary fix for issues like "apache-airlfow[all]"
+ # while we work on "proper" branch pruning techniques.
+ delay_this = (key == "setuptools")
+
+ return (delay_this, restrictive, transitive, key)
def find_matches(self, requirements):
# type: (Sequence[Requirement]) -> Iterable[Candidate]