|
1 | 1 | """Routines related to PyPI, indexes"""
|
2 | 2 |
|
3 |
| -# The following comment should be removed at some point in the future. |
4 |
| -# mypy: strict-optional=False |
5 |
| - |
6 | 3 | import enum
|
7 | 4 | import functools
|
8 | 5 | import itertools
|
9 | 6 | import logging
|
10 | 7 | import re
|
11 |
| -from typing import FrozenSet, Iterable, List, Optional, Set, Tuple, Union |
| 8 | +from typing import TYPE_CHECKING, FrozenSet, Iterable, List, Optional, Set, Tuple, Union |
12 | 9 |
|
13 | 10 | from pip._vendor.packaging import specifiers
|
14 | 11 | from pip._vendor.packaging.tags import Tag
|
|
39 | 36 | from pip._internal.utils.packaging import check_requires_python
|
40 | 37 | from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS
|
41 | 38 |
|
| 39 | +if TYPE_CHECKING: |
| 40 | + from pip._vendor.typing_extensions import TypeGuard |
| 41 | + |
42 | 42 | __all__ = ["FormatControl", "BestCandidateResult", "PackageFinder"]
|
43 | 43 |
|
44 | 44 |
|
@@ -251,7 +251,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
|
251 | 251 |
|
252 | 252 | def filter_unallowed_hashes(
|
253 | 253 | candidates: List[InstallationCandidate],
|
254 |
| - hashes: Hashes, |
| 254 | + hashes: Optional[Hashes], |
255 | 255 | project_name: str,
|
256 | 256 | ) -> List[InstallationCandidate]:
|
257 | 257 | """
|
@@ -540,6 +540,7 @@ def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey:
|
540 | 540 | binary_preference = 1
|
541 | 541 | if wheel.build_tag is not None:
|
542 | 542 | match = re.match(r"^(\d+)(.*)$", wheel.build_tag)
|
| 543 | + assert match is not None, "guaranteed by filename validation" |
543 | 544 | build_tag_groups = match.groups()
|
544 | 545 | build_tag = (int(build_tag_groups[0]), build_tag_groups[1])
|
545 | 546 | else: # sdist
|
@@ -942,43 +943,46 @@ def _format_versions(cand_iter: Iterable[InstallationCandidate]) -> str:
|
942 | 943 | "No matching distribution found for {}".format(req)
|
943 | 944 | )
|
944 | 945 |
|
945 |
| - best_installed = False |
946 |
| - if installed_version and ( |
947 |
| - best_candidate is None or best_candidate.version <= installed_version |
948 |
| - ): |
949 |
| - best_installed = True |
| 946 | + def _should_install_candidate( |
| 947 | + candidate: Optional[InstallationCandidate], |
| 948 | + ) -> "TypeGuard[InstallationCandidate]": |
| 949 | + if installed_version is None: |
| 950 | + return True |
| 951 | + if best_candidate is None: |
| 952 | + return False |
| 953 | + return best_candidate.version > installed_version |
950 | 954 |
|
951 | 955 | if not upgrade and installed_version is not None:
|
952 |
| - if best_installed: |
| 956 | + if _should_install_candidate(best_candidate): |
953 | 957 | logger.debug(
|
954 |
| - "Existing installed version (%s) is most up-to-date and " |
955 |
| - "satisfies requirement", |
| 958 | + "Existing installed version (%s) satisfies requirement " |
| 959 | + "(most up-to-date version is %s)", |
956 | 960 | installed_version,
|
| 961 | + best_candidate.version, |
957 | 962 | )
|
958 | 963 | else:
|
959 | 964 | logger.debug(
|
960 |
| - "Existing installed version (%s) satisfies requirement " |
961 |
| - "(most up-to-date version is %s)", |
| 965 | + "Existing installed version (%s) is most up-to-date and " |
| 966 | + "satisfies requirement", |
962 | 967 | installed_version,
|
963 |
| - best_candidate.version, |
964 | 968 | )
|
965 | 969 | return None
|
966 | 970 |
|
967 |
| - if best_installed: |
968 |
| - # We have an existing version, and its the best version |
| 971 | + if _should_install_candidate(best_candidate): |
969 | 972 | logger.debug(
|
970 |
| - "Installed version (%s) is most up-to-date (past versions: %s)", |
971 |
| - installed_version, |
| 973 | + "Using version %s (newest of versions: %s)", |
| 974 | + best_candidate.version, |
972 | 975 | _format_versions(best_candidate_result.iter_applicable()),
|
973 | 976 | )
|
974 |
| - raise BestVersionAlreadyInstalled |
| 977 | + return best_candidate |
975 | 978 |
|
| 979 | + # We have an existing version, and its the best version |
976 | 980 | logger.debug(
|
977 |
| - "Using version %s (newest of versions: %s)", |
978 |
| - best_candidate.version, |
| 981 | + "Installed version (%s) is most up-to-date (past versions: %s)", |
| 982 | + installed_version, |
979 | 983 | _format_versions(best_candidate_result.iter_applicable()),
|
980 | 984 | )
|
981 |
| - return best_candidate |
| 985 | + raise BestVersionAlreadyInstalled |
982 | 986 |
|
983 | 987 |
|
984 | 988 | def _find_name_version_sep(fragment: str, canonical_name: str) -> int:
|
|
0 commit comments