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
2 changes: 2 additions & 0 deletions docs/notes/2.34.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ Support for creating multiplatform/foreign platform pexes when using the `uv` re

Fixed a bug that caused `generate-lockfiles --sync` not to have its intended effect when using `uv` lockfiles.

`generate-lockfiles` now overwrites an existing lockfile that fails to parse, rather than failing with a `TOMLDecodeError`.

Fixed a bug that could cause tool execution to fail when resolving the tool from a `uv` lockfile.

Required named indexes to be referenced explicitly in requirement sources when using the uv resolver, to match the pex resolver's behavior.
Expand Down
7 changes: 4 additions & 3 deletions src/python/pants/backend/python/goals/lockfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import itertools
import os.path
import tomllib
from collections import defaultdict
from dataclasses import dataclass
from operator import itemgetter
Expand Down Expand Up @@ -403,9 +404,9 @@ async def generate_uv_lockfile(
raise ValueError(
f"Expected lockfile entry to be a FileEntry but was a {type(repo_lock_entry)}"
)
except IntrinsicError:
# May fail if the file doesn't exist, which is expected the first time a new lockfile
# is generated.
except (IntrinsicError, tomllib.TOMLDecodeError):
# May fail if the file doesn't exist or is malformed, which is expected the first time
# a new lockfile is generated or when the existing one needs to be overwritten.
pass

uv_config = resolve_config.uv_config()
Expand Down
32 changes: 32 additions & 0 deletions src/python/pants/backend/python/goals/lockfile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,3 +912,35 @@ def generate_and_get_versions(reqs: FrozenOrderedSet[str], sync: bool) -> dict[s
# Regenerate with --sync.
versions = generate_and_get_versions(updated_requirements, sync=True)
assert {"ansicolors": "1.1.8", "cowsay": "6.0"} == versions


def test_uv_lockfile_generation_ignores_malformed_existing_lockfile(
rule_runner: PythonRuleRunner,
) -> None:
# Regression test for https://github.com/pantsbuild/pants/issues/23706.
rule_runner.set_options(
[
"--python-resolves={'test': 'test.lock'}",
"--python-separate-lockfile-metadata-file",
"--generate-lockfiles-sync",
],
env_inherit=PYTHON_BOOTSTRAP_ENV,
)
req = GenerateUvLockfile(
requirements=FrozenOrderedSet(["ansicolors==1.1.8"]),
find_links=FrozenOrderedSet([]),
interpreter_constraints=InterpreterConstraints(["CPython==3.14.*"]),
resolve_name="test",
lockfile_dest="test.lock",
diff=True,
)

rule_runner.write_digest(rule_runner.request(GenerateLockfileResult, [req]).digest)
rule_runner.write_files({"test.lock": "not valid toml [[["})

result = rule_runner.request(GenerateLockfileResult, [req])
digest_contents = rule_runner.request(DigestContents, [result.digest])
by_path = {fc.path: fc for fc in digest_contents}
lock_data = tomllib.loads(by_path["test.lock"].content.decode())
packages = {pkg["name"]: pkg["version"] for pkg in lock_data.get("package", [])}
assert packages["ansicolors"] == "1.1.8"
6 changes: 3 additions & 3 deletions src/python/pants/backend/python/util_rules/lockfile_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ async def _generate_lockfile_diff(
old_content_entries = await get_digest_contents(loaded.lockfile_digest)
old_content = next(iter(old_content_entries)).content
old_packages = _parse_lockfile_packages(old_content, loaded.lockfile_format, path)
except EngineError:
# May fail if the file doesn't exist, which is expected the first time a new lockfile
# is generated.
except (EngineError, tomllib.TOMLDecodeError):
# May fail if the file doesn't exist or is malformed, which is expected the first time a
# new lockfile is generated or when the existing one needs to be overwritten.
pass

return LockfileDiff.create(
Expand Down
Loading