Skip to content

Commit 7a4549a

Browse files
fix: raise error when both --frozen and --no-sync are set
Instead of silently having --frozen take precedence, raise a UsethisError when both flags are set simultaneously. These flags are mutually exclusive since --frozen prevents both lockfile updates and syncing, while --no-sync only prevents syncing. Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/bbee573e-012b-4649-8923-7e4e46490fcf Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com>
1 parent 0ac0fbc commit 7a4549a

4 files changed

Lines changed: 37 additions & 27 deletions

File tree

src/usethis/_backend/uv/call.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,10 @@ def call_uv_subprocess(args: list[str], change_toml: bool) -> str:
5353
"run",
5454
}:
5555
new_args = ["uv", args[0], "--frozen", *args[1:]]
56-
elif (
57-
not usethis_config.frozen
58-
and usethis_config.no_sync
59-
and args[0]
60-
in {
61-
"add",
62-
"remove",
63-
}
64-
):
56+
elif usethis_config.no_sync and args[0] in {
57+
"add",
58+
"remove",
59+
}:
6560
new_args = ["uv", args[0], "--no-sync", *args[1:]]
6661
else:
6762
new_args = ["uv", *args]

src/usethis/_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from usethis._types.backend import BackendEnum
1111
from usethis._types.build_backend import BuildBackendEnum
12+
from usethis.errors import UsethisError
1213

1314
if TYPE_CHECKING:
1415
from collections.abc import Generator
@@ -114,6 +115,10 @@ def set( # noqa: PLR0912, PLR0913, PLR0915
114115
if project_dir is None:
115116
project_dir = old_project_dir
116117

118+
if frozen and no_sync:
119+
msg = "Cannot use both --frozen and --no-sync at the same time."
120+
raise UsethisError(msg)
121+
117122
self.offline = offline
118123
self.quiet = quiet
119124
self.frozen = frozen

tests/usethis/_backend/uv/test_call.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from usethis._config import usethis_config
99
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
1010
from usethis._test import change_cwd
11+
from usethis.errors import UsethisError
1112

1213

1314
class TestCallUVSubprocess:
@@ -84,9 +85,7 @@ def mock_call_subprocess(args: list[str], *, cwd: Path | None = None) -> str:
8485
["remove", "--group", "test", "pytest"], change_toml=False
8586
) == ("uv remove --quiet --no-sync --group test pytest")
8687

87-
def test_frozen_takes_precedence_over_no_sync(
88-
self, monkeypatch: pytest.MonkeyPatch
89-
):
88+
def test_frozen_and_no_sync_raises(self, monkeypatch: pytest.MonkeyPatch):
9089
# Arrange
9190
def mock_call_subprocess(args: list[str], *, cwd: Path | None = None) -> str:
9291
_ = cwd
@@ -98,20 +97,11 @@ def mock_call_subprocess(args: list[str], *, cwd: Path | None = None) -> str:
9897
mock_call_subprocess,
9998
)
10099

101-
with usethis_config.set(no_sync=True, frozen=True, offline=False):
102-
# Act, Assert
103-
# frozen should take precedence, --no-sync should not appear
104-
result = call_uv_subprocess(
105-
["add", "--group", "test", "pytest"], change_toml=False
106-
)
107-
assert "--frozen" in result
108-
assert "--no-sync" not in result
109-
110-
result = call_uv_subprocess(
111-
["remove", "--group", "test", "pytest"], change_toml=False
112-
)
113-
assert "--frozen" in result
114-
assert "--no-sync" not in result
100+
with (
101+
pytest.raises(UsethisError, match="Cannot use both --frozen and --no-sync"),
102+
usethis_config.set(no_sync=True, frozen=True, offline=False),
103+
):
104+
call_uv_subprocess(["add", "--group", "test", "pytest"], change_toml=False)
115105

116106
@pytest.mark.usefixtures("_vary_network_conn")
117107
def test_handle_missing_version(

tests/usethis/test_config.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from usethis._config import UsethisConfig, usethis_config
77
from usethis._test import change_cwd
88
from usethis._types.backend import BackendEnum
9-
from usethis.errors import ForbiddenBackendError
9+
from usethis.errors import ForbiddenBackendError, UsethisError
1010

1111

1212
class TestUsethisConfig:
@@ -55,3 +55,23 @@ def test_does_not_raise_error_when_enabled(self):
5555
output = call_uv_subprocess(["python", "list"], change_toml=False)
5656

5757
assert output is not None
58+
59+
class TestFrozenAndNoSync:
60+
def test_raises_error_when_both_set(self):
61+
with (
62+
pytest.raises(
63+
UsethisError, match="Cannot use both --frozen and --no-sync"
64+
),
65+
usethis_config.set(frozen=True, no_sync=True),
66+
):
67+
pass
68+
69+
def test_no_error_when_only_frozen(self):
70+
with usethis_config.set(frozen=True, no_sync=False):
71+
assert usethis_config.frozen
72+
assert not usethis_config.no_sync
73+
74+
def test_no_error_when_only_no_sync(self):
75+
with usethis_config.set(frozen=False, no_sync=True):
76+
assert not usethis_config.frozen
77+
assert usethis_config.no_sync

0 commit comments

Comments
 (0)