From 805a2921ad0d34698433972c6fcb1a6dca47191d Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 28 May 2018 15:14:17 -0700 Subject: [PATCH] Invoke -mvenv with the original python if in a -mvirtualenv venv --- pre_commit/languages/python_venv.py | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/pre_commit/languages/python_venv.py b/pre_commit/languages/python_venv.py index 20613a49..4397ce18 100644 --- a/pre_commit/languages/python_venv.py +++ b/pre_commit/languages/python_venv.py @@ -1,14 +1,46 @@ from __future__ import unicode_literals +import os.path + from pre_commit.languages import python +from pre_commit.util import CalledProcessError from pre_commit.util import cmd_output ENVIRONMENT_DIR = 'py_venv' +def orig_py_exe(exe): # pragma: no cover (platform specific) + """A -mvenv virtualenv made from a -mvirtualenv virtualenv installs + packages to the incorrect location. Attempt to find the _original_ exe + and invoke `-mvenv` from there. + + See: + - https://github.com/pre-commit/pre-commit/issues/755 + - https://github.com/pypa/virtualenv/issues/1095 + - https://bugs.python.org/issue30811 + """ + try: + prefix_script = 'import sys; print(sys.real_prefix)' + _, prefix, _ = cmd_output(exe, '-c', prefix_script) + prefix = prefix.strip() + except CalledProcessError: + # not created from -mvirtualenv + return exe + + if os.name == 'nt': + expected = os.path.join(prefix, 'python.exe') + else: + expected = os.path.join(prefix, 'bin', os.path.basename(exe)) + + if os.path.exists(expected): + return expected + else: + return exe + + def make_venv(envdir, python): - cmd_output(python, '-mvenv', envdir, cwd='/') + cmd_output(orig_py_exe(python), '-mvenv', envdir, cwd='/') get_default_version = python.get_default_version