Commit 3ed01339 by Marek Grzenkowicz Committed by GitHub

installer: write spec-compliant direct_url.json for file and url dependencies (#7475)

drop deprecated `hash` in favor of `hashes`
* https://packaging.python.org/en/latest/specifications/direct-url/ supersedes PEP 610
* keeping `hash` for compatibility probably does not make sense since it was not spec-compliant (":" instead of "=" as separator between algorithm and value)
parent 58fe8f22
......@@ -572,6 +572,8 @@ class Executor:
if not Path(package.source_url).is_absolute() and package.root_dir:
archive = package.root_dir / archive
self._populate_hashes_dict(archive, package)
return self._chef.prepare(archive, editable=package.develop)
def _prepare_directory_archive(self, operation: Install | Update) -> Path:
......@@ -734,13 +736,15 @@ class Executor:
archive = self._chef.prepare(archive, output_dir=output_dir)
self._populate_hashes_dict(archive, package)
return archive
def _populate_hashes_dict(self, archive: Path, package: Package) -> None:
if package.files and archive.name in {f["file"] for f in package.files}:
archive_hash = self._validate_archive_hash(archive, package)
self._hashes[package.name] = archive_hash
return archive
@staticmethod
def _validate_archive_hash(archive: Path, package: Package) -> str:
archive_hash: str = "sha256:" + get_file_hash(archive)
......@@ -874,20 +878,12 @@ class Executor:
return reference
def _create_url_url_reference(self, package: Package) -> dict[str, Any]:
archive_info = {}
if package.name in self._hashes:
archive_info["hash"] = self._hashes[package.name]
reference = {"url": package.source_url, "archive_info": archive_info}
archive_info = self._get_archive_info(package)
return reference
return {"url": package.source_url, "archive_info": archive_info}
def _create_file_url_reference(self, package: Package) -> dict[str, Any]:
archive_info = {}
if package.name in self._hashes:
archive_info["hash"] = self._hashes[package.name]
archive_info = self._get_archive_info(package)
assert package.source_url is not None
return {
......@@ -906,3 +902,20 @@ class Executor:
"url": Path(package.source_url).as_uri(),
"dir_info": dir_info,
}
def _get_archive_info(self, package: Package) -> dict[str, Any]:
"""
Create dictionary `archive_info` for file `direct_url.json`.
Specification: https://packaging.python.org/en/latest/specifications/direct-url
(it supersedes PEP 610)
:param package: This must be a poetry package instance.
"""
archive_info = {}
if package.name in self._hashes:
algorithm, value = self._hashes[package.name].split(":")
archive_info["hashes"] = {algorithm: value}
return archive_info
......@@ -622,12 +622,27 @@ def test_executor_should_write_pep610_url_references_for_files(
.resolve()
)
package = Package("demo", "0.1.0", source_type="file", source_url=url.as_posix())
# Set package.files so the executor will attempt to hash the package
package.files = [
{
"file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a", # noqa: E501
}
]
executor = Executor(tmp_venv, pool, config, io)
executor.execute([Install(package)])
verify_installed_distribution(
tmp_venv, package, {"archive_info": {}, "url": url.as_uri()}
)
expected_url_reference = {
"archive_info": {
"hashes": {
"sha256": (
"70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"
)
},
},
"url": url.as_uri(),
}
verify_installed_distribution(tmp_venv, package, expected_url_reference)
def test_executor_should_write_pep610_url_references_for_directories(
......@@ -701,12 +716,27 @@ def test_executor_should_write_pep610_url_references_for_urls(
source_type="url",
source_url="https://files.pythonhosted.org/demo-0.1.0-py2.py3-none-any.whl",
)
# Set package.files so the executor will attempt to hash the package
package.files = [
{
"file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a", # noqa: E501
}
]
executor = Executor(tmp_venv, pool, config, io)
executor.execute([Install(package)])
verify_installed_distribution(
tmp_venv, package, {"archive_info": {}, "url": package.source_url}
)
expected_url_reference = {
"archive_info": {
"hashes": {
"sha256": (
"70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"
)
},
},
"url": package.source_url,
}
verify_installed_distribution(tmp_venv, package, expected_url_reference)
def test_executor_should_write_pep610_url_references_for_git(
......
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