pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/pre-commit/pre-commit/commit/3e8d0f5e1c449381272b80241140e985631f9912

ref="https://github.githubassets.com/assets/global-d18f184ea1a06a2c.css" /> adjust python default_language_version to prefer versioned exe · pre-commit/pre-commit@3e8d0f5 · GitHub
Skip to content

Commit 3e8d0f5

Browse files
committed
adjust python default_language_version to prefer versioned exe
1 parent ff7256c commit 3e8d0f5

2 files changed

Lines changed: 93 additions & 12 deletions

File tree

pre_commit/languages/python.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ def _find_by_py_launcher(
7575
return None
7676

7777

78+
def _impl_exe_name() -> str:
79+
if sys.implementation.name == 'cpython': # pragma: cpython cover
80+
return 'python'
81+
else: # pragma: cpython no cover
82+
return sys.implementation.name # pypy mostly
83+
84+
7885
def _find_by_sys_executable() -> str | None:
7986
def _norm(path: str) -> str | None:
8087
_, exe = os.path.split(path.lower())
@@ -100,18 +107,25 @@ def _norm(path: str) -> str | None:
100107

101108
@functools.lru_cache(maxsize=1)
102109
def get_default_version() -> str: # pragma: no cover (platform dependent)
103-
# First attempt from `sys.executable` (or the realpath)
104-
exe = _find_by_sys_executable()
105-
if exe:
106-
return exe
107-
108-
# Next try the `pythonX.X` executable
109-
exe = f'python{sys.version_info[0]}.{sys.version_info[1]}'
110-
if find_executable(exe):
111-
return exe
112-
113-
if _find_by_py_launcher(exe):
114-
return exe
110+
v_major = f'{sys.version_info[0]}'
111+
v_minor = f'{sys.version_info[0]}.{sys.version_info[1]}'
112+
113+
# attempt the likely implementation exe
114+
for potential in (v_minor, v_major):
115+
exe = f'{_impl_exe_name()}{potential}'
116+
if find_executable(exe):
117+
return exe
118+
119+
# next try `sys.executable` (or the realpath)
120+
maybe_exe = _find_by_sys_executable()
121+
if maybe_exe:
122+
return maybe_exe
123+
124+
# maybe on windows we can find it via py launcher?
125+
if sys.platform == 'win32': # pragma: win32 cover
126+
exe = f'python{v_minor}'
127+
if _find_by_py_launcher(exe):
128+
return exe
115129

116130
# We tried!
117131
return C.DEFAULT

tests/languages/python_test.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pre_commit.prefix import Prefix
1313
from pre_commit.util import make_executable
1414
from pre_commit.util import win_exe
15+
from testing.auto_namedtuple import auto_namedtuple
1516
from testing.language_helpers import run_language
1617

1718

@@ -34,6 +35,72 @@ def test_read_pyvenv_cfg_non_utf8(tmpdir):
3435
assert python._read_pyvenv_cfg(pyvenv_cfg) == expected
3536

3637

38+
def _get_default_version(
39+
*,
40+
impl: str,
41+
exe: str,
42+
found: set[str],
43+
version: tuple[int, int],
44+
) -> str:
45+
sys_exe = f'/fake/path/{exe}'
46+
sys_impl = auto_namedtuple(name=impl)
47+
sys_ver = auto_namedtuple(major=version[0], minor=version[1])
48+
49+
def find_exe(s):
50+
if s in found:
51+
return f'/fake/path/found/{exe}'
52+
else:
53+
return None
54+
55+
with (
56+
mock.patch.object(sys, 'implementation', sys_impl),
57+
mock.patch.object(sys, 'executable', sys_exe),
58+
mock.patch.object(sys, 'version_info', sys_ver),
59+
mock.patch.object(python, 'find_executable', find_exe),
60+
):
61+
return python.get_default_version.__wrapped__()
62+
63+
64+
def test_default_version_sys_executable_found():
65+
ret = _get_default_version(
66+
impl='cpython',
67+
exe='python3.12',
68+
found={'python3.12'},
69+
version=(3, 12),
70+
)
71+
assert ret == 'python3.12'
72+
73+
74+
def test_default_version_picks_specific_when_found():
75+
ret = _get_default_version(
76+
impl='cpython',
77+
exe='python3',
78+
found={'python3', 'python3.12'},
79+
version=(3, 12),
80+
)
81+
assert ret == 'python3.12'
82+
83+
84+
def test_default_version_picks_pypy_versioned_exe():
85+
ret = _get_default_version(
86+
impl='pypy',
87+
exe='python',
88+
found={'pypy3.12', 'python3'},
89+
version=(3, 12),
90+
)
91+
assert ret == 'pypy3.12'
92+
93+
94+
def test_default_version_picks_pypy_unversioned_exe():
95+
ret = _get_default_version(
96+
impl='pypy',
97+
exe='python',
98+
found={'pypy3', 'python3'},
99+
version=(3, 12),
100+
)
101+
assert ret == 'pypy3'
102+
103+
37104
def test_norm_version_expanduser():
38105
home = os.path.expanduser('~')
39106
if sys.platform == 'win32': # pragma: win32 cover

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy