diff --git a/news/12680.bugfix.rst b/news/12680.bugfix.rst new file mode 100644 index 00000000000..fa821f9f339 --- /dev/null +++ b/news/12680.bugfix.rst @@ -0,0 +1 @@ +Perform hash comparisons in a case-insensitive manner. diff --git a/src/pip/_internal/utils/hashes.py b/src/pip/_internal/utils/hashes.py index c073b09dd98..535e94fca0c 100644 --- a/src/pip/_internal/utils/hashes.py +++ b/src/pip/_internal/utils/hashes.py @@ -33,7 +33,7 @@ def __init__(self, hashes: Optional[Dict[str, List[str]]] = None) -> None: if hashes is not None: for alg, keys in hashes.items(): # Make sure values are always sorted (to ease equality checks) - allowed[alg] = sorted(keys) + allowed[alg] = [k.lower() for k in sorted(keys)] self._allowed = allowed def __and__(self, other: "Hashes") -> "Hashes": diff --git a/tests/functional/test_download.py b/tests/functional/test_download.py index 555a1163f42..450690c1675 100644 --- a/tests/functional/test_download.py +++ b/tests/functional/test_download.py @@ -1401,7 +1401,7 @@ def test_incorrect_metadata_hash( ) assert result.returncode != 0 expected_msg = f"""\ - Expected sha256 WRONG-HASH + Expected sha256 wrong-hash Got {real_hash}""" assert expected_msg in result.stderr diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index eaea12a163c..4aa6e76f7db 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -619,6 +619,18 @@ def test_hashed_install_failure(script: PipTestEnvironment, tmpdir: Path) -> Non assert len(result.files_created) == 0 +def test_case_insensitive_hashed_install_success( + script: PipTestEnvironment, tmpdir: Path +) -> None: + """Test that hashes that differ only by case don't halt installation.""" + with requirements_file( + "simple2==1.0 --hash=sha256:9336AF72CA661E6336EB87BC7DE3E8844D853E" + "3848C2B9BBD2E8BF01DB88C2C7\n", + tmpdir, + ) as reqs_file: + script.pip_install_local("-r", reqs_file.resolve()) + + def test_link_hash_pass_require_hashes( script: PipTestEnvironment, shared_data: TestData ) -> None: