Merge pull request #2298 from pypa/windows-find-executable-pathext

Respect PATHEXT when looking for Win executable
This commit is contained in:
Dan Ryan
2018-06-03 17:09:23 -04:00
committed by GitHub
3 changed files with 43 additions and 15 deletions
+3 -3
View File
@@ -126,10 +126,10 @@ def which(command, location=None, allow_global=False):
if not allow_global:
if os.name == 'nt':
p = find_windows_executable(
os.path.join(location, 'Scripts'), command
os.path.join(location, 'Scripts'), command,
)
else:
p = os.sep.join([location] + ['bin/{0}'.format(command)])
p = os.path.join(location, 'bin', command)
else:
if command == 'python':
p = sys.executable
@@ -1508,7 +1508,7 @@ def pip_install(
def pip_download(package_name):
cache_dir = Path(PIPENV_CACHE_DIR)
cache_dir = Path(PIPENV_CACHE_DIR)
pip_config = {
'PIP_CACHE_DIR': fs_str(cache_dir.as_posix()),
'PIP_WHEEL_DIR': fs_str(cache_dir.joinpath('wheels').as_posix()),
+10 -12
View File
@@ -835,20 +835,18 @@ def get_windows_path(*args):
def find_windows_executable(bin_path, exe_name):
"""Given an executable name, search the given location for an executable"""
requested_path = get_windows_path(bin_path, exe_name)
if os.path.exists(requested_path):
if os.path.isfile(requested_path):
return requested_path
# Ensure we aren't adding two layers of file extensions
exe_name = os.path.splitext(exe_name)[0]
files = [
'{0}.{1}'.format(exe_name, ext) for ext in ['', 'py', 'exe', 'bat']
]
exec_paths = [get_windows_path(bin_path, f) for f in files]
exec_files = [
filename for filename in exec_paths if os.path.isfile(filename)
]
if exec_files:
return exec_files[0]
try:
pathext = os.environ['PATHEXT']
except KeyError:
pass
else:
for ext in pathext.split(os.pathsep):
path = get_windows_path(bin_path, exe_name + ext.strip().lower())
if os.path.isfile(path):
return path
return find_executable(exe_name)
@@ -0,0 +1,30 @@
import os
import mock
import pytest
from pipenv import utils
# This module is run only on Windows.
pytestmark = pytest.mark.skipif(
os.name != 'nt',
reason="only relevant on windows",
)
@mock.patch('os.path.isfile')
@mock.patch('pipenv.utils.find_executable')
def test_find_windows_executable(mocked_find_executable, mocked_isfile):
mocked_isfile.return_value = False
mocked_find_executable.return_value = None
found = utils.find_windows_executable('fake/path', 'python')
assert found is None
assert mocked_isfile.call_count > 1
calls = [mock.call('fake\\path\\python')] + [
mock.call('fake\\path\\python{0}'.format(ext.lower()))
for ext in os.environ['PATHEXT'].split(';')
]
assert mocked_isfile.mock_calls == calls