summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStéphane Bidoul <stephane.bidoul@gmail.com>2023-04-11 14:41:36 +0200
committerStéphane Bidoul <stephane.bidoul@gmail.com>2023-04-11 14:49:30 +0200
commit5119d4651e7881401315be7d262a19b762d636c0 (patch)
tree30da465538a45293eda57467d05e1d9e865a2804
parentcdd9c95eacd58237f8dd800aa40756f9cf8e9b81 (diff)
downloadpip-5119d4651e7881401315be7d262a19b762d636c0.tar.gz
Improve conversion of direct_url.hash to hashes
-rw-r--r--src/pip/_internal/models/direct_url.py30
-rw-r--r--tests/unit/test_direct_url.py30
2 files changed, 49 insertions, 11 deletions
diff --git a/src/pip/_internal/models/direct_url.py b/src/pip/_internal/models/direct_url.py
index c3de70a74..709ea69d4 100644
--- a/src/pip/_internal/models/direct_url.py
+++ b/src/pip/_internal/models/direct_url.py
@@ -105,22 +105,30 @@ class ArchiveInfo:
hash: Optional[str] = None,
hashes: Optional[Dict[str, str]] = None,
) -> None:
- if hash is not None:
+ self.hashes = hashes
+ self.hash = hash
+
+ @property
+ def hash(self) -> Optional[str]:
+ return self._hash
+
+ @hash.setter
+ def hash(self, value: Optional[str]) -> None:
+ if value is not None:
# Auto-populate the hashes key to upgrade to the new format automatically.
- # We don't back-populate the legacy hash key.
+ # We don't back-populate the legacy hash key from hashes.
try:
- hash_name, hash_value = hash.split("=", 1)
+ hash_name, hash_value = value.split("=", 1)
except ValueError:
raise DirectUrlValidationError(
- f"invalid archive_info.hash format: {hash!r}"
+ f"invalid archive_info.hash format: {value!r}"
)
- 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
+ if self.hashes is None:
+ self.hashes = {hash_name: hash_value}
+ elif hash_name not in self.hashes:
+ self.hashes = self.hashes.copy()
+ self.hashes[hash_name] = hash_value
+ self._hash = value
@classmethod
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["ArchiveInfo"]:
diff --git a/tests/unit/test_direct_url.py b/tests/unit/test_direct_url.py
index 3ca982b50..151e0a30f 100644
--- a/tests/unit/test_direct_url.py
+++ b/tests/unit/test_direct_url.py
@@ -140,3 +140,33 @@ def test_redact_url() -> None:
== "https://${PIP_TOKEN}@g.c/u/p.git"
)
assert _redact_git("ssh://git@g.c/u/p.git") == "ssh://git@g.c/u/p.git"
+
+
+def test_hash_to_hashes() -> None:
+ direct_url = DirectUrl(url="https://e.c/archive.tar.gz", info=ArchiveInfo())
+ assert isinstance(direct_url.info, ArchiveInfo)
+ direct_url.info.hash = "sha256=abcdef"
+ assert direct_url.info.hashes == {"sha256": "abcdef"}
+
+
+def test_hash_to_hashes_constructor() -> None:
+ direct_url = DirectUrl(
+ url="https://e.c/archive.tar.gz", info=ArchiveInfo(hash="sha256=abcdef")
+ )
+ assert isinstance(direct_url.info, ArchiveInfo)
+ assert direct_url.info.hashes == {"sha256": "abcdef"}
+ direct_url = DirectUrl(
+ url="https://e.c/archive.tar.gz",
+ info=ArchiveInfo(hash="sha256=abcdef", hashes={"sha512": "123456"}),
+ )
+ assert isinstance(direct_url.info, ArchiveInfo)
+ assert direct_url.info.hashes == {"sha256": "abcdef", "sha512": "123456"}
+ # In case of conflict between hash and hashes, hashes wins.
+ direct_url = DirectUrl(
+ url="https://e.c/archive.tar.gz",
+ info=ArchiveInfo(
+ hash="sha256=abcdef", hashes={"sha256": "012345", "sha512": "123456"}
+ ),
+ )
+ assert isinstance(direct_url.info, ArchiveInfo)
+ assert direct_url.info.hashes == {"sha256": "012345", "sha512": "123456"}