Skip to content

Commit 40431e5

Browse files
Don't infer uv is used if there's no lockfile but pyproject.toml exists (#1163)
* Don't infer uv is used if there's no lockfile but `pyproject.toml` already exists * Use explicit case handling in backend checks for `print_how_to_use` * Add logic to cache the backend inference Pass tests, various version bumps * Fix typo * Rehabilitate `test_pre_commit_used_not_uv` test * Add more context to `call_subprocess` failures Don't assume the function will only be called on uv - previously the message said "Failed to run uv subprocess:". Now doesn't do that but gives the full call arguments * Bump minimum version of uv 0.6.8 -> 0.8.18 This is needed for the feature where uv will allow `[project]` to be missing from a `pyproject.toml` file
1 parent 1def16b commit 40431e5

30 files changed

Lines changed: 215 additions & 89 deletions

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
### Environment Setup (REQUIRED FIRST STEP)
1414
1. **ALWAYS run `uv sync` first** after cloning or before any development work. This installs all dependencies including dev, test, and doc groups.
1515
2. Python version: Use 3.10.18 (specified in `.python-version`). The CI tests 3.10-3.14, but development uses oldest supported version.
16-
3. uv version: Minimum 0.6.8 required (documented in README and `pyproject.toml`). Check with `uv --version`.
16+
3. uv version: Minimum 0.8.18 required (documented in README and `pyproject.toml`). Check with `uv --version`.
1717

1818
### Running Commands
1919
**Critical:** ALWAYS prefix Python commands with `uv run` to use the project environment:
@@ -166,7 +166,7 @@ See CONTRIBUTING.md Architecture section for detailed documentation and examples
166166

167167
**ci.yml** - Main CI pipeline (runs on push to main, PRs, and daily cron):
168168
- Matrix testing: Python 3.10-3.14 × (ubuntu/macos/windows)
169-
- Also tests min dependencies (3.10 + uv 0.6.8) and max dependencies (3.14 + latest)
169+
- Also tests min dependencies (3.10 + uv 0.8.18) and max dependencies (3.14 + latest)
170170
- Runs prek checks, pytest with coverage
171171
- CodSpeed benchmarking (Python 3.13)
172172
- Codecov upload (Python 3.14)

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ jobs:
105105
os: "ubuntu-latest"
106106
- dependencies: "min"
107107
python_version: "3.10"
108-
uv_version: "0.6.8"
108+
uv_version: "0.8.18"
109109
checks: "false"
110110
- dependencies: "max"
111111
python_version: "3.14"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Inspired by an [**R** package of the same name](https://usethis.r-lib.org/index.
3434
## 🧭 Installation
3535

3636
First, it is strongly recommended you [install the uv package manager](https://docs.astral.sh/uv/getting-started/installation/): this is a simple, documented process. If you're already using uv, make sure you're using at least
37-
version v0.6.8 (run `uv --version` to check, and `uv self update` to upgrade).
37+
version v0.8.18 (run `uv --version` to check, and `uv self update` to upgrade).
3838

3939
You can install usethis directly into the project environment:
4040

docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ pygments==2.19.1 \
200200
--hash=sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f \
201201
--hash=sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c
202202
# via mkdocs-material
203-
pymdown-extensions==10.14.3 \
204-
--hash=sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9 \
205-
--hash=sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b
203+
pymdown-extensions==10.19.1 \
204+
--hash=sha256:4969c691009a389fb1f9712dd8e7bd70dcc418d15a0faf70acb5117d022f7de8 \
205+
--hash=sha256:e8698a66055b1dc0dca2a7f2c9d0ea6f5faa7834a9c432e3535ab96c0c4e509b
206206
# via mkdocs-material
207207
python-dateutil==2.9.0.post0 \
208208
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \

docs/start/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# 🧭 Installation
22

33
First, it is strongly recommended you [install the uv package manager](https://docs.astral.sh/uv/getting-started/installation/): this is a simple, documented process. If you're already using uv, make sure you're using at least
4-
version v0.6.8 (run `uv --version` to check, and `uv self update` to upgrade).
4+
version v0.8.18 (run `uv --version` to check, and `uv self update` to upgrade).
55

66
You can install usethis directly into the project environment:
77

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ doc = [
7979
"mkdocs-material>=9.7.0",
8080
]
8181
uv = [
82-
"uv>=0.6.8",
82+
"uv>=0.8.18",
8383
]
8484

8585
[tool.hatch.version]
@@ -195,7 +195,7 @@ rules.invalid-assignment = "ignore"
195195
rules.possibly-missing-attribute = "ignore"
196196

197197
[tool.uv]
198-
required-version = ">=0.6.8" # Sync with README
198+
required-version = ">=0.8.18" # Sync with README
199199
default-groups = [ "test", "dev", "doc" ]
200200
link-mode = "symlink"
201201

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,9 +755,9 @@ pyinstrument==5.1.1 \
755755
--hash=sha256:f2d640230b71c6d9ac8f27a9c5cd07fc8a6acad9196d1e48d9c33658b176fb80 \
756756
--hash=sha256:f4912edf01912792d2f44dfc43d3f041acc7ea634d0300b3394711963a431d1b \
757757
--hash=sha256:fa254f269a72a007b5d02c18cd4b67081e0efabbd33e18acdbd5e3be905afa06
758-
pymdown-extensions==10.14.3 \
759-
--hash=sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9 \
760-
--hash=sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b
758+
pymdown-extensions==10.19.1 \
759+
--hash=sha256:4969c691009a389fb1f9712dd8e7bd70dcc418d15a0faf70acb5117d022f7de8 \
760+
--hash=sha256:e8698a66055b1dc0dca2a7f2c9d0ea6f5faa7834a9c432e3535ab96c0c4e509b
761761
# via mkdocs-material
762762
pyright==1.1.403 \
763763
--hash=sha256:3ab69b9f41c67fb5bbb4d7a36243256f0d549ed3608678d381d5f51863921104 \

src/usethis/_config.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from contextlib import contextmanager
44
from dataclasses import dataclass
55
from pathlib import Path
6-
from typing import TYPE_CHECKING
6+
from typing import TYPE_CHECKING, Literal
77

88
from usethis._types.backend import BackendEnum
99

@@ -46,12 +46,13 @@ class UsethisConfig:
4646
alert_only: bool = False
4747
instruct_only: bool = False
4848
backend: BackendEnum = BackendEnum(BACKEND_DEFAULT) # noqa: RUF009
49+
inferred_backend: Literal[BackendEnum.uv, BackendEnum.none] | None = None
4950
disable_pre_commit: bool = False
5051
subprocess_verbose: bool = False
5152
project_dir: Path | None = None
5253

5354
@contextmanager
54-
def set( # noqa: PLR0913
55+
def set( # noqa: PLR0913, PLR0915
5556
self,
5657
*,
5758
offline: bool | None = None,
@@ -71,6 +72,7 @@ def set( # noqa: PLR0913
7172
old_alert_only = self.alert_only
7273
old_instruct_only = self.instruct_only
7374
old_backend = self.backend
75+
old_inferred_backend = self.inferred_backend
7476
old_disable_pre_commit = self.disable_pre_commit
7577
old_subprocess_verbose = self.subprocess_verbose
7678
old_project_dir = self.project_dir
@@ -100,6 +102,8 @@ def set( # noqa: PLR0913
100102
self.alert_only = alert_only
101103
self.instruct_only = instruct_only
102104
self.backend = backend
105+
if backend is not BackendEnum.auto:
106+
self.inferred_backend = backend
103107
self.disable_pre_commit = disable_pre_commit
104108
self.subprocess_verbose = subprocess_verbose
105109
if isinstance(project_dir, str):
@@ -112,6 +116,7 @@ def set( # noqa: PLR0913
112116
self.alert_only = old_alert_only
113117
self.instruct_only = old_instruct_only
114118
self.backend = old_backend
119+
self.inferred_backend = old_inferred_backend
115120
self.disable_pre_commit = old_disable_pre_commit
116121
self.subprocess_verbose = old_subprocess_verbose
117122
self.project_dir = old_project_dir

src/usethis/_integrations/backend/dispatch.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@
1111

1212

1313
def get_backend() -> Literal[BackendEnum.uv, BackendEnum.none]:
14-
if usethis_config.backend is not BackendEnum.auto:
15-
return usethis_config.backend
14+
# Effectively we cache the inference, storing it in usethis_config.
15+
if usethis_config.inferred_backend is not None:
16+
return usethis_config.inferred_backend
1617

17-
if is_poetry_used():
18+
if usethis_config.backend is not BackendEnum.auto:
19+
usethis_config.inferred_backend = usethis_config.backend
20+
elif is_poetry_used():
1821
warn_print(
1922
"This project is using Poetry, which is not fully supported by usethis."
2023
)
21-
return BackendEnum.none
22-
23-
if is_uv_used() or is_uv_available():
24-
return BackendEnum.uv
24+
usethis_config.inferred_backend = BackendEnum.none
25+
elif is_uv_used():
26+
usethis_config.inferred_backend = BackendEnum.uv
27+
elif not (usethis_config.cpd() / "pyproject.toml").exists() and is_uv_available():
28+
# If there's not likely to be a backend in use yet, and uv is available.
29+
usethis_config.inferred_backend = BackendEnum.uv
30+
else:
31+
usethis_config.inferred_backend = BackendEnum.none
2532

26-
return BackendEnum.none
33+
return usethis_config.inferred_backend

src/usethis/_integrations/backend/uv/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from usethis._integrations.backend.uv.call import call_uv_subprocess
44
from usethis._integrations.backend.uv.errors import UVSubprocessFailedError
55

6-
FALLBACK_UV_VERSION = "0.9.9"
6+
FALLBACK_UV_VERSION = "0.9.18"
77

88

99
def get_uv_version() -> str:

0 commit comments

Comments
 (0)