Skip to content

Commit a1e25e9

Browse files
Merge branch 'main' into copilot/implement-usethis-arch
2 parents 77a37ae + 95d1f5c commit a1e25e9

52 files changed

Lines changed: 476 additions & 29 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@
188188

189189
### 📚 Documentation
190190

191-
- The [FAQ](https://usethis.readthedocs.io/en/stable/faq/) now explicitly explains whether `uv` is necessary to use `usethis`, and gives some guidance for Poetry users.
191+
- The [FAQ](https://usethis.readthedocs.io/en/stable/faq/) now explicitly explains whether uv is necessary to use `usethis`, and gives some guidance for Poetry users.
192192

193193
- Instructions for implementing a new `usethis badge` command in usethis have been added to the CONTRIBUTING.md file.
194194

@@ -230,11 +230,11 @@
230230

231231
### 🚀 New Features
232232

233-
- Most commands now accept a `--backend` option to specify the package manager backend to use. Up to this point, `uv` was the only supported backend. Now, a `--backend=none` option is available to use usethis without `uv`. This is a step toward supporting other backends such as Poetry in the future. When unspecified, heuristics will be used to determine the backend.
233+
- Most commands now accept a `--backend` option to specify the package manager backend to use. Up to this point, uv was the only supported backend. Now, a `--backend=none` option is available to use usethis without uv. This is a step toward supporting other backends such as Poetry in the future. When unspecified, heuristics will be used to determine the backend.
234234

235-
- The use of `pyproject.toml` in a project is no longer assumed or imposed on a project when not using the `uv` backend.
235+
- The use of `pyproject.toml` in a project is no longer assumed or imposed on a project when not using the uv backend.
236236

237-
- `pre-commit` configurations are now more conventional, preferring URL-based repo configuration instead of local repos with `language: system`. The previous behaviour was designed to ensure synchronization of versions between the `uv` lockfile and the `pre-commit` configuration, but this is now provided by the `sync-with-uv` pre-commit hook, which is added automatically when using `pre-commit` with `uv`.
237+
- `pre-commit` configurations are now more conventional, preferring URL-based repo configuration instead of local repos with `language: system`. The previous behaviour was designed to ensure synchronization of versions between the uv lockfile and the `pre-commit` configuration, but this is now provided by the `sync-with-uv` pre-commit hook, which is added automatically when using `pre-commit` with uv.
238238

239239
- When using `usethis author`, a message with the author's name is now outputted in the console.
240240

@@ -272,7 +272,7 @@
272272

273273
### 🔧 Internal Changes
274274

275-
- The CI configuration has been overhauled. `uv` is used in more conventional ways. A runner has been added for bleeding edge dependency versions. The CI now runs on a cron schedule. `zizmor` has been added for security scanning. Permissions are more tightly scoped and explained. All actions have been bumped to their latest versions.
275+
- The CI configuration has been overhauled. uv is used in more conventional ways. A runner has been added for bleeding edge dependency versions. The CI now runs on a cron schedule. `zizmor` has been added for security scanning. Permissions are more tightly scoped and explained. All actions have been bumped to their latest versions.
276276

277277
- The pre-commit hooks have been migrated to use `prek` rather than `pre-commit` for development.
278278

@@ -286,7 +286,7 @@
286286

287287
### 🐞 Bug Fixes
288288

289-
- When subprocessing `uv`, the `usethis init` command will no longer use the default for `--build-backend`, and instead will always explicitly use `hatch`. This may change in the future if the default supported build backend for `usethis` becomes `uv_build`, which is the new default for `uv` v0.8.0. This change avoids creating broken config which mixes `uv_build` with `hatch` config.
289+
- When subprocessing uv, the `usethis init` command will no longer use the default for `--build-backend`, and instead will always explicitly use `hatch`. This may change in the future if the default supported build backend for `usethis` becomes `uv_build`, which is the new default for uv v0.8.0. This change avoids creating broken config which mixes `uv_build` with `hatch` config.
290290

291291
- When adding Import Linter while using Ruff, the `INP` rules are selected, but ignored for the tests directory. However, no message would be displayed in cases where those rules were already selected but not already ignored. Now, a message will be displayed in this case.
292292

@@ -316,7 +316,7 @@
316316

317317
### 🔧 Internal Changes
318318

319-
- Changes to the `CI` and the test suite have been made to support `uv` v0.8.0. Newer features of `uv` are now required in the CI configuration, meaning the lowest tested version of `uv` is now v0.6.8. Going forward, it is not recommended to use older versions of `uv` with `usethis`.
319+
- Changes to the CI and the test suite have been made to support uv v0.8.0. Newer features of uv are now required in the CI configuration, meaning the lowest tested version of uv is now v0.6.8. Going forward, it is not recommended to use older versions of uv with `usethis`.
320320

321321
## 0.15.0
322322

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
[![usethis](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/usethis-python/usethis-python/main/assets/badge/v1.json)](https://github.com/usethis-python/usethis-python)
88
[![PyPI Version](https://img.shields.io/pypi/v/usethis.svg)](https://pypi.python.org/pypi/usethis)
9-
![PyPI License](https://img.shields.io/pypi/l/usethis.svg)
9+
[![PyPI License](https://img.shields.io/pypi/l/usethis.svg)](https://github.com/usethis-python/usethis-python?tab=MIT-1-ov-file)
1010
[![PyPI Supported Versions](https://img.shields.io/pypi/pyversions/usethis.svg)](https://pypi.python.org/pypi/usethis)
1111
[![Docs](https://app.readthedocs.org/projects/usethis/badge/?version=stable)](https://usethis.readthedocs.io/en/stable/)
1212

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ reportAny = false
211211
reportAssignmentType = false
212212
reportCallInDefaultInitializer = false
213213
reportExplicitAny = false
214-
reportImplicitOverride = false
215214
reportImplicitStringConcatenation = false
216215
reportMissingParameterType = false
217216
reportMissingTypeArgument = false

src/usethis/_backend/uv/toml.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from pathlib import Path
22

3+
from typing_extensions import override
4+
35
from usethis._file.toml.io_ import TOMLFileManager
46

57

68
class UVTOMLManager(TOMLFileManager):
79
"""Class to manage the uv.toml file."""
810

911
@property
12+
@override
1013
def relative_path(self) -> Path:
1114
return Path("uv.toml")

src/usethis/_config_file.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from pathlib import Path
55
from typing import TYPE_CHECKING
66

7+
from typing_extensions import override
8+
79
from usethis._backend.uv.toml import UVTOMLManager
810
from usethis._file.ini.io_ import INIFileManager
911
from usethis._file.pyproject_toml.io_ import PyprojectTOMLManager
@@ -45,6 +47,7 @@ class DotCodespellRCManager(INIFileManager):
4547
"""Class to manage the .codespellrc file."""
4648

4749
@property
50+
@override
4851
def relative_path(self) -> Path:
4952
return Path(".codespellrc")
5053

@@ -53,6 +56,7 @@ class DotCoverageRCManager(INIFileManager):
5356
"""Class to manage the .coveragerc file."""
5457

5558
@property
59+
@override
5660
def relative_path(self) -> Path:
5761
return Path(".coveragerc")
5862

@@ -61,6 +65,7 @@ class DotCoverageRCTOMLManager(TOMLFileManager):
6165
"""Class to manage the .coveragerc.toml file."""
6266

6367
@property
68+
@override
6469
def relative_path(self) -> Path:
6570
return Path(".coveragerc.toml")
6671

@@ -69,6 +74,7 @@ class DotImportLinterManager(INIFileManager):
6974
"""Class to manage the .importlinter file."""
7075

7176
@property
77+
@override
7278
def relative_path(self) -> Path:
7379
return Path(".importlinter")
7480

@@ -77,6 +83,7 @@ class DotPytestINIManager(INIFileManager):
7783
"""Class to manage the .pytest.ini file."""
7884

7985
@property
86+
@override
8087
def relative_path(self) -> Path:
8188
return Path(".pytest.ini")
8289

@@ -85,6 +92,7 @@ class DotRuffTOMLManager(TOMLFileManager):
8592
"""Class to manage the .ruff.toml file."""
8693

8794
@property
95+
@override
8896
def relative_path(self) -> Path:
8997
return Path(".ruff.toml")
9098

@@ -93,6 +101,7 @@ class MkDocsYMLManager(YAMLFileManager):
93101
"""Class to manage the mkdocs.yml file."""
94102

95103
@property
104+
@override
96105
def relative_path(self) -> Path:
97106
return Path("mkdocs.yml")
98107

@@ -101,6 +110,7 @@ class PytestINIManager(INIFileManager):
101110
"""Class to manage the pytest.ini file."""
102111

103112
@property
113+
@override
104114
def relative_path(self) -> Path:
105115
return Path("pytest.ini")
106116

@@ -109,6 +119,7 @@ class RuffTOMLManager(TOMLFileManager):
109119
"""Class to manage the ruff.toml file."""
110120

111121
@property
122+
@override
112123
def relative_path(self) -> Path:
113124
return Path("ruff.toml")
114125

@@ -117,6 +128,7 @@ class ToxINIManager(INIFileManager):
117128
"""Class to manage the tox.ini file."""
118129

119130
@property
131+
@override
120132
def relative_path(self) -> Path:
121133
return Path("tox.ini")
122134

@@ -125,6 +137,7 @@ class DotTyTOMLManager(TOMLFileManager):
125137
"""Class to manage the .ty.toml file."""
126138

127139
@property
140+
@override
128141
def relative_path(self) -> Path:
129142
return Path(".ty.toml")
130143

@@ -133,5 +146,6 @@ class TyTOMLManager(TOMLFileManager):
133146
"""Class to manage the ty.toml file."""
134147

135148
@property
149+
@override
136150
def relative_path(self) -> Path:
137151
return Path("ty.toml")

src/usethis/_file/ini/io_.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from configupdater import ConfigUpdater as INIDocument
99
from configupdater import Option, Section
1010
from pydantic import TypeAdapter
11-
from typing_extensions import assert_never
11+
from typing_extensions import assert_never, override
1212

1313
from usethis._file.ini.errors import (
1414
INIDecodeError,
@@ -42,12 +42,14 @@
4242
class INIFileManager(KeyValueFileManager, metaclass=ABCMeta):
4343
_content_by_path: ClassVar[dict[Path, INIDocument | None]] = {}
4444

45+
@override
4546
def __enter__(self) -> Self:
4647
try:
4748
return super().__enter__()
4849
except UnexpectedFileOpenError as err:
4950
raise UnexpectedINIOpenError(err) from None
5051

52+
@override
5153
def read_file(self) -> INIDocument:
5254
try:
5355
return super().read_file()
@@ -59,38 +61,45 @@ def read_file(self) -> INIDocument:
5961
msg = f"Failed to decode '{self.name}':\n{err}"
6062
raise INIDecodeError(msg) from None
6163

64+
@override
6265
def _dump_content(self) -> str:
6366
if self._content is None:
6467
msg = "Content is None, cannot dump."
6568
raise ValueError(msg)
6669

6770
return str(self._content)
6871

72+
@override
6973
def _parse_content(self, content: str) -> INIDocument:
7074
updater = INIDocument()
7175
updater.read_string(content)
7276
return updater
7377

78+
@override
7479
def get(self) -> INIDocument:
7580
return super().get()
7681

82+
@override
7783
def commit(self, document: INIDocument) -> None:
7884
return super().commit(document)
7985

8086
@property
87+
@override
8188
def _content(self) -> INIDocument | None:
8289
return super()._content
8390

8491
@_content.setter
8592
def _content(self, value: INIDocument | None) -> None:
8693
self._content_by_path[self.path] = value
8794

95+
@override
8896
def _validate_lock(self) -> None:
8997
try:
9098
super()._validate_lock()
9199
except UnexpectedFileIOError as err:
92100
raise UnexpectedINIIOError(err) from None
93101

102+
@override
94103
def __contains__(self, keys: Sequence[Key]) -> bool:
95104
"""Check if the INI file contains a value at the given key.
96105
@@ -114,6 +123,7 @@ def __contains__(self, keys: Sequence[Key]) -> bool:
114123
return True
115124
return False
116125

126+
@override
117127
def __getitem__(self, item: Sequence[Key]) -> object:
118128
keys = item
119129

@@ -146,6 +156,7 @@ def __getitem__(self, item: Sequence[Key]) -> object:
146156
)
147157
raise KeyError(msg)
148158

159+
@override
149160
def set_value(
150161
self,
151162
*,
@@ -338,6 +349,7 @@ def _validated_append(
338349
else:
339350
root[section_key][option_key].append(value)
340351

352+
@override
341353
def __delitem__(self, keys: Sequence[Key]) -> None:
342354
"""Delete a value in the INI file.
343355
@@ -417,6 +429,7 @@ def _delete_strkeys(self, strkeys: Sequence[str]) -> None:
417429

418430
self.commit(root)
419431

432+
@override
420433
def extend_list(self, *, keys: Sequence[Key], values: Sequence[object]) -> None:
421434
"""Extend a list in the INI file.
422435
@@ -495,6 +508,7 @@ def _remove_from_list_in_option(
495508
elif len(new_values) > 1:
496509
root[section_key][option_key].set_values(new_values)
497510

511+
@override
498512
def remove_from_list(
499513
self, *, keys: Sequence[Key], values: Sequence[object]
500514
) -> None:

src/usethis/_file/pyproject_toml/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from typing_extensions import override
4+
35
from usethis._file.toml.errors import (
46
TOMLDecodeError,
57
TOMLError,
@@ -28,6 +30,7 @@ class PyprojectTOMLDecodeError(TOMLDecodeError, PyprojectTOMLError):
2830
"""Raised when a pyproject.toml file cannot be decoded."""
2931

3032
@property
33+
@override
3134
def name(self) -> str:
3235
"""The name of the file that could not be decoded."""
3336
return "pyproject.toml"
@@ -45,6 +48,7 @@ class PyprojectTOMLProjectSectionError(FileConfigError, PyprojectTOMLError):
4548
"""Raised when the 'project' section is missing or invalid in 'pyproject.toml'."""
4649

4750
@property
51+
@override
4852
def name(self) -> str:
4953
"""The name of the file that has a configuration error."""
5054
return "pyproject.toml"

src/usethis/_file/pyproject_toml/io_.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from pathlib import Path
44
from typing import TYPE_CHECKING
55

6+
from typing_extensions import override
7+
68
from usethis._file.pyproject_toml.errors import (
79
PyprojectTOMLDecodeError,
810
PyprojectTOMLNotFoundError,
@@ -35,15 +37,18 @@ class PyprojectTOMLManager(TOMLFileManager):
3537
"""Manages the pyproject.toml file."""
3638

3739
@property
40+
@override
3841
def relative_path(self) -> Path:
3942
return Path("pyproject.toml")
4043

44+
@override
4145
def __enter__(self) -> Self:
4246
try:
4347
return super().__enter__()
4448
except UnexpectedTOMLOpenError as err:
4549
raise UnexpectedPyprojectTOMLOpenError(err) from None
4650

51+
@override
4752
def read_file(self) -> TOMLDocument:
4853
try:
4954
return super().read_file()
@@ -54,12 +59,14 @@ def read_file(self) -> TOMLDocument:
5459
except TOMLDecodeError as err:
5560
raise PyprojectTOMLDecodeError(err) from None
5661

62+
@override
5763
def _validate_lock(self) -> None:
5864
try:
5965
super()._validate_lock()
6066
except UnexpectedTOMLIOError as err:
6167
raise UnexpectedPyprojectTOMLIOError(err) from None
6268

69+
@override
6370
def set_value(
6471
self, *, keys: Sequence[Key], value: Any, exists_ok: bool = False
6572
) -> None:
@@ -69,6 +76,7 @@ def set_value(
6976
except TOMLValueAlreadySetError as err:
7077
raise PyprojectTOMLValueAlreadySetError(err) from None
7178

79+
@override
7280
def __delitem__(self, keys: Sequence[Key]) -> None:
7381
"""Remove a value from the pyproject.toml configuration file."""
7482
try:

src/usethis/_file/setup_cfg/errors.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from typing_extensions import override
4+
35
from usethis._file.ini.errors import (
46
INIDecodeError,
57
INIError,
@@ -23,6 +25,7 @@ class SetupCFGDecodeError(INIDecodeError, SetupCFGError):
2325
"""Raised when a setup.cfg file cannot be decoded."""
2426

2527
@property
28+
@override
2629
def name(self) -> str:
2730
"""The name of the file that could not be decoded."""
2831
return "setup.cfg"

0 commit comments

Comments
 (0)