From 3f94d571896d24a10c8545284e3ce9c3c3548a14 Mon Sep 17 00:00:00 2001 From: Diego Date: Sat, 10 Apr 2021 18:20:55 -0400 Subject: [PATCH] Check whether interpreter changed and type (#123) --- nox/virtualenv.py | 30 +++++++++++++++++++++++++----- tests/test_virtualenv.py | 22 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/nox/virtualenv.py b/nox/virtualenv.py index 0e3bbca3..67aee8ac 100644 --- a/nox/virtualenv.py +++ b/nox/virtualenv.py @@ -313,12 +313,19 @@ def _clean_location(self) -> bool: """Deletes any existing virtual environment""" if os.path.exists(self.location): if self.reuse_existing: + self._check_reused_environment() return False else: shutil.rmtree(self.location) return True + def _check_reused_environment(self) -> None: + """Check if reused environment type is the same.""" + with open(os.path.join(self.location, "pyvenv.cfg")) as fp: + old_env = "virtualenv" if "virtualenv" in fp.read() else "venv" + assert old_env == self.venv_or_virtualenv + @property def _resolved_interpreter(self) -> str: """Return the interpreter, appropriately resolved for the platform. @@ -394,12 +401,25 @@ def bin_paths(self) -> List[str]: def create(self) -> bool: """Create the virtualenv or venv.""" if not self._clean_location(): - logger.debug( - "Re-using existing virtual environment at {}.".format( - self.location_name - ) + original = nox.command.run( + [self._resolved_interpreter, "-c", "import sys; print(sys.prefix)"], + silent=True, ) - return False + created = nox.command.run( + [ + os.path.join(self.location, "bin", "python"), + "-c", + "import sys; print(sys.real_prefix)", + ], + silent=True, + ) + if original == created: + logger.debug( + "Re-using existing virtual environment at {}.".format( + self.location_name + ) + ) + return False if self.venv_or_virtualenv == "virtualenv": cmd = [sys.executable, "-m", "virtualenv", self.location] diff --git a/tests/test_virtualenv.py b/tests/test_virtualenv.py index 75598d60..7aabbb21 100644 --- a/tests/test_virtualenv.py +++ b/tests/test_virtualenv.py @@ -244,6 +244,9 @@ def test__clean_location(monkeypatch, make_one): # Don't re-use existing, but doesn't currently exist. # Should return True indicating that the venv needs to be created. + monkeypatch.setattr( + nox.virtualenv.VirtualEnv, "_check_reused_environment", mock.MagicMock() + ) monkeypatch.delattr(nox.virtualenv.shutil, "rmtree") assert not dir_.check() assert venv._clean_location() @@ -289,7 +292,7 @@ def test_bin_windows(make_one): assert dir_.join("Scripts").strpath == venv.bin -def test_create(make_one): +def test_create(monkeypatch, make_one): venv, dir_ = make_one() venv.create() @@ -312,10 +315,27 @@ def test_create(make_one): dir_.ensure("test.txt") assert dir_.join("test.txt").check() venv.reuse_existing = True + monkeypatch.setattr(nox.virtualenv.nox.command, "run", mock.MagicMock()) venv.create() assert dir_.join("test.txt").check() +def test_create_check_interpreter(make_one, monkeypatch, tmpdir): + cmd_mock = mock.MagicMock( + side_effect=["python-1", "python-1", "python-2", "python-3", "python-4"] + ) + monkeypatch.setattr(nox.virtualenv.nox.command, "run", cmd_mock) + test_dir = tmpdir.mkdir("pytest") + fp = test_dir.join("pyvenv.cfg") + fp.write("virtualenv") + venv, dir_ = make_one() + venv_or_virtualenv = "venv" + venv.reuse_existing = True + venv.location = test_dir.strpath + assert not venv.create() + assert venv.create() + + def test_create_venv_backend(make_one): venv, dir_ = make_one(venv=True) venv.create()