From 4302f4e0043177d2fc8c7b2852e2e2054249b432 Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Mon, 29 Mar 2021 16:54:30 -0400 Subject: [PATCH] Use `{env}/bin` instead of `{env}/Scripts` when Python is from MSYS2 on Windows. MSYS2 prefers a Linux filesystem layout, but is otherwise a native Windows interpreter. Fixes #1982 --- CONTRIBUTORS | 1 + docs/changelog/1982.bugfix.rst | 3 +++ src/tox/config/__init__.py | 5 +++++ src/tox/helper/get_version.py | 2 ++ src/tox/interpreters/__init__.py | 2 ++ tests/unit/config/test_config.py | 16 ++++++++++++++++ tests/unit/interpreters/test_interpreters.py | 4 +++- 7 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/1982.bugfix.rst diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 55dd6d1b3e..5be3eaa099 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -48,6 +48,7 @@ Ionel Maries Cristian Itxaka Serrano Jake Windle Jannis Leidel +Jesse Schwartzentruber Joachim Brandon LeBlanc Johannes Christ John Mark Vandenberg diff --git a/docs/changelog/1982.bugfix.rst b/docs/changelog/1982.bugfix.rst new file mode 100644 index 0000000000..6cd703a71c --- /dev/null +++ b/docs/changelog/1982.bugfix.rst @@ -0,0 +1,3 @@ +Distinguish between normal Windows Python and MSYS2 Python when looking for +virtualenv executable path. Adds os.sep to :class:`InterpreterInfo` +- by :user:`jschwartzentruber` diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py index 278d4b2b6d..5e0c178f6d 100644 --- a/src/tox/config/__init__.py +++ b/src/tox/config/__init__.py @@ -1053,6 +1053,11 @@ def get_envbindir(self): isinstance(self.python_info, NoInterpreterInfo) or tox.INFO.IS_WIN is False or self.python_info.implementation == "Jython" + or ( + # this combination is MSYS2 + tox.INFO.IS_WIN + and self.python_info.ossep == "/" + ) or ( tox.INFO.IS_WIN and self.python_info.implementation == "PyPy" diff --git a/src/tox/helper/get_version.py b/src/tox/helper/get_version.py index b1a8455a4a..b39660de69 100644 --- a/src/tox/helper/get_version.py +++ b/src/tox/helper/get_version.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import json +import os import platform import sys @@ -11,6 +12,7 @@ "version": sys.version, "is_64": sys.maxsize > 2 ** 32, "sysplatform": sys.platform, + "ossep": os.sep, "extra_version_info": getattr(sys, "pypy_version_info", None), } info_as_dump = json.dumps(info) diff --git a/src/tox/interpreters/__init__.py b/src/tox/interpreters/__init__.py index a31314004e..d2b0044ec4 100644 --- a/src/tox/interpreters/__init__.py +++ b/src/tox/interpreters/__init__.py @@ -103,6 +103,7 @@ def __init__( version_info, sysplatform, is_64, + ossep, extra_version_info, ): self.implementation = implementation @@ -111,6 +112,7 @@ def __init__( self.version_info = version_info self.sysplatform = sysplatform self.is_64 = is_64 + self.ossep = ossep self.extra_version_info = extra_version_info def __str__(self): diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index b4bd24fb56..cfc564c018 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -1469,6 +1469,22 @@ def test_envbindir_jython(self, newconfig, bp): if bp == "jython": assert envconfig.envpython == envconfig.envbindir.join(bp) + @pytest.mark.parametrize("sep, bindir", [("\\", "Scripts"), ("/", "bin")]) + def test_envbindir_win(self, newconfig, monkeypatch, sep, bindir): + monkeypatch.setattr(tox.INFO, "IS_WIN", True) + config = newconfig( + """ + [testenv] + basepython=python + """, + ) + assert len(config.envconfigs) == 1 + envconfig = config.envconfigs["python"] + envconfig.python_info.ossep = sep # force os.sep result + # on win32 with msys2, virtualenv uses "bin" for python + assert envconfig.envbindir.basename == bindir + assert envconfig.envpython == envconfig.envbindir.join("python") + @pytest.mark.parametrize("plat", ["win32", "linux2"]) def test_passenv_as_multiline_list(self, newconfig, monkeypatch, plat): monkeypatch.setattr(tox.INFO, "IS_WIN", plat == "win32") diff --git a/tests/unit/interpreters/test_interpreters.py b/tests/unit/interpreters/test_interpreters.py index fd364bafb1..298a4aae42 100644 --- a/tests/unit/interpreters/test_interpreters.py +++ b/tests/unit/interpreters/test_interpreters.py @@ -192,7 +192,9 @@ def info( version_info="my-version-info", sysplatform="my-sys-platform", ): - return InterpreterInfo(implementation, executable, version_info, sysplatform, True, None) + return InterpreterInfo( + implementation, executable, version_info, sysplatform, True, "/", None + ) def test_data(self): x = self.info("larry", "moe", "shemp", "curly")