Skip to content

Commit fb9b33c

Browse files
authored
Introduce a LockfileFormat enum. (#23233)
Previously we had an `is_pex_native` boolean, where the alternative was using constraints files. This change makes way for new lockfile formats, specifically uv.lock.
1 parent 756ac44 commit fb9b33c

File tree

8 files changed

+52
-19
lines changed

8 files changed

+52
-19
lines changed

src/python/pants/backend/python/goals/pytest_runner_test.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints
1414
from pants.backend.python.util_rules.lockfile_metadata import PythonLockfileMetadataV3
1515
from pants.backend.python.util_rules.pex import PexRequirementsInfo
16-
from pants.backend.python.util_rules.pex_requirements import LoadedLockfile, Lockfile
16+
from pants.backend.python.util_rules.pex_requirements import (
17+
LoadedLockfile,
18+
Lockfile,
19+
LockfileFormat,
20+
)
1721
from pants.engine.fs import DigestContents, FileContent
1822
from pants.engine.internals.native_engine import EMPTY_DIGEST
1923
from pants.testutil.option_util import create_subsystem
@@ -98,7 +102,9 @@ def validate(reqs: list[str]) -> None:
98102
only_binary=set(),
99103
no_binary=set(),
100104
)
101-
loaded_lockfile = LoadedLockfile(EMPTY_DIGEST, "", metadata, 0, True, None, lockfile)
105+
loaded_lockfile = LoadedLockfile(
106+
EMPTY_DIGEST, "", metadata, 0, LockfileFormat.Pex, None, lockfile
107+
)
102108
run_rule_with_mocks(
103109
validate_pytest_cov_included,
104110
rule_args=[tool],

src/python/pants/backend/python/subsystems/python_tool_base_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pants.backend.python.util_rules.pex_requirements import (
1010
LoadedLockfile,
1111
Lockfile,
12+
LockfileFormat,
1213
PexRequirements,
1314
Resolve,
1415
)
@@ -52,7 +53,9 @@ def test_get_lockfile_metadata() -> None:
5253
no_binary=set(),
5354
)
5455
lockfile = Lockfile("dummy_url", "dummy_description_of_origin", "dummy_resolve")
55-
loaded_lockfile = LoadedLockfile(EMPTY_DIGEST, "", metadata, 0, True, None, lockfile)
56+
loaded_lockfile = LoadedLockfile(
57+
EMPTY_DIGEST, "", metadata, 0, LockfileFormat.Pex, None, lockfile
58+
)
5659
assert (
5760
run_rule_with_mocks(
5861
get_lockfile_metadata,

src/python/pants/backend/python/util_rules/pex.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
LoadedLockfile,
4545
LoadedLockfileRequest,
4646
Lockfile,
47+
LockfileFormat,
4748
Resolve,
4849
ResolvePexConfigRequest,
4950
determine_resolve_pex_config,
@@ -571,7 +572,7 @@ async def _build_uv_venv(
571572
uv_request.requirements.from_superset, **implicitly()
572573
)
573574
loaded_lockfile = await load_lockfile(LoadedLockfileRequest(lockfile), **implicitly())
574-
if loaded_lockfile.is_pex_native:
575+
if loaded_lockfile.lockfile_format == LockfileFormat.Pex:
575576
try:
576577
digest_contents = await get_digest_contents(loaded_lockfile.lockfile_digest)
577578
lockfile_bytes = next(
@@ -793,7 +794,7 @@ async def _setup_pex_requirements(
793794
if loaded_lockfile:
794795
argv = (
795796
["--lock", loaded_lockfile.lockfile_path, *pex_lock_resolver_args]
796-
if loaded_lockfile.is_pex_native
797+
if loaded_lockfile.lockfile_format == LockfileFormat.Pex
797798
# We use pip to resolve a requirements.txt pseudo-lockfile, possibly with hashes.
798799
else [
799800
"--requirement",
@@ -843,7 +844,7 @@ async def _setup_pex_requirements(
843844
loaded_lockfile = await load_lockfile(LoadedLockfileRequest(lockfile), **implicitly())
844845

845846
# NB: This is also validated in the constructor.
846-
assert loaded_lockfile.is_pex_native
847+
assert loaded_lockfile.lockfile_format == LockfileFormat.Pex
847848
if not reqs_info.req_strings:
848849
return _BuildPexRequirementsSetup([], [], concurrency_available)
849850

src/python/pants/backend/python/util_rules/pex_from_targets.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
EntireLockfile,
3535
LoadedLockfileRequest,
3636
Lockfile,
37+
LockfileFormat,
3738
PexRequirements,
3839
Resolve,
3940
load_lockfile,
@@ -570,7 +571,7 @@ async def _determine_requirements_for_pex_from_targets(
570571
loaded_lockfile = await load_lockfile(
571572
LoadedLockfileRequest(chosen_resolve.lockfile), **implicitly()
572573
)
573-
pex_native_subsetting_supported = loaded_lockfile.is_pex_native
574+
pex_native_subsetting_supported = loaded_lockfile.lockfile_format == LockfileFormat.Pex
574575
if loaded_lockfile.as_constraints_strings:
575576
requirements = dataclasses.replace(
576577
requirements,

src/python/pants/backend/python/util_rules/pex_from_targets_test.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
)
5252
from pants.backend.python.util_rules.pex_requirements import (
5353
EntireLockfile,
54+
LockfileFormat,
5455
PexRequirements,
5556
Resolve,
5657
)
@@ -172,10 +173,12 @@ class RequirementMode(Enum):
172173
global_requirement_constraints = ["constraint1", "constraint2"]
173174

174175
resolve__pex = Resolve("pex", False)
175-
loaded_lockfile__pex = Mock(is_pex_native=True, as_constraints_strings=None)
176+
loaded_lockfile__pex = Mock(lockfile_format=LockfileFormat.Pex, as_constraints_strings=None)
176177
chosen_resolve__pex = Mock(lockfile=Mock())
177178
chosen_resolve__pex.name = "pex" # name has special meaning in Mock(), so must set it here.
178-
loaded_lockfile__not_pex = Mock(is_pex_native=False, as_constraints_strings=req_strings)
179+
loaded_lockfile__not_pex = Mock(
180+
lockfile_format=LockfileFormat.ConstraintsDeprecated, as_constraints_strings=req_strings
181+
)
179182
chosen_resolve__not_pex = Mock(lockfile=Mock())
180183
chosen_resolve__not_pex.name = "not_pex" # ditto.
181184

src/python/pants/backend/python/util_rules/pex_requirements.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import logging
99
from collections.abc import Iterable, Iterator
1010
from dataclasses import dataclass, field
11+
from enum import StrEnum, auto
1112
from typing import TYPE_CHECKING
1213
from urllib.parse import urlparse
1314

@@ -50,6 +51,13 @@
5051
logger = logging.getLogger(__name__)
5152

5253

54+
class LockfileFormat(StrEnum):
55+
Pex = auto()
56+
# The very old, deprecated constraints-based "lockfile" that should
57+
# be removed entirely.
58+
ConstraintsDeprecated = auto()
59+
60+
5361
@dataclass(frozen=True)
5462
class Resolve:
5563
# A named resolve for a "user lockfile".
@@ -101,10 +109,10 @@ class LoadedLockfile:
101109
# An estimate of the number of requirements in this lockfile, to be used as a heuristic for
102110
# available parallelism.
103111
requirement_estimate: int
104-
# True if the loaded lockfile is in PEX's native format.
105-
is_pex_native: bool
106-
# If !is_pex_native, the lockfile parsed as constraints strings, for use when the lockfile
107-
# needs to be subsetted (see #15031, ##12222).
112+
# The format of the loaded lockfile.
113+
lockfile_format: LockfileFormat
114+
# If lockfile_format is ConstraintsDeprecated, the lockfile parsed as constraints strings,
115+
# for use when the lockfile needs to be subsetted (see #15031, ##12222).
108116
as_constraints_strings: FrozenOrderedSet[str] | None
109117
# The original file or file content (which may not have identical content to the output
110118
# `lockfile_digest`).
@@ -225,7 +233,11 @@ async def load_lockfile(
225233

226234
lockfile_contents = await get_digest_contents(lockfile_digest)
227235
lock_bytes = lockfile_contents[0].content
228-
is_pex_native = is_probably_pex_json_lockfile(lock_bytes)
236+
lockfile_format = (
237+
LockfileFormat.Pex
238+
if is_probably_pex_json_lockfile(lock_bytes)
239+
else LockfileFormat.ConstraintsDeprecated
240+
)
229241
constraints_strings = None
230242

231243
metadata_url = PythonLockfileMetadata.metadata_location_for_lockfile(lockfile.url)
@@ -256,7 +268,7 @@ async def load_lockfile(
256268
pass
257269

258270
if not metadata:
259-
if is_pex_native:
271+
if lockfile_format == LockfileFormat.Pex:
260272
header_delimiter = "//"
261273
stripped_lock_bytes = strip_comments_from_pex_json_lockfile(lock_bytes)
262274
lockfile_digest = await create_digest(
@@ -286,7 +298,7 @@ async def load_lockfile(
286298
lockfile_path,
287299
metadata,
288300
requirement_estimate,
289-
is_pex_native,
301+
lockfile_format,
290302
constraints_strings,
291303
original_lockfile=lockfile,
292304
)

src/python/pants/backend/python/util_rules/pex_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
EntireLockfile,
4848
LoadedLockfile,
4949
Lockfile,
50+
LockfileFormat,
5051
PexRequirements,
5152
Resolve,
5253
ResolvePexConfig,
@@ -703,7 +704,9 @@ def create_loaded_lockfile(is_pex_lock: bool) -> LoadedLockfile:
703704
lockfile_path,
704705
metadata=None,
705706
requirement_estimate=2,
706-
is_pex_native=is_pex_lock,
707+
lockfile_format=LockfileFormat.Pex
708+
if is_pex_lock
709+
else LockfileFormat.ConstraintsDeprecated,
707710
as_constraints_strings=None,
708711
original_lockfile=lockfile_obj,
709712
)

src/python/pants/core/goals/update_build_files_test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
from pants.backend.python.util_rules import pex
1818
from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints
1919
from pants.backend.python.util_rules.lockfile_metadata import PythonLockfileMetadata
20-
from pants.backend.python.util_rules.pex_requirements import LoadedLockfile, Lockfile
20+
from pants.backend.python.util_rules.pex_requirements import (
21+
LoadedLockfile,
22+
Lockfile,
23+
LockfileFormat,
24+
)
2125
from pants.core.goals.update_build_files import (
2226
FormatWithBlackRequest,
2327
FormatWithBuildifierRequest,
@@ -185,7 +189,7 @@ def assert_ics(
185189
"black.lock",
186190
metadata=metadata,
187191
requirement_estimate=1,
188-
is_pex_native=True,
192+
lockfile_format=LockfileFormat.Pex,
189193
as_constraints_strings=None,
190194
original_lockfile=Lockfile(
191195
"black.lock", url_description_of_origin="foo", resolve_name="black"

0 commit comments

Comments
 (0)