diff --git a/.github/workflows/languages.yaml b/.github/workflows/languages.yaml index fccf298..61293a0 100644 --- a/.github/workflows/languages.yaml +++ b/.github/workflows/languages.yaml @@ -36,7 +36,7 @@ jobs: matrix: include: ${{ fromJSON(needs.vars.outputs.languages) }} steps: - - uses: asottile/workflows/.github/actions/fast-checkout@v1.8.1 + - uses: asottile/workflows/.github/actions/fast-checkout@v1.4.0 - uses: actions/setup-python@v4 with: python-version: 3.9 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7fda646..2355b66 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,12 +12,12 @@ concurrency: jobs: main-windows: - uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1 + uses: asottile/workflows/.github/workflows/tox.yml@v1.6.0 with: env: '["py39"]' os: windows-latest main-linux: - uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1 + uses: asottile/workflows/.github/workflows/tox.yml@v1.6.0 with: env: '["py39", "py310", "py311", "py312"]' os: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b216fbd..4a23da2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,15 +29,15 @@ repos: - id: pyupgrade args: [--py39-plus] - repo: https://github.com/hhatto/autopep8 - rev: v2.3.2 + rev: v2.3.1 hooks: - id: autopep8 - repo: https://github.com/PyCQA/flake8 - rev: 7.1.2 + rev: 7.1.1 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.15.0 + rev: v1.14.1 hooks: - id: mypy additional_dependencies: [types-pyyaml] diff --git a/CHANGELOG.md b/CHANGELOG.md index b63f443..408afe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,3 @@ -4.2.0 - 2025-03-18 -================== - -### Features -- For `language: python` first attempt a versioned python executable for - the default language version before consulting a potentially unversioned - `sys.executable`. - - #3430 PR by @asottile. - -### Fixes -- Handle error during conflict detection when a file is named "HEAD" - - #3425 PR by @tusharsadhwani. - 4.1.0 - 2025-01-20 ================== diff --git a/debian/changelog b/debian/changelog index 2502d57..9a50475 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,3 @@ -pre-commit (4.2.0-1) sid; urgency=medium - - * Merging upstream version 4.2.0. - - -- Daniel Baumann Thu, 20 Mar 2025 08:17:36 +0100 - pre-commit (4.1.0-3) sid; urgency=medium * Updating to standards version 4.7.1. diff --git a/pre_commit/git.py b/pre_commit/git.py index 2f424f8..19aac38 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -126,7 +126,7 @@ def get_conflicted_files() -> set[str]: merge_diff_filenames = zsplit( cmd_output( 'git', 'diff', '--name-only', '--no-ext-diff', '-z', - '-m', tree_hash, 'HEAD', 'MERGE_HEAD', '--', + '-m', tree_hash, 'HEAD', 'MERGE_HEAD', )[1], ) return set(merge_conflict_filenames) | set(merge_diff_filenames) diff --git a/pre_commit/languages/python.py b/pre_commit/languages/python.py index 88ececc..0c4bb62 100644 --- a/pre_commit/languages/python.py +++ b/pre_commit/languages/python.py @@ -75,13 +75,6 @@ def _find_by_py_launcher( return None -def _impl_exe_name() -> str: - if sys.implementation.name == 'cpython': # pragma: cpython cover - return 'python' - else: # pragma: cpython no cover - return sys.implementation.name # pypy mostly - - def _find_by_sys_executable() -> str | None: def _norm(path: str) -> str | None: _, exe = os.path.split(path.lower()) @@ -107,25 +100,18 @@ def _find_by_sys_executable() -> str | None: @functools.lru_cache(maxsize=1) def get_default_version() -> str: # pragma: no cover (platform dependent) - v_major = f'{sys.version_info[0]}' - v_minor = f'{sys.version_info[0]}.{sys.version_info[1]}' + # First attempt from `sys.executable` (or the realpath) + exe = _find_by_sys_executable() + if exe: + return exe - # attempt the likely implementation exe - for potential in (v_minor, v_major): - exe = f'{_impl_exe_name()}{potential}' - if find_executable(exe): - return exe + # Next try the `pythonX.X` executable + exe = f'python{sys.version_info[0]}.{sys.version_info[1]}' + if find_executable(exe): + return exe - # next try `sys.executable` (or the realpath) - maybe_exe = _find_by_sys_executable() - if maybe_exe: - return maybe_exe - - # maybe on windows we can find it via py launcher? - if sys.platform == 'win32': # pragma: win32 cover - exe = f'python{v_minor}' - if _find_by_py_launcher(exe): - return exe + if _find_by_py_launcher(exe): + return exe # We tried! return C.DEFAULT diff --git a/setup.cfg b/setup.cfg index af34452..60d9764 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pre_commit -version = 4.2.0 +version = 4.1.0 description = A framework for managing and maintaining multi-language pre-commit hooks. long_description = file: README.md long_description_content_type = text/markdown diff --git a/tests/git_test.py b/tests/git_test.py index 02b6ce3..93f5a1c 100644 --- a/tests/git_test.py +++ b/tests/git_test.py @@ -141,15 +141,6 @@ def test_get_conflicted_files_unstaged_files(in_merge_conflict): assert ret == {'conflict_file'} -def test_get_conflicted_files_with_file_named_head(in_merge_conflict): - resolve_conflict() - open('HEAD', 'w').close() - cmd_output('git', 'add', 'HEAD') - - ret = set(git.get_conflicted_files()) - assert ret == {'conflict_file', 'HEAD'} - - MERGE_MSG = b"Merge branch 'foo' into bar\n\nConflicts:\n\tconflict_file\n" OTHER_MERGE_MSG = MERGE_MSG + b'\tother_conflict_file\n' diff --git a/tests/languages/python_test.py b/tests/languages/python_test.py index 565525a..ab26e14 100644 --- a/tests/languages/python_test.py +++ b/tests/languages/python_test.py @@ -12,7 +12,6 @@ from pre_commit.languages import python from pre_commit.prefix import Prefix from pre_commit.util import make_executable from pre_commit.util import win_exe -from testing.auto_namedtuple import auto_namedtuple from testing.language_helpers import run_language @@ -35,72 +34,6 @@ def test_read_pyvenv_cfg_non_utf8(tmpdir): assert python._read_pyvenv_cfg(pyvenv_cfg) == expected -def _get_default_version( - *, - impl: str, - exe: str, - found: set[str], - version: tuple[int, int], -) -> str: - sys_exe = f'/fake/path/{exe}' - sys_impl = auto_namedtuple(name=impl) - sys_ver = auto_namedtuple(major=version[0], minor=version[1]) - - def find_exe(s): - if s in found: - return f'/fake/path/found/{exe}' - else: - return None - - with ( - mock.patch.object(sys, 'implementation', sys_impl), - mock.patch.object(sys, 'executable', sys_exe), - mock.patch.object(sys, 'version_info', sys_ver), - mock.patch.object(python, 'find_executable', find_exe), - ): - return python.get_default_version.__wrapped__() - - -def test_default_version_sys_executable_found(): - ret = _get_default_version( - impl='cpython', - exe='python3.12', - found={'python3.12'}, - version=(3, 12), - ) - assert ret == 'python3.12' - - -def test_default_version_picks_specific_when_found(): - ret = _get_default_version( - impl='cpython', - exe='python3', - found={'python3', 'python3.12'}, - version=(3, 12), - ) - assert ret == 'python3.12' - - -def test_default_version_picks_pypy_versioned_exe(): - ret = _get_default_version( - impl='pypy', - exe='python', - found={'pypy3.12', 'python3'}, - version=(3, 12), - ) - assert ret == 'pypy3.12' - - -def test_default_version_picks_pypy_unversioned_exe(): - ret = _get_default_version( - impl='pypy', - exe='python', - found={'pypy3', 'python3'}, - version=(3, 12), - ) - assert ret == 'pypy3' - - def test_norm_version_expanduser(): home = os.path.expanduser('~') if sys.platform == 'win32': # pragma: win32 cover