Commit fb52c989 by Arun Babu Neelicattu Committed by GitHub

handle poetry 1.1 lock content hash (#5458)

This change ensures that content-hash generated by poetry < 1.2 does
not trigger unnecessary warnings and operations. We do this by using a
backwards compatible hashing logic.
parent 819d6d4b
......@@ -46,7 +46,8 @@ class Locker:
_VERSION = "1.1"
_relevant_keys = ["dependencies", "group", "source", "extras"]
_legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"]
_relevant_keys = [*_legacy_keys, "group"]
def __init__(self, lock: str | Path, local_config: dict) -> None:
self._lock = TOMLFile(lock)
......@@ -428,13 +429,14 @@ class Locker:
relevant_content = {}
for key in self._relevant_keys:
relevant_content[key] = content.get(key)
data = content.get(key)
content_hash = sha256(
json.dumps(relevant_content, sort_keys=True).encode()
).hexdigest()
if data is None and key not in self._legacy_keys:
continue
relevant_content[key] = data
return content_hash
return sha256(json.dumps(relevant_content, sort_keys=True).encode()).hexdigest()
def _get_lock_data(self) -> TOMLDocument:
if not self._lock.exists():
......
......@@ -101,7 +101,7 @@ six = "*"
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "ae61bd854548e88c090780099edd400d58e6944ce9f3fc086d2f9aa5ac487f14"
content-hash = "0cd068218f235c162f7b74bc8faf4ce3387b82daee1c1bb7a97af034f27ee116"
[metadata.files]
certifi = [
......
from __future__ import annotations
import json
import logging
import tempfile
import uuid
from hashlib import sha256
from pathlib import Path
from typing import TYPE_CHECKING
......@@ -94,7 +97,7 @@ resolved_reference = "123456"
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = [
......@@ -303,7 +306,7 @@ python-versions = "*"
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -343,7 +346,7 @@ foo = ["B (>=1.0.0)"]
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -373,7 +376,7 @@ foo = ["bar"]
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -420,7 +423,7 @@ reference = "legacy"
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -504,7 +507,7 @@ B = {version = "^1.0.0", extras = ["a", "b", "c"], optional = true}
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -598,7 +601,7 @@ F = {git = "https://github.com/python-poetry/poetry.git", branch = "foo"}
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "178f2cd01dc40e96be23a4a0ae1094816626346346618335e5ff4f0b2c0c5831"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
A = []
......@@ -651,3 +654,46 @@ lib-b = []
assert root_dir.match("*/lib/libA")
# relative_to raises an exception if not relative - is_relative_to comes in py3.9
assert root_dir.relative_to(locker.lock.path.parent.resolve()) is not None
@pytest.mark.parametrize(
("local_config", "fresh"),
[
({}, True),
({"dependencies": [uuid.uuid4().hex]}, True),
(
{
"dependencies": [uuid.uuid4().hex],
"dev-dependencies": [uuid.uuid4().hex],
},
True,
),
(
{
"dependencies": [uuid.uuid4().hex],
"dev-dependencies": None,
},
True,
),
({"dependencies": [uuid.uuid4().hex], "groups": [uuid.uuid4().hex]}, False),
],
)
def test_content_hash_with_legacy_is_compatible(
local_config: dict[str, list[str]], fresh: bool, locker: Locker
) -> None:
# old hash generation
relevant_content = {}
for key in locker._legacy_keys:
relevant_content[key] = local_config.get(key)
locker = locker.__class__(
lock=locker.lock.path,
local_config=local_config,
)
old_content_hash = sha256(
json.dumps(relevant_content, sort_keys=True).encode()
).hexdigest()
content_hash = locker._get_content_hash()
assert (content_hash == old_content_hash) or fresh
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment