Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "2.2.1"
description = "Python dependency management and packaging made easy."
requires-python = ">=3.10,<4.0"
dependencies = [
"poetry-core @ git+https://github.com/python-poetry/poetry-core.git",
"poetry-core @ git+https://github.com/radoering/poetry-core.git@file-url-size-upload-time",
"build (>=1.2.1,<2.0.0)",
"cachecontrol[filecache] (>=0.14.0,<0.15.0)",
"cleo (>=2.1.0,<3.0.0)",
Expand Down
11 changes: 8 additions & 3 deletions src/poetry/packages/direct_origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ def get_package_from_file(cls, file_path: Path) -> Package:
f"Unable to determine package info from path: {file_path}"
)

package.files = [
{
"file": file_path.name,
"hash": "sha256:" + get_file_hash(file_path),
"size": file_path.stat().st_size,
}
]

return package

@classmethod
Expand All @@ -91,9 +99,6 @@ def get_package_from_url(self, url: str) -> Package:
)

package = self.get_package_from_file(artifact)
package.files = [
{"file": link.filename, "hash": "sha256:" + get_file_hash(artifact)}
]

package._source_type = "url"
package._source_url = url
Expand Down
8 changes: 7 additions & 1 deletion src/poetry/packages/locker.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,13 @@ def _dump_package(
):
if not marker.is_any():
data["markers"][group] = str(marker)
data["files"] = sorted(package.files, key=lambda x: x["file"])
data["files"] = sorted(
[
{k: v for k, v in f.items() if k in {"file", "hash"}}
for f in package.files
],
key=lambda x: x["file"],
)

if dependencies:
data["dependencies"] = table()
Expand Down
8 changes: 0 additions & 8 deletions src/poetry/puzzle/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
from poetry.packages.package_collection import PackageCollection
from poetry.puzzle.exceptions import OverrideNeededError
from poetry.repositories.repository_pool import Priority
from poetry.utils.helpers import get_file_hash


if TYPE_CHECKING:
Expand Down Expand Up @@ -344,13 +343,6 @@ def _search_for_file(self, dependency: FileDependency) -> Package:
if dependency.base is not None:
package.root_dir = dependency.base

package.files = [
{
"file": dependency.path.name,
"hash": "sha256:" + get_file_hash(dependency.full_path),
}
]

return package

def _search_for_directory(self, dependency: DirectoryDependency) -> Package:
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/repositories/cached_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class CachedRepository(Repository, ABC):
CACHE_VERSION = parse_constraint("2.0.0")
CACHE_VERSION = parse_constraint("2.1.0")

def __init__(
self, name: str, *, disable_cache: bool = False, config: Config | None = None
Expand Down
12 changes: 11 additions & 1 deletion src/poetry/repositories/http_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,17 @@ def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]
level="warning",
)
else:
files.append({"file": link.filename, "hash": file_hash})
files.append(
{
"file": link.filename,
"hash": file_hash,
"url": link.url_without_fragment,
}
)
if link.size is not None:
files[-1]["size"] = link.size
if link.upload_time_isoformat is not None:
files[-1]["upload_time"] = link.upload_time_isoformat

if not files:
raise PackageNotFoundError(
Expand Down
4 changes: 4 additions & 0 deletions src/poetry/repositories/link_sources/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def _link_cache(self) -> LinkCache:
requires_python = file.get("requires-python")
hashes = file.get("hashes", {})
yanked = file.get("yanked", False)
size = file.get("size")
upload_time = file.get("upload-time")

# see https://peps.python.org/pep-0714/#clients
# and https://peps.python.org/pep-0691/#project-detail
Expand All @@ -51,6 +53,8 @@ def _link_cache(self) -> LinkCache:
hashes=hashes,
yanked=yanked,
metadata=metadata,
size=size,
upload_time=upload_time,
)

if link.ext not in self.SUPPORTED_FORMATS:
Expand Down
5 changes: 5 additions & 0 deletions src/poetry/repositories/pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,13 @@ def _get_release_info(
{
"file": file_info["filename"],
"hash": "sha256:" + file_info["digests"]["sha256"],
"url": file_info["url"],
}
)
if (size := file_info.get("size")) is not None:
files[-1]["size"] = size
if upload_time := file_info.get("upload_time_iso_8601"):
files[-1]["upload_time"] = upload_time
data.files = files

