Skip to content

Commit ae408c3

Browse files
authored
🐛 fix(patch): detect python -m pre_commit (#115)
During .pth processing, sys.argv is ["-m", ...] without the module name. The patch detection missed this case, so `python -m pre_commit` ran without uv. Use sys.orig_argv (available since Python 3.10) to check for the pre_commit module name. Fixes #80
1 parent 77942c4 commit ae408c3

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

src/pre_commit_uv/__init__.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,28 @@
99
_original_main = None
1010

1111

12+
def _is_calling_pre_commit() -> bool:
13+
if "FORCE_PRE_COMMIT_UV_PATCH" in os.environ:
14+
return True
15+
if not sys.argv or not sys.argv[0]:
16+
return False
17+
# case when pre-commit is called via python -m pre_commit
18+
if sys.argv[0] == "-m" and "-m" in sys.orig_argv and "pre_commit" in sys.orig_argv:
19+
return True
20+
calling = sys.argv[1] if sys.argv[0] == sys.executable and len(sys.argv) >= 1 else sys.argv[0]
21+
# case when pre-commit is called directly
22+
if os.path.split(calling)[1] == f"pre-commit{'.exe' if sys.platform == 'win32' else ''}":
23+
return True
24+
# case when pre-commit is called due to a git commit
25+
return "-m" in sys.argv and "hook-impl" in sys.argv
26+
27+
1228
def _patch() -> None:
1329
global _original_main
1430
if _original_main is not None: # already patched, nothing more to do
1531
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:
32+
33+
if _is_calling_pre_commit() and os.environ.get("DISABLE_PRE_COMMIT_UV_PATCH") is None:
2734
from pre_commit import main # noqa: PLC0415
2835

2936
_original_main, main.main = main.main, _new_main

tests/test_main.py

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

3+
import sys
34
from importlib.metadata import version
45
from subprocess import check_call, check_output
56
from textwrap import dedent
@@ -47,8 +48,8 @@ def test_run_precommit_hook() -> None:
4748

4849
@pytest.mark.usefixtures("install_hook")
4950
def test_call_as_module() -> None:
50-
run_result = check_output(["python3", "-m", "pre_commit", "run", "-a", "--color", "never"], encoding="utf-8")
51-
assert f"[INFO] Using pre-commit with uv {uv} via pre-commit-uv {self}" not in run_result.splitlines()
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()
5253

5354

5455
def test_install(git_repo: Path, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch) -> None:

0 commit comments

Comments
 (0)