Skip to content

Commit

Permalink
feat: add a uv backend
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
  • Loading branch information
henryiii committed Feb 16, 2024
1 parent 5c82dc5 commit cd93c8e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
18 changes: 8 additions & 10 deletions nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,12 @@ def install(self, *args: str, **kwargs: Any) -> None:
if "silent" not in kwargs:
kwargs["silent"] = True

self._run("python", "-m", "pip", "install", *args, external="error", **kwargs)
if getattr(venv, "venv_prog", "") == "uv":
self._run("uv", "pip", "install", *args, external="error", **kwargs)
else:
self._run(
"python", "-m", "pip", "install", *args, external="error", **kwargs
)

def notify(
self,
Expand Down Expand Up @@ -748,11 +753,12 @@ def _create_venv(self) -> None:
self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs
)

if backend is None or backend == "virtualenv":
if backend is None or backend in {"virtualenv", "venv", "uv"}:
self.venv = VirtualEnv(
self.envdir,
interpreter=self.func.python, # type: ignore[arg-type]
reuse_existing=reuse_existing,
venv=backend or "virtualenv",
venv_params=self.func.venv_params,
)
elif backend in {"conda", "mamba"}:
Expand All @@ -763,14 +769,6 @@ def _create_venv(self) -> None:
venv_params=self.func.venv_params,
conda_cmd=backend,
)
elif backend == "venv":
self.venv = VirtualEnv(
self.envdir,
interpreter=self.func.python, # type: ignore[arg-type]
reuse_existing=reuse_existing,
venv=True,
venv_params=self.func.venv_params,
)
else:
raise ValueError(
"Expected venv_backend one of ('virtualenv', 'conda', 'mamba',"
Expand Down
19 changes: 14 additions & 5 deletions nox/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,22 +312,23 @@ class VirtualEnv(ProcessEnv):
"""

is_sandboxed = True
allowed_globals = ("uv",)

def __init__(
self,
location: str,
interpreter: str | None = None,
reuse_existing: bool = False,
*,
venv: bool = False,
venv: str = "virtualenv",
venv_params: Any = None,
):
self.location_name = location
self.location = os.path.abspath(location)
self.interpreter = interpreter
self._resolved: None | str | InterpreterNotFound = None
self.reuse_existing = reuse_existing
self.venv_or_virtualenv = "venv" if venv else "virtualenv"
self.venv_prog = venv
self.venv_params = venv_params or []
super().__init__(env={"VIRTUAL_ENV": self.location})

Expand Down Expand Up @@ -359,7 +360,7 @@ def _check_reused_environment_type(self) -> bool:
old_env = (
"virtualenv" if any(pattern.match(line) for line in fp) else "venv"
)
return old_env == self.venv_or_virtualenv
return old_env == self.venv_prog

def _check_reused_environment_interpreter(self) -> bool:
"""Check if reused environment interpreter is the same."""
Expand Down Expand Up @@ -474,18 +475,26 @@ def create(self) -> bool:

return False

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

resolved_interpreter_name = os.path.basename(self._resolved_interpreter)

logger.info(
f"Creating virtual environment ({self.venv_or_virtualenv}) using"
f"Creating virtual environment ({self.venv_prog}) using"
f" {resolved_interpreter_name} in {self.location_name}"
)
nox.command.run(cmd, silent=True, log=nox.options.verbose or False)
Expand Down

0 comments on commit cd93c8e

Please sign in to comment.