Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add venv as an option for venv_backend #231

Merged
merged 7 commits into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,16 @@ def _create_venv(self):
self.venv = CondaEnv(
path, interpreter=self.func.python, reuse_existing=reuse_existing
)
elif self.func.venv_backend == "venv":
self.venv = VirtualEnv(
path,
interpreter=self.func.python,
reuse_existing=reuse_existing,
venv=True,
)
else:
raise ValueError(
"Expected venv_backend one of ('virtualenv', 'conda'), but got '{}'.".format(
"Expected venv_backend one of ('virtualenv', 'conda', 'venv'), but got '{}'.".format(
self.func.venv_backend
)
)
Expand Down
25 changes: 16 additions & 9 deletions nox/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,13 @@ class VirtualEnv(ProcessEnv):

is_sandboxed = True

def __init__(self, location, interpreter=None, reuse_existing=False):
def __init__(self, location, interpreter=None, reuse_existing=False, *, venv=False):
self.location_name = location
self.location = os.path.abspath(location)
self.interpreter = interpreter
self._resolved = None
self.reuse_existing = reuse_existing
self.venv_or_virtualenv = "venv" if venv else "virtualenv"
super(VirtualEnv, self).__init__()

_clean_location = _clean_location
Expand Down Expand Up @@ -275,21 +276,27 @@ def bin(self):
return os.path.join(self.location, "bin")

def create(self):
"""Create the virtualenv."""
"""Create the virtualenv or venv."""
if not self._clean_location():
logger.debug(
"Re-using existing virtualenv at {}.".format(self.location_name)
"Re-using existing virtual environment at {}.".format(
self.location_name
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a risk here that the existing environment used virtualenv, but the request was to use venv? If so, would this result in the caller getting the wrong type of environment? This is a real edge case, and probably isn't a major consideration, but it's worth noting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes there is. Agreed this is an edge case. I suppose there could be a call made to identify whether it's a virtualenv or venv and to assert as necessary before continuing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have an outstanding bug to make sure the -r checks the interpreter version as well. We might be able to just add a note to that issue that checking the backend should be part of the check as well. #123.

)
return False

cmd = [sys.executable, "-m", "virtualenv", self.location]

if self.interpreter:
cmd.extend(["-p", self._resolved_interpreter])
if self.venv_or_virtualenv == "virtualenv":
cmd = [sys.executable, "-m", "virtualenv", self.location]
if self.interpreter:
cmd.extend(["-p", self._resolved_interpreter])
else:
cmd = [self._resolved_interpreter, "-m", "venv", self.location]

logger.info(
"Creating virtualenv using {} in {}".format(
os.path.basename(self._resolved_interpreter), self.location_name
"Creating virtual environment ({}) using {} in {}".format(
self.venv_or_virtualenv,
os.path.basename(self._resolved_interpreter),
self.location_name,
)
)
nox.command.run(cmd, silent=True, log=False)
Expand Down
1 change: 1 addition & 0 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ def test__create_venv(self, create):
"virtualenv",
nox.virtualenv.VirtualEnv,
),
("nox.virtualenv.VirtualEnv.create", "venv", nox.virtualenv.VirtualEnv),
("nox.virtualenv.CondaEnv.create", "conda", nox.virtualenv.CondaEnv),
],
)
Expand Down
6 changes: 6 additions & 0 deletions tests/test_virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def test_constructor_defaults(make_one):
assert venv.location
assert venv.interpreter is None
assert venv.reuse_existing is False
assert venv.venv_or_virtualenv == "virtualenv"


@pytest.mark.skipif(IS_WINDOWS, reason="Not testing multiple interpreters on Windows.")
Expand Down Expand Up @@ -213,6 +214,11 @@ def test_create(make_one):
assert dir_.join("test.txt").check()


def test_create_venv_backend(make_one):
venv, dir_ = make_one(venv=True)
venv.create()


@pytest.mark.skipif(IS_WINDOWS, reason="Not testing multiple interpreters on Windows.")
def test_create_interpreter(make_one):
venv, dir_ = make_one(interpreter="python3")
Expand Down