diff --git a/pre_commit/languages/python.py b/pre_commit/languages/python.py index 2ef92901..9505577e 100644 --- a/pre_commit/languages/python.py +++ b/pre_commit/languages/python.py @@ -114,23 +114,29 @@ def healthy(prefix, language_version): def norm_version(version): + if version.endswith('+venv'): + use_venv = True + version = version[:-5] + else: + use_venv = False if os.name == 'nt': # pragma: no cover (windows) # Try looking up by name version_exec = find_executable(version) if version_exec and version_exec != version: - return version_exec + return version_exec, use_venv version_exec = _find_by_py_launcher(version) if version_exec: - return version_exec + return version_exec, use_venv # If it is in the form pythonx.x search in the default # place on windows if version.startswith('python'): - return r'C:\{}\python.exe'.format(version.replace('.', '')) + path = r'C:\{}\python.exe'.format(version.replace('.', '')) + return path, use_venv # Otherwise assume it is a path - return os.path.expanduser(version) + return os.path.expanduser(version), use_venv def install_environment(prefix, version, additional_dependencies): @@ -141,25 +147,22 @@ def install_environment(prefix, version, additional_dependencies): env_dir = prefix.path(directory) with clean_path_on_failure(env_dir): if version != 'default': - target_python = norm_version(version) + target_python, use_venv = norm_version(version) else: target_python = os.path.realpath(sys.executable) + use_venv = False - try: - subprocess.check_call( - [target_python, '-c', 'import venv'], - stderr=devnull, - stdout=devnull, - ) - venv_python = target_python - venv_module = 'venv' - extra_cmd = [] - except subprocess.CalledProcessError: - venv_python = sys.executable - venv_module = 'virtualenv' - extra_cmd = ['-p', target_python] - - venv_cmd = [venv_python, '-m', venv_module, env_dir] + extra_cmd + if use_venv: + venv_cmd = [target_python, '-m', 'venv', env_dir] + else: + venv_cmd = [ + sys.executable, + '-m', + 'virtualenv', + '-p', + target_python, + env_dir, + ] venv_env = dict(os.environ, VIRTUALENV_NO_DOWNLOAD='1') cmd_output(*venv_cmd, cwd='/', env=venv_env) with in_env(prefix, version): diff --git a/tests/languages/python_test.py b/tests/languages/python_test.py index 78211cb9..b8331f91 100644 --- a/tests/languages/python_test.py +++ b/tests/languages/python_test.py @@ -3,6 +3,8 @@ from __future__ import unicode_literals import os.path +import pytest + from pre_commit.languages import python @@ -15,4 +17,14 @@ def test_norm_version_expanduser(): path = '~/.pyenv/versions/3.4.3/bin/python' expected_path = home + '/.pyenv/versions/3.4.3/bin/python' result = python.norm_version(path) - assert result == expected_path + assert result == (expected_path, False) + + +@pytest.mark.parametrize( + 'version,use_venv', [ + ('python3.6', False), + ('python3.6+venv', True), + ], +) +def test_norm_version_venv(version, use_venv): + assert python.norm_version(version)[1] == use_venv