Skip to content

Commit 45837ae

Browse files
Merge 8e07e2a into master
2 parents 014b12b + 8e07e2a commit 45837ae

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 7.1
2+
3+
- Fixed: `call` command sometimes received incorrect `$PYTHONPATH` values on systems
4+
with multiple versions of Python
5+
16
# 7.0
27

38
- The `create`, `call`, `delete`, `recreate` and `path` commands work on Windows.

tests/pythonpath_test.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import os
2+
import unittest
3+
4+
from vien.main import _insert_into_pythonpath
5+
6+
7+
@unittest.skipUnless(os.name == 'posix', "posix colons format")
8+
class PythonPathTestPosix(unittest.TestCase):
9+
def test_empty(self):
10+
os.environ["PYTHONPATH"] = ''
11+
self.assertEqual(_insert_into_pythonpath('/a/b/c'),
12+
'/a/b/c')
13+
14+
def test_empty_multiple(self):
15+
os.environ["PYTHONPATH"] = ':::'
16+
self.assertEqual(_insert_into_pythonpath('/a/b/c'),
17+
'/a/b/c')
18+
19+
def test_empties_skipped(self):
20+
os.environ["PYTHONPATH"] = ':xx:::::yy:::'
21+
self.assertEqual(_insert_into_pythonpath('/a/b/c'),
22+
'/a/b/c:xx:yy')
23+
24+
def test_duplicates_skipped(self):
25+
os.environ["PYTHONPATH"] = 'aaa:bbb:ccc'
26+
self.assertEqual(_insert_into_pythonpath('bbb'),
27+
'aaa:bbb:ccc')
28+
29+
def test_two(self):
30+
os.environ["PYTHONPATH"] = ' /bbb/ccc : /dd/ee/ff '
31+
self.assertEqual(_insert_into_pythonpath('/a/b/c'),
32+
'/a/b/c:/bbb/ccc:/dd/ee/ff')
33+
34+
35+
@unittest.skipUnless(os.name == 'nt', "windows semicolons format")
36+
class PythonPathTestWindows(unittest.TestCase):
37+
# most tests are done on POSIX. Here we just test ';' and 'C:/'
38+
def test_two(self):
39+
os.environ["PYTHONPATH"] = ' C:/ccc/33 ; D:/ddd/44 '
40+
self.assertEqual(_insert_into_pythonpath('E:/my/project'),
41+
'E:/my/project;C:/ccc/33;D:/ddd/44')
42+
43+
44+
if __name__ == "__main__":
45+
unittest.main()

vien/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = "7.0.1"
1+
__version__ = "7.1.0"
22
__copyright__ = "(c) 2020-2021 Artëm IG <github.com/rtmigo>"
33
__license__ = "BSD-3-Clause"

vien/main.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,23 @@ def _insert_into_pythonpath(insert_me: str) -> str:
337337
# "The format is the same as the shell’s PATH: one or more directory
338338
# pathnames separated by os.pathsep (e.g. colons on Unix or semicolons
339339
# on Windows)"
340-
return os.pathsep.join([insert_me] + sys.path)
340+
####
341+
# $PYTHONPATH and sys.path are not the same.
342+
# - sys.path contains directories used by the current interpreter
343+
# (the one that runs vien)
344+
# - $PYTHONPATH is the variable to be used by all interpreters
345+
#
346+
# For example, if we run vien on Python 3.7 and trying to use venv with
347+
# Python 3.9, we should not provide out own sys.path (3.7) to the child
348+
# interpreter (3.9).
349+
350+
parts = [p.strip() for p in
351+
os.environ.get("PYTHONPATH", '').split(os.pathsep)]
352+
parts = [p for p in parts if p]
353+
354+
if insert_me not in parts:
355+
parts.insert(0, insert_me)
356+
return os.pathsep.join(parts)
341357

342358

343359
def child_env(proj_path: Path) -> Optional[Dict]:
@@ -355,6 +371,7 @@ def main_call(venv_dir: Path,
355371
proj_path: Path,
356372
other_args: List[str]):
357373
python_exe = venv_dir_to_python_exe(venv_dir)
374+
# print("EXE",python_exe)
358375
assert len(other_args) > 0
359376
args = [str(python_exe)] + other_args
360377

0 commit comments

Comments
 (0)