Skip to content
Merged
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
52 changes: 40 additions & 12 deletions src/packaging/pylock.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,6 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:
hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract]
)
_validate_path_url(package_sdist.path, package_sdist.url)
try:
parse_sdist_filename(package_sdist.filename)
except Exception as e:
raise PylockValidationError(
f"Invalid sdist filename {package_sdist.filename!r}"
) from e
return package_sdist

@property
Expand Down Expand Up @@ -502,12 +496,6 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:
hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract]
)
_validate_path_url(package_wheel.path, package_wheel.url)
try:
parse_wheel_filename(package_wheel.filename)
except Exception as e:
raise PylockValidationError(
f"Invalid wheel filename {package_wheel.filename!r}"
) from e
return package_wheel

@property
Expand Down Expand Up @@ -597,6 +585,46 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:
"Exactly one of vcs, directory, archive must be set "
"if sdist and wheels are not set"
)
for i, wheel in enumerate(package.wheels or []):
try:
(name, version, _, _) = parse_wheel_filename(wheel.filename)
except Exception as e:
raise PylockValidationError(
f"Invalid wheel filename {wheel.filename!r}",
context=f"wheels[{i}]",
) from e
if name != package.name:
raise PylockValidationError(
f"Name in {wheel.filename!r} is not consistent with "
f"package name {package.name!r}",
context=f"wheels[{i}]",
)
if package.version and version != package.version:
raise PylockValidationError(
f"Version in {wheel.filename!r} is not consistent with "
f"package version {str(package.version)!r}",
context=f"wheels[{i}]",
)
if package.sdist:
try:
name, version = parse_sdist_filename(package.sdist.filename)
except Exception as e:
raise PylockValidationError(
f"Invalid sdist filename {package.sdist.filename!r}",
context="sdist",
) from e
if name != package.name:
raise PylockValidationError(
f"Name in {package.sdist.filename!r} is not consistent with "
f"package name {package.name!r}",
context="sdist",
)
if package.version and version != package.version:
raise PylockValidationError(
f"Version in {package.sdist.filename!r} is not consistent with "
f"package version {str(package.version)!r}",
context="sdist",
)
try:
for i, attestation_identity in enumerate( # noqa: B007
package.attestation_identities or []
Expand Down
108 changes: 108 additions & 0 deletions tests/test_pylock.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ def test_pylock_invalid_vcs() -> None:
),
"example-1.0.tar.gz",
),
(
PackageSdist(
path="example-1.0.tar.gz",
hashes={},
),
"example-1.0.tar.gz",
),
(
PackageSdist(
url="https://example.com/example-1.0.tar.gz",
Expand Down Expand Up @@ -362,6 +369,13 @@ def test_pylock_invalid_vcs() -> None:
),
"example-1.0-py3-none-any.whl",
),
(
PackageWheel(
path="example-1.0-py3-none-any.whl",
hashes={},
),
"example-1.0-py3-none-any.whl",
),
(
PackageWheel(
url="https://example.com/example-1.0-py3-none-any.whl",
Expand Down Expand Up @@ -439,6 +453,55 @@ def test_pylock_invalid_wheel_filename() -> None:
)


def test_pylock_inconsistent_wheel_name() -> None:
data = {
"lock-version": "1.0",
"created-by": "pip",
"packages": [
{
"name": "foo",
"wheels": [
{
"url": "http://example.com/bar-1.0-py3-none-any.whl",
"hashes": {"sha256": "f" * 40},
}
],
}
],
}
with pytest.raises(PylockValidationError) as exc_info:
Pylock.from_dict(data)
assert str(exc_info.value) == (
"Name in 'bar-1.0-py3-none-any.whl' is not consistent "
"with package name 'foo' in 'packages[0].wheels[0]'"
)


def test_pylock_inconsistent_wheel_version() -> None:
data = {
"lock-version": "1.0",
"created-by": "pip",
"packages": [
{
"name": "bar",
"version": "2.0",
"wheels": [
{
"url": "http://example.com/bar-1.0-py3-none-any.whl",
"hashes": {"sha256": "f" * 40},
}
],
}
],
}
with pytest.raises(PylockValidationError) as exc_info:
Pylock.from_dict(data)
assert str(exc_info.value) == (
"Version in 'bar-1.0-py3-none-any.whl' is not consistent "
"with package version '2.0' in 'packages[0].wheels[0]'"
)


def test_pylock_invalid_sdist_filename() -> None:
data = {
"lock-version": "1.0",
Expand All @@ -460,6 +523,51 @@ def test_pylock_invalid_sdist_filename() -> None:
)


def test_pylock_inconsistent_sdist_name() -> None:
data = {
"lock-version": "1.0",
"created-by": "pip",
"packages": [
{
"name": "foo",
"sdist": {
"path": "./bar-1.0.tar.gz",
"hashes": {"sha256": "f" * 40},
},
},
],
}
with pytest.raises(PylockValidationError) as exc_info:
Pylock.from_dict(data)
assert str(exc_info.value) == (
"Name in 'bar-1.0.tar.gz' is not consistent "
"with package name 'foo' in 'packages[0].sdist'"
)


def test_pylock_inconsistent_sdist_version() -> None:
data = {
"lock-version": "1.0",
"created-by": "pip",
"packages": [
{
"name": "bar",
"version": "2.0",
"sdist": {
"path": "./bar-1.0.tar.gz",
"hashes": {"sha256": "f" * 40},
},
},
],
}
with pytest.raises(PylockValidationError) as exc_info:
Pylock.from_dict(data)
assert str(exc_info.value) == (
"Version in 'bar-1.0.tar.gz' is not consistent "
"with package version '2.0' in 'packages[0].sdist'"
)


def test_pylock_invalid_wheel() -> None:
data = {
"lock-version": "1.0",
Expand Down
Loading