From 23ab63e2f36dec54cf8c98e8c24e1dff3b91e4e4 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:18:47 +0530 Subject: [PATCH 01/10] Import FormatControl more directly --- src/pip/_internal/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/cache.py b/src/pip/_internal/cache.py index 8ebecbbd5..c5431e14d 100644 --- a/src/pip/_internal/cache.py +++ b/src/pip/_internal/cache.py @@ -20,7 +20,7 @@ from pip._internal.wheel import InvalidWheelFilename, Wheel if MYPY_CHECK_RUNNING: from typing import Optional, Set, List, Any - from pip._internal.index import FormatControl + from pip._internal.models.format_control import FormatControl from pip._internal.pep425tags import Pep425Tag logger = logging.getLogger(__name__) From c18e912b2ac62e374feb02c2a430f95fe5b84dfc Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:21:43 +0530 Subject: [PATCH 02/10] Import InstallationCandidate more directly --- tests/unit/test_self_check_outdated.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_self_check_outdated.py b/tests/unit/test_self_check_outdated.py index e8c402247..72fa69293 100644 --- a/tests/unit/test_self_check_outdated.py +++ b/tests/unit/test_self_check_outdated.py @@ -10,7 +10,7 @@ from mock import patch from pip._vendor import pkg_resources from pip._internal import self_outdated_check -from pip._internal.index import InstallationCandidate +from pip._internal.models.candidate import InstallationCandidate from pip._internal.network.session import PipSession from pip._internal.self_outdated_check import ( SelfCheckState, From 66e9b44f15bbfc7335d05c3c7121a2e305443882 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:27:09 +0530 Subject: [PATCH 03/10] Import req_file more directly --- tests/unit/test_req_file.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit/test_req_file.py b/tests/unit/test_req_file.py index 41e07e60f..ca86a191b 100644 --- a/tests/unit/test_req_file.py +++ b/tests/unit/test_req_file.py @@ -7,7 +7,7 @@ import pytest from mock import Mock, patch from pretend import stub -import pip._internal.index +import pip._internal.req.req_file # this will be monkeypatched from pip._internal.exceptions import ( InstallationError, RequirementsFileParseError, @@ -272,7 +272,6 @@ class TestProcessLine(object): def test_nested_requirements_file(self, monkeypatch): line = '-r another_file' req = install_req_from_line('SomeProject') - import pip._internal.req.req_file def stub_parse_requirements(req_url, finder, comes_from, options, session, wheel_cache, constraint): @@ -285,7 +284,6 @@ class TestProcessLine(object): def test_nested_constraints_file(self, monkeypatch): line = '-c another_file' req = install_req_from_line('SomeProject') - import pip._internal.req.req_file def stub_parse_requirements(req_url, finder, comes_from, options, session, wheel_cache, constraint): From d766c448e1f8ce84ed757d7c49bcaa8dfcce8812 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:20:47 +0530 Subject: [PATCH 04/10] Move index interaction code into pip._internal.index Why: To better group code that handles index interactions. Renames pip._internal.{collector -> index.collector} and pip._internal.{index -> index.package_finder} --- src/pip/_internal/index/__init__.py | 2 ++ src/pip/_internal/{ => index}/collector.py | 0 src/pip/_internal/{index.py => index/package_finder.py} | 0 3 files changed, 2 insertions(+) create mode 100644 src/pip/_internal/index/__init__.py rename src/pip/_internal/{ => index}/collector.py (100%) rename src/pip/_internal/{index.py => index/package_finder.py} (100%) diff --git a/src/pip/_internal/index/__init__.py b/src/pip/_internal/index/__init__.py new file mode 100644 index 000000000..7a17b7b3b --- /dev/null +++ b/src/pip/_internal/index/__init__.py @@ -0,0 +1,2 @@ +"""Index interaction code +""" diff --git a/src/pip/_internal/collector.py b/src/pip/_internal/index/collector.py similarity index 100% rename from src/pip/_internal/collector.py rename to src/pip/_internal/index/collector.py diff --git a/src/pip/_internal/index.py b/src/pip/_internal/index/package_finder.py similarity index 100% rename from src/pip/_internal/index.py rename to src/pip/_internal/index/package_finder.py From 6ea84c6145c3795f1053e69dcb1a69e9bb3ffc40 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:28:24 +0530 Subject: [PATCH 05/10] Update docs to refer to index as a sub-package --- .../development/architecture/package-finding.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/html/development/architecture/package-finding.rst b/docs/html/development/architecture/package-finding.rst index dfbf5e7ae..d214c9b02 100644 --- a/docs/html/development/architecture/package-finding.rst +++ b/docs/html/development/architecture/package-finding.rst @@ -1,10 +1,10 @@ -Finding and choosing files (``index.py`` and ``PackageFinder``) +Finding and choosing files (``index`` and ``PackageFinder``) --------------------------------------------------------------- -The ``index.py`` module is a top-level module in pip responsible for deciding +The ``pip._internal.index`` sub-package in pip responsible for deciding what file to download and from where, given a requirement for a project. The -module's functionality is largely exposed through and coordinated by the -module's ``PackageFinder`` class. +package's functionality is largely exposed through and coordinated by the +package's ``PackageFinder`` class. .. _index-py-overview: @@ -133,8 +133,8 @@ method is the ``collect_links()`` method. The :ref:`PackageFinder ` class invokes this method as the first step of its ``find_all_candidates()`` method. -The ``LinkCollector`` class is the only class in the ``index.py`` module that -makes network requests and is the only class in the module that depends +The ``LinkCollector`` class is the only class in the ``index`` sub-package that +makes network requests and is the only class in the sub-package that depends directly on ``PipSession``, which stores pip's configuration options and state for making requests. From 2db6f428bf3770209680ba06378c133aa0d6041f Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 22:29:05 +0530 Subject: [PATCH 06/10] Update imports to {index -> index.package_finder} --- src/pip/_internal/build_env.py | 2 +- src/pip/_internal/cli/req_command.py | 2 +- src/pip/_internal/commands/list.py | 2 +- src/pip/_internal/legacy_resolve.py | 2 +- src/pip/_internal/operations/prepare.py | 2 +- src/pip/_internal/req/req_file.py | 2 +- src/pip/_internal/req/req_install.py | 2 +- src/pip/_internal/self_outdated_check.py | 2 +- tests/lib/__init__.py | 4 ++-- tests/unit/test_build_env.py | 2 +- tests/unit/test_finder.py | 2 +- tests/unit/test_index.py | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pip/_internal/build_env.py b/src/pip/_internal/build_env.py index 5e6dc4602..f55f0e6b8 100644 --- a/src/pip/_internal/build_env.py +++ b/src/pip/_internal/build_env.py @@ -23,7 +23,7 @@ from pip._internal.utils.ui import open_spinner if MYPY_CHECK_RUNNING: from typing import Tuple, Set, Iterable, Optional, List - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder logger = logging.getLogger(__name__) diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py index 203e86a49..88088b948 100644 --- a/src/pip/_internal/cli/req_command.py +++ b/src/pip/_internal/cli/req_command.py @@ -14,7 +14,7 @@ from functools import partial from pip._internal.cli.base_command import Command from pip._internal.cli.command_context import CommandContextMixIn from pip._internal.exceptions import CommandError -from pip._internal.index import PackageFinder +from pip._internal.index.package_finder import PackageFinder from pip._internal.legacy_resolve import Resolver from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.network.session import PipSession diff --git a/src/pip/_internal/commands/list.py b/src/pip/_internal/commands/list.py index 77a245b6d..cce470a60 100644 --- a/src/pip/_internal/commands/list.py +++ b/src/pip/_internal/commands/list.py @@ -12,7 +12,7 @@ from pip._vendor.six.moves import zip_longest from pip._internal.cli import cmdoptions from pip._internal.cli.req_command import IndexGroupCommand from pip._internal.exceptions import CommandError -from pip._internal.index import PackageFinder +from pip._internal.index.package_finder import PackageFinder from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.self_outdated_check import make_link_collector from pip._internal.utils.misc import ( diff --git a/src/pip/_internal/legacy_resolve.py b/src/pip/_internal/legacy_resolve.py index c24158f4d..be67bdac1 100644 --- a/src/pip/_internal/legacy_resolve.py +++ b/src/pip/_internal/legacy_resolve.py @@ -46,7 +46,7 @@ if MYPY_CHECK_RUNNING: from pip._internal.distributions import AbstractDistribution from pip._internal.network.session import PipSession - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder from pip._internal.operations.prepare import RequirementPreparer from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_set import RequirementSet diff --git a/src/pip/_internal/operations/prepare.py b/src/pip/_internal/operations/prepare.py index 73a20e319..9993f8841 100644 --- a/src/pip/_internal/operations/prepare.py +++ b/src/pip/_internal/operations/prepare.py @@ -61,7 +61,7 @@ if MYPY_CHECK_RUNNING: from mypy_extensions import TypedDict from pip._internal.distributions import AbstractDistribution - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder from pip._internal.models.link import Link from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import RequirementTracker diff --git a/src/pip/_internal/req/req_file.py b/src/pip/_internal/req/req_file.py index da75ad628..47486fa1f 100644 --- a/src/pip/_internal/req/req_file.py +++ b/src/pip/_internal/req/req_file.py @@ -36,7 +36,7 @@ if MYPY_CHECK_RUNNING: ) from pip._internal.req import InstallRequirement from pip._internal.cache import WheelCache - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder from pip._internal.network.session import PipSession ReqFileLines = Iterator[Tuple[int, Text]] diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 763a2f544..f3e5234d6 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -67,7 +67,7 @@ if MYPY_CHECK_RUNNING: ) from pip._internal.build_env import BuildEnvironment from pip._internal.cache import WheelCache - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder from pip._vendor.pkg_resources import Distribution from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.markers import Marker diff --git a/src/pip/_internal/self_outdated_check.py b/src/pip/_internal/self_outdated_check.py index 51ef3439f..c85fcc635 100644 --- a/src/pip/_internal/self_outdated_check.py +++ b/src/pip/_internal/self_outdated_check.py @@ -15,7 +15,7 @@ from pip._vendor.packaging import version as packaging_version from pip._vendor.six import ensure_binary from pip._internal.collector import LinkCollector -from pip._internal.index import PackageFinder +from pip._internal.index.package_finder import PackageFinder from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.utils.compat import WINDOWS diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index 32580739f..3e3f7e44f 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -13,8 +13,8 @@ from textwrap import dedent import pytest from scripttest import FoundDir, TestFileEnvironment -from pip._internal.collector import LinkCollector -from pip._internal.index import PackageFinder +from pip._internal.index.collector import LinkCollector +from pip._internal.index.package_finder import PackageFinder from pip._internal.locations import get_major_minor_version from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import SelectionPreferences diff --git a/tests/unit/test_build_env.py b/tests/unit/test_build_env.py index bcc241bbe..372c83556 100644 --- a/tests/unit/test_build_env.py +++ b/tests/unit/test_build_env.py @@ -23,7 +23,7 @@ def run_with_build_env(script, setup_script_contents, from pip._internal.build_env import BuildEnvironment from pip._internal.collector import LinkCollector - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import ( SelectionPreferences diff --git a/tests/unit/test_finder.py b/tests/unit/test_finder.py index 1295ff0b0..ac17cdf9d 100644 --- a/tests/unit/test_finder.py +++ b/tests/unit/test_finder.py @@ -12,7 +12,7 @@ from pip._internal.exceptions import ( BestVersionAlreadyInstalled, DistributionNotFound, ) -from pip._internal.index import ( +from pip._internal.index.package_finder import ( CandidateEvaluator, InstallationCandidate, Link, diff --git a/tests/unit/test_index.py b/tests/unit/test_index.py index 63eac97b9..fc3fa0c15 100644 --- a/tests/unit/test_index.py +++ b/tests/unit/test_index.py @@ -4,7 +4,7 @@ import pytest from pip._vendor.packaging.specifiers import SpecifierSet from pip._internal.collector import LinkCollector -from pip._internal.index import ( +from pip._internal.index.package_finder import ( CandidateEvaluator, CandidatePreferences, FormatControl, From 611fc6069b8fab73bcf7a0076b5423eae796f37e Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sun, 6 Oct 2019 23:41:01 +0530 Subject: [PATCH 07/10] Update references to collector.py --- src/pip/_internal/index/package_finder.py | 2 +- src/pip/_internal/models/link.py | 2 +- src/pip/_internal/self_outdated_check.py | 2 +- tests/unit/test_build_env.py | 2 +- tests/unit/test_collector.py | 11 ++++++----- tests/unit/test_finder.py | 5 ++++- tests/unit/test_index.py | 2 +- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/pip/_internal/index/package_finder.py b/src/pip/_internal/index/package_finder.py index 897444aae..9b338e693 100644 --- a/src/pip/_internal/index/package_finder.py +++ b/src/pip/_internal/index/package_finder.py @@ -38,7 +38,7 @@ if MYPY_CHECK_RUNNING: FrozenSet, Iterable, List, Optional, Set, Text, Tuple, Union, ) from pip._vendor.packaging.version import _BaseVersion - from pip._internal.collector import LinkCollector + from pip._internal.index.collector import LinkCollector from pip._internal.models.search_scope import SearchScope from pip._internal.req import InstallRequirement from pip._internal.pep425tags import Pep425Tag diff --git a/src/pip/_internal/models/link.py b/src/pip/_internal/models/link.py index 2d50d1798..ff808f5e9 100644 --- a/src/pip/_internal/models/link.py +++ b/src/pip/_internal/models/link.py @@ -19,7 +19,7 @@ from pip._internal.utils.urls import path_to_url, url_to_path if MYPY_CHECK_RUNNING: from typing import Optional, Text, Tuple, Union - from pip._internal.collector import HTMLPage + from pip._internal.index.collector import HTMLPage from pip._internal.utils.hashes import Hashes diff --git a/src/pip/_internal/self_outdated_check.py b/src/pip/_internal/self_outdated_check.py index c85fcc635..38f1d815f 100644 --- a/src/pip/_internal/self_outdated_check.py +++ b/src/pip/_internal/self_outdated_check.py @@ -14,7 +14,7 @@ from pip._vendor import pkg_resources from pip._vendor.packaging import version as packaging_version from pip._vendor.six import ensure_binary -from pip._internal.collector import LinkCollector +from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import SelectionPreferences diff --git a/tests/unit/test_build_env.py b/tests/unit/test_build_env.py index 372c83556..9db08a124 100644 --- a/tests/unit/test_build_env.py +++ b/tests/unit/test_build_env.py @@ -22,7 +22,7 @@ def run_with_build_env(script, setup_script_contents, import sys from pip._internal.build_env import BuildEnvironment - from pip._internal.collector import LinkCollector + from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import ( diff --git a/tests/unit/test_collector.py b/tests/unit/test_collector.py index f602c956a..cf709c99b 100644 --- a/tests/unit/test_collector.py +++ b/tests/unit/test_collector.py @@ -9,7 +9,7 @@ from mock import Mock, patch from pip._vendor import html5lib, requests from pip._vendor.six.moves.urllib import request as urllib_request -from pip._internal.collector import ( +from pip._internal.index.collector import ( HTMLPage, _clean_link, _determine_base_url, @@ -334,7 +334,7 @@ def test_get_html_page_invalid_scheme(caplog, url, vcs_scheme): assert page is None assert caplog.record_tuples == [ ( - "pip._internal.collector", + "pip._internal.index.collector", logging.DEBUG, "Cannot look at {} URL {}".format(vcs_scheme, url), ), @@ -367,7 +367,8 @@ def test_get_html_page_directory_append_index(tmpdir): session = mock.Mock(PipSession) fake_response = make_fake_html_response(expected_url) - with mock.patch("pip._internal.collector._get_html_response") as mock_func: + mock_func = mock.patch("pip._internal.index.collector._get_html_response") + with mock_func as mock_func: mock_func.return_value = fake_response actual = _get_html_page(Link(dir_url), session=session) assert mock_func.mock_calls == [ @@ -434,7 +435,7 @@ def check_links_include(links, names): class TestLinkCollector(object): - @patch('pip._internal.collector._get_html_response') + @patch('pip._internal.index.collector._get_html_response') def test_collect_links(self, mock_get_html_response, caplog, data): caplog.set_level(logging.DEBUG) @@ -474,5 +475,5 @@ class TestLinkCollector(object): 1 location(s) to search for versions of twine: * https://pypi.org/simple/twine/""") assert caplog.record_tuples == [ - ('pip._internal.collector', logging.DEBUG, expected_message), + ('pip._internal.index.collector', logging.DEBUG, expected_message), ] diff --git a/tests/unit/test_finder.py b/tests/unit/test_finder.py index ac17cdf9d..e7bf13e02 100644 --- a/tests/unit/test_finder.py +++ b/tests/unit/test_finder.py @@ -62,7 +62,10 @@ def test_no_partial_name_match(data): def test_tilde(): """Finder can accept a path with ~ in it and will normalize it.""" - with patch('pip._internal.collector.os.path.exists', return_value=True): + patched_exists = patch( + 'pip._internal.index.collector.os.path.exists', return_value=True + ) + with patched_exists: finder = make_test_finder(find_links=['~/python-pkgs']) req = install_req_from_line("gmpy") with pytest.raises(DistributionNotFound): diff --git a/tests/unit/test_index.py b/tests/unit/test_index.py index fc3fa0c15..bc86398ee 100644 --- a/tests/unit/test_index.py +++ b/tests/unit/test_index.py @@ -3,7 +3,7 @@ import logging import pytest from pip._vendor.packaging.specifiers import SpecifierSet -from pip._internal.collector import LinkCollector +from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import ( CandidateEvaluator, CandidatePreferences, From 3846da7f713b32a698e007d4abe3e12f53998064 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 8 Oct 2019 08:22:00 +0530 Subject: [PATCH 08/10] Update docs/html/development/architecture/package-finding.rst Co-Authored-By: Ellen Marie Dash --- docs/html/development/architecture/package-finding.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/html/development/architecture/package-finding.rst b/docs/html/development/architecture/package-finding.rst index d214c9b02..153b917af 100644 --- a/docs/html/development/architecture/package-finding.rst +++ b/docs/html/development/architecture/package-finding.rst @@ -1,7 +1,7 @@ Finding and choosing files (``index`` and ``PackageFinder``) --------------------------------------------------------------- -The ``pip._internal.index`` sub-package in pip responsible for deciding +The ``pip._internal.index`` sub-package in pip is responsible for deciding what file to download and from where, given a requirement for a project. The package's functionality is largely exposed through and coordinated by the package's ``PackageFinder`` class. From 2399a26cb16f1d75b8a904674f1289e44e14cb8f Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sat, 19 Oct 2019 22:29:19 +0530 Subject: [PATCH 09/10] Remove remaining references to index.py --- docs/html/development/architecture/package-finding.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/html/development/architecture/package-finding.rst b/docs/html/development/architecture/package-finding.rst index 153b917af..221af9405 100644 --- a/docs/html/development/architecture/package-finding.rst +++ b/docs/html/development/architecture/package-finding.rst @@ -38,7 +38,7 @@ file to download for a package, given a requirement: ` class). The remainder of this section is organized by documenting some of the -classes inside ``index.py``, in the following order: +classes inside the ``index`` package, in the following order: * the main :ref:`PackageFinder ` class, * the :ref:`LinkCollector ` class, @@ -54,7 +54,7 @@ The ``PackageFinder`` class *************************** The ``PackageFinder`` class is the primary way through which code in pip -interacts with ``index.py``. It is an umbrella class that encapsulates and +interacts with ``index`` package. It is an umbrella class that encapsulates and groups together various package-finding functionality. The ``PackageFinder`` class is responsible for searching the network and file From 6d96b85388a9bcc3c087abf5b6f8a7c943cced9b Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sat, 19 Oct 2019 22:31:45 +0530 Subject: [PATCH 10/10] Update the URL fragment to not include "py" I'm making this change since it's unlikely that folks would've linked to this specific section, and if they did, this isn't exactly user facing documentation, so I wouldn't hold this to the same standard. --- docs/html/development/architecture/package-finding.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/html/development/architecture/package-finding.rst b/docs/html/development/architecture/package-finding.rst index 221af9405..53ece59f8 100644 --- a/docs/html/development/architecture/package-finding.rst +++ b/docs/html/development/architecture/package-finding.rst @@ -7,7 +7,7 @@ package's functionality is largely exposed through and coordinated by the package's ``PackageFinder`` class. -.. _index-py-overview: +.. _index-overview: Overview ******** @@ -89,7 +89,7 @@ case, the ``PackageFinder`` instance is created by the ``self_outdated_check.py`` module's ``pip_self_version_check()`` function. The ``PackageFinder`` class is responsible for doing all of the things listed -in the :ref:`Overview ` section like fetching and parsing +in the :ref:`Overview ` section like fetching and parsing `PEP 503`_ simple repository HTML pages, evaluating which links in the simple repository pages are relevant for each requirement, and further filtering and sorting by preference the candidates for install coming from the relevant @@ -105,7 +105,7 @@ One of ``PackageFinder``'s main top-level methods is :ref:`LinkEvaluator ` object to filter out some of those links, and then returns a list of ``InstallationCandidates`` (aka candidates for install). This corresponds to steps 1-3 of the - :ref:`Overview ` above. + :ref:`Overview ` above. 2. Constructs a ``CandidateEvaluator`` object and uses that to determine the best candidate. It does this by calling the ``CandidateEvaluator`` class's ``compute_best_candidate()`` method on the return value of