Skip to content

Commit ab7c12a

Browse files
committed
refactor(python2/site): do not override PYTHONPATH
1 parent 0df0299 commit ab7c12a

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

docs/changelog/1673.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``PYTHONPATH`` being overriden on Python 2 — by :user:`jd`.

src/virtualenv/create/via_global_ref/builtin/python2/site.py

+33-11
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,25 @@ def rewrite_standard_library_sys_path():
8989
skip_rewrite = value == exe_dir # don't fix the current executable location, notably on Windows this gets added
9090
skip_rewrite = skip_rewrite # ___SKIP_REWRITE____
9191
if not skip_rewrite:
92-
if dir_starts_with(value, exe_dir):
93-
# content inside the exe folder needs to remap to original executables folder
94-
orig_exe_folder = base_executable[: base_executable.rfind(sep)]
95-
value = "{}{}".format(orig_exe_folder, value[len(exe_dir) :])
96-
elif dir_starts_with(value, prefix):
97-
value = "{}{}".format(base_prefix, value[len(prefix) :])
98-
elif dir_starts_with(value, exec_prefix):
99-
value = "{}{}".format(base_exec_prefix, value[len(exec_prefix) :])
100-
sys.path[at] = value
92+
sys.path[at] = translate_directory(
93+
value, base_executable, exe_dir, exec_prefix, base_prefix, prefix, base_exec_prefix
94+
)
10195

96+
# Now that we can access os.environ["PYTHONPATH"], we can revert our
97+
# rewrite of thoses paths done above
98+
import os
10299

103-
def dir_starts_with(directory, prefix):
104-
return directory == prefix or directory.startswith(prefix + sep)
100+
python_paths = os.environ.get("PYTHONPATH", "").split(":")
101+
for ppath in map(abs_path, python_paths):
102+
translated_ppath = translate_directory(
103+
ppath, base_executable, exe_dir, exec_prefix, base_prefix, prefix, base_exec_prefix
104+
)
105+
try:
106+
at = sys.path.index(translated_ppath)
107+
except ValueError:
108+
pass
109+
else:
110+
sys.path[at] = ppath
105111

106112

107113
def abs_path(value):
@@ -118,6 +124,22 @@ def abs_path(value):
118124
return value
119125

120126

127+
def translate_directory(directory, base_executable, exe_dir, exec_prefix, base_prefix, prefix, base_exec_prefix):
128+
if dir_starts_with(directory, exe_dir):
129+
# content inside the exe folder needs to remap to original executables folder
130+
orig_exe_folder = base_executable[: base_executable.rfind(sep)]
131+
return "{}{}".format(orig_exe_folder, directory[len(exe_dir) :])
132+
elif dir_starts_with(directory, prefix):
133+
return "{}{}".format(base_prefix, directory[len(prefix) :])
134+
elif dir_starts_with(directory, exec_prefix):
135+
return "{}{}".format(base_exec_prefix, directory[len(exec_prefix) :])
136+
return directory
137+
138+
139+
def dir_starts_with(directory, prefix):
140+
return directory == prefix or directory.startswith(prefix + sep)
141+
142+
121143
def disable_user_site_package():
122144
"""Flip the switch on enable user site package"""
123145
# sys.flags is a c-extension type, so we cannot monkeypatch it, replace it with a python class to flip it

tests/unit/create/test_creator.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from virtualenv.pyenv_cfg import PyEnvCfg
2424
from virtualenv.run import cli_run, session_via_cli
2525
from virtualenv.util.path import Path
26-
from virtualenv.util.six import ensure_text
26+
from virtualenv.util.six import ensure_text, ensure_str
2727

2828
CURRENT = PythonInfo.current_system()
2929

@@ -111,7 +111,7 @@ def system(session_app_data):
111111
)
112112
],
113113
)
114-
def test_create_no_seed(python, creator, isolated, system, coverage_env, special_name_dir, method):
114+
def test_create_no_seed(python, creator, isolated, system, coverage_env, special_name_dir, method, override_env_var):
115115
dest = special_name_dir
116116
cmd = [
117117
"-v",
@@ -128,6 +128,9 @@ def test_create_no_seed(python, creator, isolated, system, coverage_env, special
128128
]
129129
if isolated == "global":
130130
cmd.append("--system-site-packages")
131+
# Set a path that is inside the virtualenv
132+
python_path = dest / "foobar"
133+
override_env_var("PYTHONPATH", ensure_str(str(python_path)))
131134
result = cli_run(cmd)
132135
coverage_env()
133136
if IS_PYPY:
@@ -141,6 +144,8 @@ def test_create_no_seed(python, creator, isolated, system, coverage_env, special
141144
assert not content, "\n".join(ensure_text(str(i)) for i in content)
142145
assert result.creator.env_name == ensure_text(dest.name)
143146
debug = result.creator.debug
147+
# Check the PYTHONPATH has not been modified
148+
assert ensure_text(str(python_path)) in debug["sys"]["path"]
144149
sys_path = cleanup_sys_path(debug["sys"]["path"])
145150
system_sys_path = cleanup_sys_path(system["sys"]["path"])
146151
our_paths = set(sys_path) - set(system_sys_path)

0 commit comments

Comments
 (0)