refactor(languages/python): adapt scripts path resolution

Cygwin isn't the only edge-case for a differing bin/ path. In addition there
also is MSYS2, which behaves differently than Cygwin. CPython compiled against
Microsoft Visual C++ Runtime (MSVCRT) through MinGW, will correctly identify as
an 'nt' platform, yet will prefer a POSIX path scheme.

In order to avoid having to patch every edge-case, we can spy on the system
configurations install paths through the `sysconfig` module and get the basename
of the global scripts path, which will be returned in accordance with the
preferred install path scheme of the system/platform.

Fixes: https://github.com/pre-commit/pre-commit/issues/3448
This commit is contained in:
Rodney, Tiara 2025-04-15 14:42:17 +02:00
parent d2b61d0ef2
commit 7c4dfd7779
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723

View file

@ -4,8 +4,10 @@ import contextlib
import functools import functools
import os import os
import sys import sys
import sysconfig
from collections.abc import Generator from collections.abc import Generator
from collections.abc import Sequence from collections.abc import Sequence
from pathlib import Path
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit import lang_base from pre_commit import lang_base
@ -46,10 +48,9 @@ def _read_pyvenv_cfg(filename: str) -> dict[str, str]:
return ret return ret
def bin_dir(venv: str) -> str: def bin_dir(venv: str) -> Path:
"""On windows there's a different directory for the virtualenv""" """On windows there's a different directory for the virtualenv"""
bin_part = 'Scripts' if sys.platform == 'win32' else 'bin' return Path(venv) / Path(sysconfig.get_path('scripts')).name
return os.path.join(venv, bin_part)
def get_env_patch(venv: str) -> PatchesT: def get_env_patch(venv: str) -> PatchesT: