pre-commit-uv 4.2.0__tar.gz → 4.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/PKG-INFO +2 -7
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/pyproject.toml +37 -23
- pre_commit_uv-4.2.2/src/pre_commit_uv/__init__.py +174 -0
- pre_commit_uv-4.2.2/tests/test_health_check.py +77 -0
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/tests/test_main.py +18 -2
- pre_commit_uv-4.2.0/src/pre_commit_uv/__init__.py +0 -128
- pre_commit_uv-4.2.0/tox.ini +0 -70
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/.gitignore +0 -0
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/LICENSE.txt +0 -0
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/README.md +0 -0
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/src/pre_commit_uv/py.typed +0 -0
- {pre_commit_uv-4.2.0 → pre_commit_uv-4.2.2}/src/pre_commit_uv_patch.pth +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pre-commit-uv
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.2
|
|
4
4
|
Summary: Run pre-commit with uv
|
|
5
5
|
Project-URL: Bug Tracker, https://github.com/tox-dev/pre-commit-uv/issues
|
|
6
|
+
Project-URL: Source Code, https://github.com/tox-dev/pre-commit-uv
|
|
6
7
|
Project-URL: Changelog, https://github.com/tox-dev/pre-commit-uv/releases
|
|
7
8
|
Project-URL: Documentation, https://github.com/tox-dev/pre-commit-uv/
|
|
8
|
-
Project-URL: Source Code, https://github.com/tox-dev/pre-commit-uv
|
|
9
9
|
Author-email: Bernat Gabor <gaborjbernat@gmail.com>
|
|
10
10
|
License: Permission is hereby granted, free of charge, to any person obtaining a
|
|
11
11
|
copy of this software and associated documentation files (the
|
|
@@ -39,11 +39,6 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
39
39
|
Requires-Python: >=3.10
|
|
40
40
|
Requires-Dist: pre-commit>=4.3
|
|
41
41
|
Requires-Dist: uv>=0.9.1
|
|
42
|
-
Provides-Extra: testing
|
|
43
|
-
Requires-Dist: covdefaults>=2.3; extra == 'testing'
|
|
44
|
-
Requires-Dist: pytest-cov>=7; extra == 'testing'
|
|
45
|
-
Requires-Dist: pytest-mock>=3.15.1; extra == 'testing'
|
|
46
|
-
Requires-Dist: pytest>=8.4.2; extra == 'testing'
|
|
47
42
|
Description-Content-Type: text/markdown
|
|
48
43
|
|
|
49
44
|
# pre-commit-uv
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
build-backend = "hatchling.build"
|
|
3
3
|
requires = [
|
|
4
4
|
"hatch-vcs>=0.5",
|
|
5
|
-
"hatchling>=1.
|
|
5
|
+
"hatchling>=1.28",
|
|
6
6
|
]
|
|
7
7
|
|
|
8
8
|
[project]
|
|
@@ -36,18 +36,39 @@ dependencies = [
|
|
|
36
36
|
"pre-commit>=4.3",
|
|
37
37
|
"uv>=0.9.1",
|
|
38
38
|
]
|
|
39
|
-
|
|
39
|
+
urls."Bug Tracker" = "https://github.com/tox-dev/pre-commit-uv/issues"
|
|
40
|
+
urls."Source Code" = "https://github.com/tox-dev/pre-commit-uv"
|
|
41
|
+
urls.Changelog = "https://github.com/tox-dev/pre-commit-uv/releases"
|
|
42
|
+
urls.Documentation = "https://github.com/tox-dev/pre-commit-uv/"
|
|
43
|
+
|
|
44
|
+
[dependency-groups]
|
|
45
|
+
dev = [
|
|
46
|
+
{ include-group = "lint" },
|
|
47
|
+
{ include-group = "pkg-meta" },
|
|
48
|
+
{ include-group = "test" },
|
|
49
|
+
{ include-group = "type" },
|
|
50
|
+
]
|
|
51
|
+
test = [
|
|
40
52
|
"covdefaults>=2.3",
|
|
41
53
|
"pytest>=8.4.2",
|
|
42
54
|
"pytest-cov>=7",
|
|
43
55
|
"pytest-mock>=3.15.1",
|
|
44
56
|
]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
type = [
|
|
58
|
+
"ty>=0.0.17",
|
|
59
|
+
{ include-group = "test" },
|
|
60
|
+
]
|
|
61
|
+
lint = [
|
|
62
|
+
"pre-commit-uv>=4.2",
|
|
63
|
+
]
|
|
64
|
+
pkg-meta = [
|
|
65
|
+
"check-wheel-contents>=0.6.3",
|
|
66
|
+
"twine>=6.2",
|
|
67
|
+
"uv>=0.10.2",
|
|
68
|
+
]
|
|
49
69
|
|
|
50
70
|
[tool.hatch]
|
|
71
|
+
version.source = "vcs"
|
|
51
72
|
build.dev-mode-dirs = [
|
|
52
73
|
"src",
|
|
53
74
|
]
|
|
@@ -58,7 +79,6 @@ build.targets.sdist.include = [
|
|
|
58
79
|
]
|
|
59
80
|
build.targets.wheel.only-include = [ "src" ]
|
|
60
81
|
build.targets.wheel.sources = [ "src" ]
|
|
61
|
-
version.source = "vcs"
|
|
62
82
|
|
|
63
83
|
[tool.ruff]
|
|
64
84
|
line-length = 120
|
|
@@ -69,7 +89,6 @@ lint.select = [
|
|
|
69
89
|
"ALL",
|
|
70
90
|
]
|
|
71
91
|
lint.ignore = [
|
|
72
|
-
"ANN101", # no type annotation for self
|
|
73
92
|
"ANN401", # allow Any as type annotation
|
|
74
93
|
"COM812", # Conflict with formatter
|
|
75
94
|
"CPY", # No copyright statements
|
|
@@ -77,6 +96,7 @@ lint.ignore = [
|
|
|
77
96
|
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
|
|
78
97
|
"DOC501", # not working with Sphinx
|
|
79
98
|
"ISC001", # Conflict with formatter
|
|
99
|
+
"RUF067", # `__init__` module should only contain docstrings and re-exports
|
|
80
100
|
"S104", # Possible binding to all interfaces
|
|
81
101
|
]
|
|
82
102
|
lint.per-file-ignores."tests/**/*.py" = [
|
|
@@ -104,14 +124,19 @@ count = true
|
|
|
104
124
|
[tool.pyproject-fmt]
|
|
105
125
|
max_supported_python = "3.14"
|
|
106
126
|
|
|
127
|
+
[tool.ty]
|
|
128
|
+
environment.python-version = "3.14"
|
|
129
|
+
|
|
107
130
|
[tool.pytest]
|
|
108
131
|
ini_options.testpaths = [
|
|
109
132
|
"tests",
|
|
110
133
|
]
|
|
111
134
|
|
|
112
135
|
[tool.coverage]
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
run.parallel = true
|
|
137
|
+
run.plugins = [
|
|
138
|
+
"covdefaults",
|
|
139
|
+
]
|
|
115
140
|
paths.source = [
|
|
116
141
|
"src",
|
|
117
142
|
".tox/*/.venv/lib/*/site-packages",
|
|
@@ -122,16 +147,5 @@ paths.source = [
|
|
|
122
147
|
"**\\src",
|
|
123
148
|
]
|
|
124
149
|
report.fail_under = 63
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"covdefaults",
|
|
128
|
-
]
|
|
129
|
-
|
|
130
|
-
[tool.mypy]
|
|
131
|
-
show_error_codes = true
|
|
132
|
-
strict = true
|
|
133
|
-
overrides = [
|
|
134
|
-
{ module = [
|
|
135
|
-
"pre_commit.*",
|
|
136
|
-
], ignore_missing_imports = true },
|
|
137
|
-
]
|
|
150
|
+
html.show_contexts = true
|
|
151
|
+
html.skip_covered = false
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""Package root."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# only import built-ins at top level to avoid interpreter startup overhead
|
|
6
|
+
import os
|
|
7
|
+
import pathlib
|
|
8
|
+
import sys
|
|
9
|
+
from typing import TYPE_CHECKING, cast
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Callable, Sequence
|
|
13
|
+
from typing import Protocol
|
|
14
|
+
|
|
15
|
+
from pre_commit.prefix import Prefix
|
|
16
|
+
|
|
17
|
+
class _PatchablePython(Protocol):
|
|
18
|
+
install_environment: Callable[[Prefix, str, Sequence[str]], None]
|
|
19
|
+
health_check: Callable[[Prefix, str], str | None]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_original_main = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _is_calling_pre_commit() -> bool:
|
|
26
|
+
if "FORCE_PRE_COMMIT_UV_PATCH" in os.environ:
|
|
27
|
+
return True
|
|
28
|
+
if not sys.argv or not sys.argv[0]:
|
|
29
|
+
return False
|
|
30
|
+
# case when pre-commit is called via python -m pre_commit
|
|
31
|
+
if sys.argv[0] == "-m" and "-m" in sys.orig_argv and "pre_commit" in sys.orig_argv:
|
|
32
|
+
return True
|
|
33
|
+
calling = sys.argv[1] if sys.argv[0] == sys.executable and len(sys.argv) >= 1 else sys.argv[0]
|
|
34
|
+
# case when pre-commit is called directly
|
|
35
|
+
if os.path.split(calling)[1] == f"pre-commit{'.exe' if sys.platform == 'win32' else ''}":
|
|
36
|
+
return True
|
|
37
|
+
# case when pre-commit is called due to a git commit
|
|
38
|
+
return "-m" in sys.argv and "hook-impl" in sys.argv
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _patch() -> None:
|
|
42
|
+
global _original_main
|
|
43
|
+
if _original_main is not None: # already patched, nothing more to do
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
if _is_calling_pre_commit() and os.environ.get("DISABLE_PRE_COMMIT_UV_PATCH") is None:
|
|
47
|
+
from pre_commit import main # noqa: PLC0415
|
|
48
|
+
|
|
49
|
+
_original_main, main.main = main.main, _new_main # ty: ignore[invalid-assignment]
|
|
50
|
+
if "--version" in sys.argv:
|
|
51
|
+
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
52
|
+
|
|
53
|
+
from pre_commit import constants # noqa: PLC0415
|
|
54
|
+
|
|
55
|
+
constants.VERSION = (
|
|
56
|
+
f"{constants.VERSION} ("
|
|
57
|
+
f"pre-commit-uv={_metadata_version('pre-commit-uv')}, "
|
|
58
|
+
f"uv={_metadata_version('uv')}"
|
|
59
|
+
f")"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _new_main(argv: Sequence[str] | None = None) -> int:
|
|
64
|
+
# imports applied locally to avoid patching import overhead cost
|
|
65
|
+
from functools import cache # noqa: PLC0415
|
|
66
|
+
|
|
67
|
+
from pre_commit.languages import python # noqa: PLC0415
|
|
68
|
+
|
|
69
|
+
def _install_environment(
|
|
70
|
+
prefix: Prefix,
|
|
71
|
+
version: str,
|
|
72
|
+
additional_dependencies: Sequence[str],
|
|
73
|
+
) -> None:
|
|
74
|
+
import logging # noqa: PLC0415
|
|
75
|
+
|
|
76
|
+
from pre_commit.git import get_root # noqa: PLC0415
|
|
77
|
+
from pre_commit.lang_base import environment_dir, setup_cmd # noqa: PLC0415
|
|
78
|
+
from pre_commit.util import cmd_output_b # noqa: PLC0415
|
|
79
|
+
|
|
80
|
+
project_root_dir = get_root()
|
|
81
|
+
|
|
82
|
+
logger = logging.getLogger("pre_commit")
|
|
83
|
+
logger.info("Using pre-commit with uv %s via pre-commit-uv %s", uv_version(), self_version())
|
|
84
|
+
uv = _uv()
|
|
85
|
+
py = python.norm_version(version) or os.environ.get("UV_PYTHON", sys.executable)
|
|
86
|
+
venv_cmd = [
|
|
87
|
+
uv,
|
|
88
|
+
"--project",
|
|
89
|
+
project_root_dir,
|
|
90
|
+
"venv",
|
|
91
|
+
"--seed",
|
|
92
|
+
environment_dir(prefix, python.ENVIRONMENT_DIR, version),
|
|
93
|
+
"-p",
|
|
94
|
+
py,
|
|
95
|
+
]
|
|
96
|
+
cmd_output_b(*venv_cmd, cwd="/")
|
|
97
|
+
|
|
98
|
+
with python.in_env(prefix, version):
|
|
99
|
+
setup_cmd(
|
|
100
|
+
prefix,
|
|
101
|
+
(
|
|
102
|
+
uv,
|
|
103
|
+
"--project",
|
|
104
|
+
project_root_dir,
|
|
105
|
+
"pip",
|
|
106
|
+
"install",
|
|
107
|
+
".",
|
|
108
|
+
*additional_dependencies,
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
@cache
|
|
113
|
+
def _uv() -> str:
|
|
114
|
+
from uv import find_uv_bin # noqa: PLC0415
|
|
115
|
+
|
|
116
|
+
return find_uv_bin()
|
|
117
|
+
|
|
118
|
+
@cache
|
|
119
|
+
def self_version() -> str:
|
|
120
|
+
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
121
|
+
|
|
122
|
+
return _metadata_version("pre-commit-uv")
|
|
123
|
+
|
|
124
|
+
@cache
|
|
125
|
+
def uv_version() -> str:
|
|
126
|
+
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
127
|
+
|
|
128
|
+
return _metadata_version("uv")
|
|
129
|
+
|
|
130
|
+
patched = cast("_PatchablePython", python)
|
|
131
|
+
patched.install_environment = _install_environment
|
|
132
|
+
patched.health_check = _health_check
|
|
133
|
+
assert _original_main is not None # noqa: S101
|
|
134
|
+
return _original_main(argv)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _version_info(exe: str) -> str:
|
|
138
|
+
from pre_commit.util import CalledProcessError, cmd_output # noqa: PLC0415
|
|
139
|
+
|
|
140
|
+
prog = 'import sys;print(".".join(str(p) for p in sys.version_info[0:3]))'
|
|
141
|
+
try:
|
|
142
|
+
return cmd_output(exe, "-S", "-c", prog)[1].strip()
|
|
143
|
+
except CalledProcessError:
|
|
144
|
+
return f"<<error retrieving version from {exe}>>"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _health_check(prefix: Prefix, version: str) -> str | None:
|
|
148
|
+
# uv may record fewer version components in pyvenv.cfg than pre-commit expects (e.g. "3.14" vs "3.14.6"),
|
|
149
|
+
# so compare only the components uv actually wrote rather than requiring an exact string match
|
|
150
|
+
from pre_commit.lang_base import environment_dir # noqa: PLC0415
|
|
151
|
+
from pre_commit.languages import python # noqa: PLC0415
|
|
152
|
+
from pre_commit.util import win_exe # noqa: PLC0415
|
|
153
|
+
|
|
154
|
+
pyvenv_cfg = pathlib.Path(environment_dir(prefix, python.ENVIRONMENT_DIR, version)) / "pyvenv.cfg"
|
|
155
|
+
if not pyvenv_cfg.exists():
|
|
156
|
+
return "pyvenv.cfg does not exist (old virtualenv?)"
|
|
157
|
+
|
|
158
|
+
cfg = python._read_pyvenv_cfg(str(pyvenv_cfg)) # noqa: SLF001
|
|
159
|
+
if "version_info" not in cfg:
|
|
160
|
+
return "created virtualenv's pyvenv.cfg is missing `version_info`"
|
|
161
|
+
expected = cfg["version_info"].split(".")
|
|
162
|
+
|
|
163
|
+
py_exe = prefix.path(python.bin_dir(str(pyvenv_cfg.parent)), win_exe("python"))
|
|
164
|
+
targets = [("virtualenv python", py_exe)]
|
|
165
|
+
if "base-executable" in cfg:
|
|
166
|
+
targets.append(("base executable", cfg["base-executable"]))
|
|
167
|
+
for label, exe in targets:
|
|
168
|
+
if (actual := _version_info(exe)).split(".")[: len(expected)] != expected:
|
|
169
|
+
return (
|
|
170
|
+
f"{label} version did not match created version:\n"
|
|
171
|
+
f"- actual version: {actual}\n"
|
|
172
|
+
f"- expected version: {cfg['version_info']}\n"
|
|
173
|
+
)
|
|
174
|
+
return None
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from pre_commit.languages import python
|
|
7
|
+
from pre_commit.prefix import Prefix
|
|
8
|
+
|
|
9
|
+
from pre_commit_uv import _health_check
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
version = "default"
|
|
15
|
+
major_minor = f"{sys.version_info[0]}.{sys.version_info[1]}"
|
|
16
|
+
full_version = ".".join(str(p) for p in sys.version_info[0:3])
|
|
17
|
+
wrong_version = f"{sys.version_info[0]}.{sys.version_info[1] + 1}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _make_env(tmp_path: Path, pyvenv_cfg: str | None) -> Prefix:
|
|
21
|
+
envdir = tmp_path / f"py_env-{version}"
|
|
22
|
+
bin_dir = python.bin_dir(str(envdir))
|
|
23
|
+
(tmp_path / bin_dir).mkdir(parents=True)
|
|
24
|
+
(tmp_path / bin_dir / python.win_exe("python")).symlink_to(sys.executable)
|
|
25
|
+
if pyvenv_cfg is not None:
|
|
26
|
+
(envdir / "pyvenv.cfg").write_text(pyvenv_cfg)
|
|
27
|
+
return Prefix(str(tmp_path))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_health_check_truncated_version_passes(tmp_path: Path) -> None:
|
|
31
|
+
"""uv >=0.11.22 writes only the major.minor into pyvenv.cfg (see issue #152)."""
|
|
32
|
+
prefix = _make_env(tmp_path, f"version_info = {major_minor}\nbase-executable = {sys.executable}\n")
|
|
33
|
+
|
|
34
|
+
assert _health_check(prefix, version) is None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_health_check_full_version_passes(tmp_path: Path) -> None:
|
|
38
|
+
prefix = _make_env(tmp_path, f"version_info = {full_version}\nbase-executable = {sys.executable}\n")
|
|
39
|
+
|
|
40
|
+
assert _health_check(prefix, version) is None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_health_check_no_base_executable_passes(tmp_path: Path) -> None:
|
|
44
|
+
prefix = _make_env(tmp_path, f"version_info = {major_minor}\n")
|
|
45
|
+
|
|
46
|
+
assert _health_check(prefix, version) is None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_health_check_version_mismatch_fails(tmp_path: Path) -> None:
|
|
50
|
+
prefix = _make_env(tmp_path, f"version_info = {wrong_version}\n")
|
|
51
|
+
|
|
52
|
+
result = _health_check(prefix, version)
|
|
53
|
+
|
|
54
|
+
assert result is not None
|
|
55
|
+
assert "virtualenv python version did not match created version" in result
|
|
56
|
+
assert f"- expected version: {wrong_version}" in result
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_health_check_base_executable_mismatch_fails(tmp_path: Path) -> None:
|
|
60
|
+
prefix = _make_env(tmp_path, f"version_info = {major_minor}\nbase-executable = /does/not/exist/python\n")
|
|
61
|
+
|
|
62
|
+
result = _health_check(prefix, version)
|
|
63
|
+
|
|
64
|
+
assert result is not None
|
|
65
|
+
assert "base executable version did not match created version" in result
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_health_check_missing_pyvenv_cfg(tmp_path: Path) -> None:
|
|
69
|
+
prefix = _make_env(tmp_path, None)
|
|
70
|
+
|
|
71
|
+
assert _health_check(prefix, version) == "pyvenv.cfg does not exist (old virtualenv?)"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_health_check_missing_version_info(tmp_path: Path) -> None:
|
|
75
|
+
prefix = _make_env(tmp_path, "home = /usr\n")
|
|
76
|
+
|
|
77
|
+
assert _health_check(prefix, version) == "created virtualenv's pyvenv.cfg is missing `version_info`"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import sys
|
|
3
4
|
from importlib.metadata import version
|
|
4
5
|
from subprocess import check_call, check_output
|
|
5
6
|
from textwrap import dedent
|
|
@@ -47,8 +48,8 @@ def test_run_precommit_hook() -> None:
|
|
|
47
48
|
|
|
48
49
|
@pytest.mark.usefixtures("install_hook")
|
|
49
50
|
def test_call_as_module() -> None:
|
|
50
|
-
run_result = check_output([
|
|
51
|
-
assert f"[INFO] Using pre-commit with uv {uv} via pre-commit-uv {self}"
|
|
51
|
+
run_result = check_output([sys.executable, "-m", "pre_commit", "run", "-a", "--color", "never"], encoding="utf-8")
|
|
52
|
+
assert f"[INFO] Using pre-commit with uv {uv} via pre-commit-uv {self}" in run_result.splitlines()
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
def test_install(git_repo: Path, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
@@ -68,6 +69,21 @@ def test_install(git_repo: Path, caplog: pytest.LogCaptureFixture, monkeypatch:
|
|
|
68
69
|
]
|
|
69
70
|
|
|
70
71
|
|
|
72
|
+
def test_install_seeds_pip(git_repo: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
73
|
+
monkeypatch.setenv("FORCE_PRE_COMMIT_UV_PATCH", "1")
|
|
74
|
+
|
|
75
|
+
import pre_commit_uv # noqa: PLC0415
|
|
76
|
+
|
|
77
|
+
pre_commit_uv._patch() # noqa: SLF001
|
|
78
|
+
main.main(["install-hooks", "-c", str(git_repo / precommit_file)])
|
|
79
|
+
|
|
80
|
+
env_dirs = list((git_repo / "store").rglob("py_env-*"))
|
|
81
|
+
assert env_dirs, "expected at least one hook environment"
|
|
82
|
+
py = next((env_dirs[0] / "bin").glob("python*"))
|
|
83
|
+
result = check_output([str(py), "-c", "import pip"], encoding="utf-8")
|
|
84
|
+
assert not result
|
|
85
|
+
|
|
86
|
+
|
|
71
87
|
test_install_with_uv_config_cases: list[tuple[str, str]] = [
|
|
72
88
|
(
|
|
73
89
|
"pyproject.toml",
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"""Package root."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
# only import built-ins at top level to avoid interpreter startup overhead
|
|
6
|
-
import os
|
|
7
|
-
import sys
|
|
8
|
-
|
|
9
|
-
_original_main = None
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def _patch() -> None:
|
|
13
|
-
global _original_main
|
|
14
|
-
if _original_main is not None: # already patched, nothing more to do
|
|
15
|
-
return
|
|
16
|
-
calling_pre_commit = "FORCE_PRE_COMMIT_UV_PATCH" in os.environ
|
|
17
|
-
if not calling_pre_commit and sys.argv and sys.argv[0]: # must have arguments
|
|
18
|
-
calling = sys.argv[1] if sys.argv[0] == sys.executable and len(sys.argv) >= 1 else sys.argv[0]
|
|
19
|
-
if (
|
|
20
|
-
os.path.split(calling)[1] == f"pre-commit{'.exe' if sys.platform == 'win32' else ''}"
|
|
21
|
-
# case when pre-commit is called due to a git commit
|
|
22
|
-
or ("-m" in sys.argv and "hook-impl" in sys.argv)
|
|
23
|
-
):
|
|
24
|
-
calling_pre_commit = True
|
|
25
|
-
|
|
26
|
-
if calling_pre_commit and os.environ.get("DISABLE_PRE_COMMIT_UV_PATCH") is None:
|
|
27
|
-
from pre_commit import main # noqa: PLC0415
|
|
28
|
-
|
|
29
|
-
_original_main, main.main = main.main, _new_main
|
|
30
|
-
if "--version" in sys.argv:
|
|
31
|
-
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
32
|
-
|
|
33
|
-
from pre_commit import constants # noqa: PLC0415
|
|
34
|
-
|
|
35
|
-
constants.VERSION = (
|
|
36
|
-
f"{constants.VERSION} ("
|
|
37
|
-
f"pre-commit-uv={_metadata_version('pre-commit-uv')}, "
|
|
38
|
-
f"uv={_metadata_version('uv')}"
|
|
39
|
-
f")"
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def _new_main(argv: list[str] | None = None) -> int:
|
|
44
|
-
# imports applied locally to avoid patching import overhead cost
|
|
45
|
-
from functools import cache # noqa: PLC0415
|
|
46
|
-
from typing import TYPE_CHECKING, cast # noqa: PLC0415
|
|
47
|
-
|
|
48
|
-
from pre_commit.languages import python # noqa: PLC0415
|
|
49
|
-
|
|
50
|
-
if TYPE_CHECKING:
|
|
51
|
-
from collections.abc import Sequence # noqa: PLC0415
|
|
52
|
-
|
|
53
|
-
from pre_commit.prefix import Prefix # noqa: PLC0415
|
|
54
|
-
|
|
55
|
-
def _install_environment(
|
|
56
|
-
prefix: Prefix,
|
|
57
|
-
version: str,
|
|
58
|
-
additional_dependencies: Sequence[str],
|
|
59
|
-
) -> None:
|
|
60
|
-
import logging # noqa: PLC0415
|
|
61
|
-
|
|
62
|
-
from pre_commit.git import get_root # noqa: PLC0415
|
|
63
|
-
from pre_commit.lang_base import environment_dir, setup_cmd # noqa: PLC0415
|
|
64
|
-
from pre_commit.util import cmd_output_b # noqa: PLC0415
|
|
65
|
-
|
|
66
|
-
project_root_dir = get_root()
|
|
67
|
-
|
|
68
|
-
logger = logging.getLogger("pre_commit")
|
|
69
|
-
logger.info("Using pre-commit with uv %s via pre-commit-uv %s", uv_version(), self_version())
|
|
70
|
-
uv = _uv()
|
|
71
|
-
py = python.norm_version(version) or os.environ.get("UV_PYTHON", sys.executable)
|
|
72
|
-
venv_cmd = [
|
|
73
|
-
uv,
|
|
74
|
-
"--project",
|
|
75
|
-
project_root_dir,
|
|
76
|
-
"venv",
|
|
77
|
-
environment_dir(prefix, python.ENVIRONMENT_DIR, version),
|
|
78
|
-
"-p",
|
|
79
|
-
py,
|
|
80
|
-
]
|
|
81
|
-
cmd_output_b(*venv_cmd, cwd="/")
|
|
82
|
-
|
|
83
|
-
with python.in_env(prefix, version):
|
|
84
|
-
setup_cmd(
|
|
85
|
-
prefix,
|
|
86
|
-
(
|
|
87
|
-
uv,
|
|
88
|
-
"--project",
|
|
89
|
-
project_root_dir,
|
|
90
|
-
"pip",
|
|
91
|
-
"install",
|
|
92
|
-
".",
|
|
93
|
-
*additional_dependencies,
|
|
94
|
-
),
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
@cache
|
|
98
|
-
def _uv() -> str:
|
|
99
|
-
from uv import find_uv_bin # noqa: PLC0415
|
|
100
|
-
|
|
101
|
-
return find_uv_bin()
|
|
102
|
-
|
|
103
|
-
@cache
|
|
104
|
-
def self_version() -> str:
|
|
105
|
-
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
106
|
-
|
|
107
|
-
return _metadata_version("pre-commit-uv")
|
|
108
|
-
|
|
109
|
-
@cache
|
|
110
|
-
def uv_version() -> str:
|
|
111
|
-
from importlib.metadata import version as _metadata_version # noqa: PLC0415
|
|
112
|
-
|
|
113
|
-
return _metadata_version("uv")
|
|
114
|
-
|
|
115
|
-
@cache
|
|
116
|
-
def _version_info(exe: str) -> str:
|
|
117
|
-
from pre_commit.util import CalledProcessError, cmd_output # noqa: PLC0415
|
|
118
|
-
|
|
119
|
-
prog = 'import sys;print(".".join(str(p) for p in sys.version_info[0:3]))'
|
|
120
|
-
try:
|
|
121
|
-
return cast("str", cmd_output(exe, "-S", "-c", prog)[1].strip())
|
|
122
|
-
except CalledProcessError:
|
|
123
|
-
return f"<<error retrieving version from {exe}>>"
|
|
124
|
-
|
|
125
|
-
python.install_environment = _install_environment
|
|
126
|
-
python._version_info = _version_info # noqa: SLF001
|
|
127
|
-
assert _original_main is not None # noqa: S101
|
|
128
|
-
return cast("int", _original_main(argv))
|
pre_commit_uv-4.2.0/tox.ini
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
[tox]
|
|
2
|
-
requires =
|
|
3
|
-
tox>=4.31
|
|
4
|
-
tox-uv>=1.28.1
|
|
5
|
-
env_list =
|
|
6
|
-
fix
|
|
7
|
-
3.14
|
|
8
|
-
3.13
|
|
9
|
-
3.12
|
|
10
|
-
3.11
|
|
11
|
-
3.10
|
|
12
|
-
3.9
|
|
13
|
-
3.8
|
|
14
|
-
type
|
|
15
|
-
pkg_meta
|
|
16
|
-
skip_missing_interpreters = true
|
|
17
|
-
|
|
18
|
-
[testenv]
|
|
19
|
-
description = run the unit tests with pytest under {base_python}
|
|
20
|
-
package = wheel
|
|
21
|
-
wheel_build_env = .pkg
|
|
22
|
-
extras =
|
|
23
|
-
testing
|
|
24
|
-
pass_env =
|
|
25
|
-
PYTEST_*
|
|
26
|
-
set_env =
|
|
27
|
-
COVERAGE_FILE = {work_dir}/.coverage.{env_name}
|
|
28
|
-
commands =
|
|
29
|
-
python -m pytest {tty:--color=yes} {posargs: \
|
|
30
|
-
--cov {env_site_packages_dir}{/}pre_commit_uv --cov {tox_root}{/}tests \
|
|
31
|
-
--cov-config=pyproject.toml --no-cov-on-fail --cov-report term-missing:skip-covered --cov-context=test \
|
|
32
|
-
--cov-report html:{env_tmp_dir}{/}htmlcov --cov-report xml:{work_dir}{/}coverage.{env_name}.xml \
|
|
33
|
-
--junitxml {work_dir}{/}junit.{env_name}.xml \
|
|
34
|
-
tests}
|
|
35
|
-
|
|
36
|
-
[testenv:fix]
|
|
37
|
-
description = format the code base to adhere to our styles, and complain about what we cannot do automatically
|
|
38
|
-
skip_install = true
|
|
39
|
-
deps =
|
|
40
|
-
pre-commit-uv>=4.1.1
|
|
41
|
-
commands =
|
|
42
|
-
pre-commit run --all-files --show-diff-on-failure
|
|
43
|
-
|
|
44
|
-
[testenv:type]
|
|
45
|
-
description = run type check on code base
|
|
46
|
-
deps =
|
|
47
|
-
mypy==1.18.2
|
|
48
|
-
commands =
|
|
49
|
-
mypy src
|
|
50
|
-
mypy tests
|
|
51
|
-
|
|
52
|
-
[testenv:pkg_meta]
|
|
53
|
-
description = check that the long description is valid
|
|
54
|
-
skip_install = true
|
|
55
|
-
deps =
|
|
56
|
-
check-wheel-contents>=0.6.3
|
|
57
|
-
twine>=6.2
|
|
58
|
-
uv>=0.9.1
|
|
59
|
-
commands =
|
|
60
|
-
uv build --sdist --wheel --out-dir {env_tmp_dir} .
|
|
61
|
-
twine check {env_tmp_dir}{/}*
|
|
62
|
-
check-wheel-contents --no-config {env_tmp_dir}
|
|
63
|
-
|
|
64
|
-
[testenv:dev]
|
|
65
|
-
description = generate a DEV environment
|
|
66
|
-
package = editable
|
|
67
|
-
commands =
|
|
68
|
-
uv tree
|
|
69
|
-
python -c 'import sys; print(sys.executable)'
|
|
70
|
-
python task/dev_pth.py {env_site_packages_dir}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|