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

refactor: pull out env creation into helper method #912

Merged
merged 2 commits into from
Jan 21, 2025
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
11 changes: 2 additions & 9 deletions nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,14 +618,7 @@ def _run(
args = (nox.virtualenv.UV, *args[1:])

# Combine the env argument with our virtualenv's env vars.
env = env or {}
env = {**self.env, **env}
if include_outer_env:
env = {**os.environ, **env}
if self.virtualenv.bin_paths:
env["PATH"] = os.pathsep.join(
[*self.virtualenv.bin_paths, env.get("PATH") or ""]
)
env = self.virtualenv._get_env(env or {}, include_outer_env=include_outer_env)

# If --error-on-external-run is specified, error on external programs.
if self._runner.global_config.error_on_external_run and external is None:
Expand Down Expand Up @@ -821,7 +814,7 @@ def install(
if not isinstance(
venv, (CondaEnv, VirtualEnv, PassthroughEnv)
): # pragma: no cover
msg = "A session without a virtualenv can not install dependencies."
msg = f"A session without a virtualenv (got {venv!r}) can not install dependencies."
raise TypeError(msg)
if isinstance(venv, PassthroughEnv):
if self._runner.global_config.no_install:
Expand Down
21 changes: 21 additions & 0 deletions nox/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,27 @@ def venv_backend(self) -> str:
Returns the string used to select this environment.
"""

def _get_env(
self,
/,
env: Mapping[str, str | None],
*,
include_outer_env: bool = True,
) -> dict[str, str | None]:
"""
Get the computed environment, with bin paths added. You can request
the outer environment be excluded. The initial env can be empty.
"""

computed_env = {**self.env, **env}
if include_outer_env:
computed_env = {**os.environ, **computed_env}
if self.bin_paths:
computed_env["PATH"] = os.pathsep.join(
[*self.bin_paths, computed_env.get("PATH") or ""]
)
return computed_env


def locate_via_py(version: str) -> str | None:
"""Find the Python executable using the Windows Launcher.
Expand Down
51 changes: 27 additions & 24 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ def test__normalize_path_give_up() -> None:
assert "any-path" in norm_path


class FakeEnv(mock.MagicMock):
_get_env = nox.virtualenv.VirtualEnv._get_env


def make_fake_env(venv_backend: str = "venv", **kwargs: Any) -> FakeEnv:
return FakeEnv(
spec=nox.virtualenv.VirtualEnv,
env={},
venv_backend=venv_backend,
**kwargs,
)


class TestSession:
def make_session_and_runner(
self,
Expand All @@ -122,11 +135,8 @@ def make_session_and_runner(
),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv.bin_paths = ["/no/bin/for/you"] # type: ignore[misc]
runner.venv.venv_backend = "venv" # type: ignore[misc]
runner.venv = make_fake_env(bin_paths=["/no/bin/for/you"])
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
return nox.sessions.Session(runner=runner), runner

def test_create_tmp(self) -> None:
Expand Down Expand Up @@ -750,10 +760,8 @@ def test_install(self) -> None:
global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv.venv_backend = "venv" # type: ignore[misc]
runner.venv = make_fake_env()
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)

class SessionNoSlots(nox.sessions.Session):
pass
Expand Down Expand Up @@ -782,10 +790,8 @@ def test_install_non_default_kwargs(self) -> None:
global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv.venv_backend = "venv" # type: ignore[misc]
runner.venv = make_fake_env()
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)

class SessionNoSlots(nox.sessions.Session):
pass
Expand Down Expand Up @@ -936,10 +942,9 @@ def test_install_uv(self) -> None:
global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv.venv_backend = "uv" # type: ignore[misc]
runner.venv = make_fake_env(venv_backend="uv")
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
assert runner.venv.venv_backend == "uv"

class SessionNoSlots(nox.sessions.Session):
pass
Expand All @@ -965,10 +970,9 @@ def test_install_uv_command(self, monkeypatch: pytest.MonkeyPatch) -> None:
global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv.venv_backend = "uv" # type: ignore[misc]
runner.venv = make_fake_env(venv_backend="uv")
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
assert runner.venv.venv_backend == "uv"

class SessionNoSlots(nox.sessions.Session):
pass
Expand Down Expand Up @@ -1241,9 +1245,8 @@ def test__reuse_venv_invalid(self) -> None:
def make_runner_with_mock_venv(self) -> nox.sessions.SessionRunner:
runner = self.make_runner()
runner._create_venv = mock.Mock() # type: ignore[method-assign]
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
assert runner.venv
runner.venv.env = {}
runner.venv = make_fake_env()
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
return runner

def test_execute_noop_success(self, caplog: pytest.LogCaptureFixture) -> None:
Expand Down
Loading