lol

Python: fix virtualenv with Python 2

authored by

Frederik Rietdijk and committed by
Frederik Rietdijk
f17001af 98bcf5d8

+52 -9
+6 -6
pkgs/development/interpreters/python/sitecustomize.py
··· 21 21 if paths: 22 22 functools.reduce(lambda k, p: site.addsitedir(p, k), paths.split(':'), site._init_pathinfo()) 23 23 24 - # Check whether we are in a venv. 25 - # Note Python 2 does not support base_prefix so we assume we are not in a venv. 26 - in_venv = sys.version_info.major == 3 and sys.prefix != sys.base_prefix 24 + # Check whether we are in a venv or virtualenv. 25 + # For Python 3 we check whether our `base_prefix` is different from our current `prefix`. 26 + # For Python 2 we check whether the non-standard `real_prefix` is set. 27 + # https://stackoverflow.com/questions/1871549/determine-if-python-is-running-inside-virtualenv 28 + in_venv = (sys.version_info.major == 3 and sys.prefix != sys.base_prefix) or (sys.version_info.major == 2 and hasattr(sys, "real_prefix")) 27 29 28 30 if not in_venv: 29 31 executable = os.environ.pop('NIX_PYTHONEXECUTABLE', None) ··· 32 34 if 'PYTHONEXECUTABLE' not in os.environ and executable is not None: 33 35 sys.executable = executable 34 36 if prefix is not None: 35 - # Because we cannot check with Python 2 whether we are in a venv, 36 - # creating a venv from a Nix env won't work as well with Python 2. 37 - # Also, note that sysconfig does not like it when sys.prefix is set to None 37 + # Sysconfig does not like it when sys.prefix is set to None 38 38 sys.prefix = sys.exec_prefix = prefix 39 39 site.PREFIXES.insert(0, prefix)
+1 -3
pkgs/development/interpreters/python/tests.nix
··· 19 19 is_nixenv = "False"; 20 20 is_virtualenv = "False"; 21 21 }; 22 - } // lib.optionalAttrs (python.isPy3k && !python.isPyPy) { 22 + } // lib.optionalAttrs (!python.isPyPy) { 23 23 # Use virtualenv from a Nix env. 24 - # Does not function with Python 2 25 - # ValueError: source and destination is the same /nix/store/38kz3j1a87cq5y59k5w7k9yk4cqgc5b2-python-2.7.18/lib/python2.7/os.py 26 24 nixenv-virtualenv = rec { 27 25 env = runCommand "${python.name}-virtualenv" {} '' 28 26 ${pythonVirtualEnv.interpreter} -m virtualenv $out
+4
pkgs/development/interpreters/python/tests/test_python.py
··· 43 43 else: 44 44 self.assertEqual(sys.prefix, sys.base_prefix) 45 45 46 + @unittest.skipIf(sys.version_info.major==3, "sys.real_prefix is only set by virtualenv in case of Python 2.") 47 + def test_real_prefix(self): 48 + self.assertTrue(hasattr(sys, "real_prefix") == IS_VIRTUALENV) 49 + 46 50 def test_python_version(self): 47 51 self.assertTrue(platform.python_version().startswith(PYTHON_VERSION)) 48 52
+37
pkgs/development/python-modules/virtualenv/0001-Check-base_prefix-and-base_exec_prefix-for-Python-2.patch
··· 1 + From 21563405d6e2348ee457187f7fb61beb102bb367 Mon Sep 17 00:00:00 2001 2 + From: Frederik Rietdijk <fridh@fridh.nl> 3 + Date: Sun, 24 May 2020 09:33:13 +0200 4 + Subject: [PATCH] Check base_prefix and base_exec_prefix for Python 2 5 + 6 + This is a Nixpkgs-specific change so it can support virtualenvs from Nix envs. 7 + --- 8 + src/virtualenv/discovery/py_info.py | 8 ++++++-- 9 + 1 file changed, 6 insertions(+), 2 deletions(-) 10 + 11 + diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py 12 + index 6f12128..74e9218 100644 13 + --- a/src/virtualenv/discovery/py_info.py 14 + +++ b/src/virtualenv/discovery/py_info.py 15 + @@ -51,13 +51,17 @@ class PythonInfo(object): 16 + self.version = u(sys.version) 17 + self.os = u(os.name) 18 + 19 + + config_vars = {} if sys.version_info.major is not 2 else sysconfig._CONFIG_VARS 20 + + base_prefix = config_vars.get("prefix") 21 + + base_exec_prefix = config_vars.get("exec_prefix") 22 + + 23 + # information about the prefix - determines python home 24 + self.prefix = u(abs_path(getattr(sys, "prefix", None))) # prefix we think 25 + - self.base_prefix = u(abs_path(getattr(sys, "base_prefix", None))) # venv 26 + + self.base_prefix = u(abs_path(getattr(sys, "base_prefix", base_prefix))) # venv 27 + self.real_prefix = u(abs_path(getattr(sys, "real_prefix", None))) # old virtualenv 28 + 29 + # information about the exec prefix - dynamic stdlib modules 30 + - self.base_exec_prefix = u(abs_path(getattr(sys, "base_exec_prefix", None))) 31 + + self.base_exec_prefix = u(abs_path(getattr(sys, "base_exec_prefix", base_exec_prefix))) 32 + self.exec_prefix = u(abs_path(getattr(sys, "exec_prefix", None))) 33 + 34 + self.executable = u(abs_path(sys.executable)) # the executable we were invoked via 35 + -- 36 + 2.25.1 37 +
+4
pkgs/development/python-modules/virtualenv/default.nix
··· 43 43 importlib-metadata 44 44 ]; 45 45 46 + patches = lib.optionals (isPy27) [ 47 + ./0001-Check-base_prefix-and-base_exec_prefix-for-Python-2.patch 48 + ]; 49 + 46 50 meta = { 47 51 description = "A tool to create isolated Python environments"; 48 52 homepage = "http://www.virtualenv.org";