if self._fallback and data.requires_dist is None:
Expand Down
4 changes: 2 additions & 2 deletions tests/installation/test_chooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes(
files: list[PackageFile] = [
{
"file": filename,
"hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
"hash": f"sha256:{dist_hash_getter(filename).sha256}",
}
for filename in [
f"{package.name}-{package.version}.tar.gz",
Expand Down Expand Up @@ -291,7 +291,7 @@ def test_chooser_does_not_choose_yanked_if_others(
files: list[PackageFile] = [
{
"file": filename,
"hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
"hash": f"sha256:{dist_hash_getter(filename).sha256}",
}
for filename in [
f"{package.name}-{package.version}-py2-none-any.whl",
Expand Down
21 changes: 21 additions & 0 deletions tests/packages/test_direct_origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ def test_direct_origin_get_package_from_file(fixture_dir: FixtureDirGetter) -> N
wheel_path = fixture_dir("distributions") / "demo-0.1.2-py2.py3-none-any.whl"
package = DirectOrigin.get_package_from_file(wheel_path)
assert package.name == "demo"
assert package.files == [
{
"file": "demo-0.1.2-py2.py3-none-any.whl",
"hash": "sha256:55dde4e6828081de7a1e429f33180459c333d9da593db62a3d75a8f5e505dde1",
"size": 1552,
}
]


def test_direct_origin_caches_url_dependency(tmp_path: Path) -> None:
Expand All @@ -31,6 +38,13 @@ def test_direct_origin_caches_url_dependency(tmp_path: Path) -> None:
package = direct_origin.get_package_from_url(url)

assert package.name == "demo"
assert package.files == [
{
"file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a",
"size": 1116,
}
]
assert artifact_cache.get_cached_archive_for_link(Link(url), strict=True)


Expand All @@ -51,6 +65,13 @@ def test_direct_origin_does_not_download_url_dependency_when_cached(
package = direct_origin.get_package_from_url(url)

assert package.name == "demo"
assert package.files == [
{
"file": "demo-0.1.2-py2.py3-none-any.whl",
"hash": "sha256:55dde4e6828081de7a1e429f33180459c333d9da593db62a3d75a8f5e505dde1",
"size": 1552,
}
]
artifact_cache.get_cached_archive_for_link.assert_called_once_with(
Link(url), strict=True, download_func=download_file
)
42 changes: 41 additions & 1 deletion tests/packages/test_locker.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ def test_locker_properly_assigns_metadata_files(locker: Locker) -> None:
package.files = []


def test_lock_packages_with_null_description(
def test_locker_dumps_packages_with_null_description(
locker: Locker, root: ProjectPackage, transitive_info: TransitivePackageInfo
) -> None:
package_a = get_package("A", "1.0.0")
Expand Down Expand Up @@ -733,6 +733,46 @@ def test_lock_packages_with_null_description(
assert content == expected


def test_locker_does_not_dump_file_urls(
locker: Locker, root: ProjectPackage, transitive_info: TransitivePackageInfo
) -> None:
package_a = get_package("A", "1.0")
package_a.files = [
{
"file": "a-1.0.whl",
"hash": "sha256:abcdef1234567890",
"url": "https://example.org/a-1.0.whl",
},
]

locker.set_lock_data(root, {package_a: transitive_info})

with locker.lock.open(encoding="utf-8") as f:
content = f.read()

expected = f"""\
# {GENERATED_COMMENT}

[[package]]
name = "A"
version = "1.0"
description = ""
optional = false
python-versions = "*"
groups = ["main"]
files = [
{{file = "a-1.0.whl", hash = "sha256:abcdef1234567890"}},
]

[metadata]
lock-version = "2.1"
python-versions = "*"
content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8"
"""

assert content == expected


def test_lock_file_should_not_have_mixed_types(
locker: Locker, root: ProjectPackage, transitive_info: TransitivePackageInfo
) -> None:
Expand Down
28 changes: 28 additions & 0 deletions tests/puzzle/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,13 @@ def test_search_for_file_sdist(

assert package.name == "demo"
assert package.version.text == "0.1.0"
assert package.files == [
{
"file": "demo-0.1.0.tar.gz",
"hash": "sha256:9fa123ad707a5c6c944743bf3e11a0e80d86cb518d3cf25320866ca3ef43e2ad",
"size": 1003,
}
]

required = {
r for r in sorted(package.requires, key=lambda r: r.name) if not r.is_optional()
Expand Down Expand Up @@ -575,6 +582,13 @@ def test_search_for_file_sdist_with_extras(

assert package.name == "demo"
assert package.version.text == "0.1.0"
assert package.files == [
{
"file": "demo-0.1.0.tar.gz",
"hash": "sha256:9fa123ad707a5c6c944743bf3e11a0e80d86cb518d3cf25320866ca3ef43e2ad",
"size": 1003,
}
]

required = {
r for r in sorted(package.requires, key=lambda r: r.name) if not r.is_optional()
Expand Down Expand Up @@ -605,6 +619,13 @@ def test_search_for_file_wheel(

assert package.name == "demo"
assert package.version.text == "0.1.0"
assert package.files == [
{
"file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a",
"size": 1116,
}
]

required = {
r for r in sorted(package.requires, key=lambda r: r.name) if not r.is_optional()
Expand Down Expand Up @@ -636,6 +657,13 @@ def test_search_for_file_wheel_with_extras(

assert package.name == "demo"
assert package.version.text == "0.1.0"
assert package.files == [
{
"file": "demo-0.1.0-py2.py3-none-any.whl",
"hash": "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a",
"size": 1116,
}
]

required = {
r for r in sorted(package.requires, key=lambda r: r.name) if not r.is_optional()
Expand Down
Loading