Commit aa591ec4 by Randy Döring Committed by Bjorn Neergaard

locker: do not assign unrelated filenames/hashes to direct origin dependencies…

locker: do not assign unrelated filenames/hashes to direct origin dependencies when used in multiple constraints dependencies
parent 18dbb92d
...@@ -128,9 +128,18 @@ class Locker: ...@@ -128,9 +128,18 @@ class Locker:
# Old lock so we create dummy files from the hashes # Old lock so we create dummy files from the hashes
hashes = cast("dict[str, Any]", metadata["hashes"]) hashes = cast("dict[str, Any]", metadata["hashes"])
package.files = [{"name": h, "hash": h} for h in hashes[name]] package.files = [{"name": h, "hash": h} for h in hashes[name]]
elif source_type in {"git", "directory", "url"}:
package.files = []
else: else:
files = metadata["files"][name] files = metadata["files"][name]
package.files = files if source_type == "file":
filename = Path(url).name
package.files = [item for item in files if item["file"] == filename]
else:
# Strictly speaking, this is not correct, but we have no chance
# to always determine which are the correct files because the
# lockfile doesn't keep track which files belong to which package.
package.files = files
package.python_versions = info["python-versions"] package.python_versions = info["python-versions"]
extras = info.get("extras", {}) extras = info.get("extras", {})
......
...@@ -409,6 +409,120 @@ git-package-subdir = [] ...@@ -409,6 +409,120 @@ git-package-subdir = []
assert package.source_subdirectory == "subdir" assert package.source_subdirectory == "subdir"
def test_locker_properly_assigns_metadata_files(locker: Locker) -> None:
"""
For multiple constraints dependencies, there is only one common entry in
metadata.files. However, we must not assign all the files to each of the packages
because this can result in duplicated and outdated entries when running
`poetry lock --no-update` and hash check failures when running `poetry install`.
"""
content = """\
[[package]]
name = "demo"
version = "1.0"
description = ""
category = "main"
optional = false
python-versions = "*"
develop = false
[[package]]
name = "demo"
version = "1.0"
description = ""
category = "main"
optional = false
python-versions = "*"
develop = false
[package.source]
type = "git"
url = "https://github.com/demo/demo.git"
reference = "main"
resolved_reference = "123456"
[[package]]
name = "demo"
version = "1.0"
description = ""
category = "main"
optional = false
python-versions = "*"
develop = false
[package.source]
type = "directory"
url = "./folder"
[[package]]
name = "demo"
version = "1.0"
description = ""
category = "main"
optional = false
python-versions = "*"
develop = false
[package.source]
type = "file"
url = "./demo-1.0-cp39-win_amd64.whl"
[[package]]
name = "demo"
version = "1.0"
description = ""
category = "main"
optional = false
python-versions = "*"
develop = false
[package.source]
type = "url"
url = "https://example.com/demo-1.0-cp38-win_amd64.whl"
[metadata]
lock-version = "1.1"
python-versions = "*"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
[metadata.files]
# metadata.files are only tracked for non-direct origin and file dependencies
demo = [
{file = "demo-1.0-cp39-win_amd64.whl", hash = "sha256"},
{file = "demo-1.0.tar.gz", hash = "sha256"},
{file = "demo-1.0-py3-none-any.whl", hash = "sha256"},
]
"""
locker.lock.write(tomlkit.parse(content))
repository = locker.locked_repository()
assert len(repository.packages) == 5
assert {package.source_type for package in repository.packages} == {
None,
"git",
"directory",
"file",
"url",
}
for package in repository.packages:
if package.source_type is None:
# non-direct origin package contains all files
# with the current lockfile format we have no chance to determine
# which files are correct, so we keep all for hash check
# correct files are set later in Provider.complete_package()
assert package.files == [
{"file": "demo-1.0-cp39-win_amd64.whl", "hash": "sha256"},
{"file": "demo-1.0.tar.gz", "hash": "sha256"},
{"file": "demo-1.0-py3-none-any.whl", "hash": "sha256"},
]
elif package.source_type == "file":
assert package.files == [
{"file": "demo-1.0-cp39-win_amd64.whl", "hash": "sha256"}
]
else:
package.files = []
def test_lock_packages_with_null_description(locker: Locker, root: ProjectPackage): def test_lock_packages_with_null_description(locker: Locker, root: ProjectPackage):
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.description = None package_a.description = None
......
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