From 38681f3d6669754c7e919f0eb051b12931bfb0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 30 Dec 2022 14:11:45 +0100 Subject: [PATCH] Allow multiple hashes in direct_url.json This influences the recorded direct_url.json metadata, and therefore the pip inspect output, as well as the pip install --report format. --- news/11312.feature.rst | 2 ++ src/pip/_internal/models/direct_url.py | 15 +++++++++++++-- tests/unit/test_direct_url.py | 4 ++++ tests/unit/test_direct_url_helpers.py | 4 ++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 news/11312.feature.rst diff --git a/news/11312.feature.rst b/news/11312.feature.rst new file mode 100644 index 00000000000..493dde83059 --- /dev/null +++ b/news/11312.feature.rst @@ -0,0 +1,2 @@ +Change the hashes in the installation report to be a mapping. Emit the +``archive_info.hashes`` dictionary in ``direct_url.json``. diff --git a/src/pip/_internal/models/direct_url.py b/src/pip/_internal/models/direct_url.py index e75feda9ca9..09b540f916c 100644 --- a/src/pip/_internal/models/direct_url.py +++ b/src/pip/_internal/models/direct_url.py @@ -103,17 +103,28 @@ class ArchiveInfo: def __init__( self, hash: Optional[str] = None, + hashes: Optional[Dict[str, str]] = None, ) -> None: + if hash is not None: + # Auto-populate the hashes key to upgrade to the new format automatically. + # We don't back-populate the legacy hash key. + hash_name, hash_value = hash.split("=", 1) + if hashes is None: + hashes = {hash_name: hash_value} + elif hash_name not in hash: + hashes = hashes.copy() + hashes[hash_name] = hash_value self.hash = hash + self.hashes = hashes @classmethod def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["ArchiveInfo"]: if d is None: return None - return cls(hash=_get(d, str, "hash")) + return cls(hash=_get(d, str, "hash"), hashes=_get(d, dict, "hashes")) def _to_dict(self) -> Dict[str, Any]: - return _filter_none(hash=self.hash) + return _filter_none(hash=self.hash, hashes=self.hashes) class DirInfo: diff --git a/tests/unit/test_direct_url.py b/tests/unit/test_direct_url.py index c81e5129253..e1708ae9381 100644 --- a/tests/unit/test_direct_url.py +++ b/tests/unit/test_direct_url.py @@ -39,6 +39,10 @@ def test_archive_info() -> None: assert ( direct_url.info.hash == direct_url_dict["archive_info"]["hash"] # type: ignore ) + # test we add the hashes key automatically + direct_url_dict["archive_info"]["hashes"] = { # type: ignore + "sha1": "1b8c5bc61a86f377fea47b4276c8c8a5842d2220" + } assert direct_url.to_dict() == direct_url_dict diff --git a/tests/unit/test_direct_url_helpers.py b/tests/unit/test_direct_url_helpers.py index 3ab253462b6..692ee299c02 100644 --- a/tests/unit/test_direct_url_helpers.py +++ b/tests/unit/test_direct_url_helpers.py @@ -146,6 +146,10 @@ def test_from_link_archive() -> None: ) assert isinstance(direct_url.info, ArchiveInfo) assert direct_url.info.hash == "sha1=1b8c5bc61a86f377fea47b4276c8c8a5842d2220" + # Test the hashes key has been automatically populated. + assert direct_url.info.hashes == { + "sha1": "1b8c5bc61a86f377fea47b4276c8c8a5842d2220" + } def test_from_link_dir(tmpdir: Path) -> None: