Skip to content

Commit d25a067

Browse files
authored
refactor: pull out env creation into helper method (#912)
* refactor: pull out env creation into method Signed-off-by: Henry Schreiner <[email protected]> * refactor: make get_env private Signed-off-by: Henry Schreiner <[email protected]> --------- Signed-off-by: Henry Schreiner <[email protected]>
1 parent a02eb79 commit d25a067

File tree

3 files changed

+50
-33
lines changed

3 files changed

+50
-33
lines changed

nox/sessions.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -618,14 +618,7 @@ def _run(
618618
args = (nox.virtualenv.UV, *args[1:])
619619

620620
# Combine the env argument with our virtualenv's env vars.
621-
env = env or {}
622-
env = {**self.env, **env}
623-
if include_outer_env:
624-
env = {**os.environ, **env}
625-
if self.virtualenv.bin_paths:
626-
env["PATH"] = os.pathsep.join(
627-
[*self.virtualenv.bin_paths, env.get("PATH") or ""]
628-
)
621+
env = self.virtualenv._get_env(env or {}, include_outer_env=include_outer_env)
629622

630623
# If --error-on-external-run is specified, error on external programs.
631624
if self._runner.global_config.error_on_external_run and external is None:
@@ -821,7 +814,7 @@ def install(
821814
if not isinstance(
822815
venv, (CondaEnv, VirtualEnv, PassthroughEnv)
823816
): # pragma: no cover
824-
msg = "A session without a virtualenv can not install dependencies."
817+
msg = f"A session without a virtualenv (got {venv!r}) can not install dependencies."
825818
raise TypeError(msg)
826819
if isinstance(venv, PassthroughEnv):
827820
if self._runner.global_config.no_install:

nox/virtualenv.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,27 @@ def venv_backend(self) -> str:
191191
Returns the string used to select this environment.
192192
"""
193193

194+
def _get_env(
195+
self,
196+
/,
197+
env: Mapping[str, str | None],
198+
*,
199+
include_outer_env: bool = True,
200+
) -> dict[str, str | None]:
201+
"""
202+
Get the computed environment, with bin paths added. You can request
203+
the outer environment be excluded. The initial env can be empty.
204+
"""
205+
206+
computed_env = {**self.env, **env}
207+
if include_outer_env:
208+
computed_env = {**os.environ, **computed_env}
209+
if self.bin_paths:
210+
computed_env["PATH"] = os.pathsep.join(
211+
[*self.bin_paths, computed_env.get("PATH") or ""]
212+
)
213+
return computed_env
214+
194215

195216
def locate_via_py(version: str) -> str | None:
196217
"""Find the Python executable using the Windows Launcher.

tests/test_sessions.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ def test__normalize_path_give_up() -> None:
105105
assert "any-path" in norm_path
106106

107107

108+
class FakeEnv(mock.MagicMock):
109+
_get_env = nox.virtualenv.VirtualEnv._get_env
110+
111+
112+
def make_fake_env(venv_backend: str = "venv", **kwargs: Any) -> FakeEnv:
113+
return FakeEnv(
114+
spec=nox.virtualenv.VirtualEnv,
115+
env={},
116+
venv_backend=venv_backend,
117+
**kwargs,
118+
)
119+
120+
108121
class TestSession:
109122
def make_session_and_runner(
110123
self,
@@ -122,11 +135,8 @@ def make_session_and_runner(
122135
),
123136
manifest=mock.create_autospec(nox.manifest.Manifest),
124137
)
125-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
126-
assert runner.venv
127-
runner.venv.env = {}
128-
runner.venv.bin_paths = ["/no/bin/for/you"] # type: ignore[misc]
129-
runner.venv.venv_backend = "venv" # type: ignore[misc]
138+
runner.venv = make_fake_env(bin_paths=["/no/bin/for/you"])
139+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
130140
return nox.sessions.Session(runner=runner), runner
131141

132142
def test_create_tmp(self) -> None:
@@ -750,10 +760,8 @@ def test_install(self) -> None:
750760
global_config=_options.options.namespace(posargs=[]),
751761
manifest=mock.create_autospec(nox.manifest.Manifest),
752762
)
753-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
754-
assert runner.venv
755-
runner.venv.env = {}
756-
runner.venv.venv_backend = "venv" # type: ignore[misc]
763+
runner.venv = make_fake_env()
764+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
757765

758766
class SessionNoSlots(nox.sessions.Session):
759767
pass
@@ -782,10 +790,8 @@ def test_install_non_default_kwargs(self) -> None:
782790
global_config=_options.options.namespace(posargs=[]),
783791
manifest=mock.create_autospec(nox.manifest.Manifest),
784792
)
785-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
786-
assert runner.venv
787-
runner.venv.env = {}
788-
runner.venv.venv_backend = "venv" # type: ignore[misc]
793+
runner.venv = make_fake_env()
794+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
789795

790796
class SessionNoSlots(nox.sessions.Session):
791797
pass
@@ -936,10 +942,9 @@ def test_install_uv(self) -> None:
936942
global_config=_options.options.namespace(posargs=[]),
937943
manifest=mock.create_autospec(nox.manifest.Manifest),
938944
)
939-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
940-
assert runner.venv
941-
runner.venv.env = {}
942-
runner.venv.venv_backend = "uv" # type: ignore[misc]
945+
runner.venv = make_fake_env(venv_backend="uv")
946+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
947+
assert runner.venv.venv_backend == "uv"
943948

944949
class SessionNoSlots(nox.sessions.Session):
945950
pass
@@ -965,10 +970,9 @@ def test_install_uv_command(self, monkeypatch: pytest.MonkeyPatch) -> None:
965970
global_config=_options.options.namespace(posargs=[]),
966971
manifest=mock.create_autospec(nox.manifest.Manifest),
967972
)
968-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
969-
assert runner.venv
970-
runner.venv.env = {}
971-
runner.venv.venv_backend = "uv" # type: ignore[misc]
973+
runner.venv = make_fake_env(venv_backend="uv")
974+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
975+
assert runner.venv.venv_backend == "uv"
972976

973977
class SessionNoSlots(nox.sessions.Session):
974978
pass
@@ -1241,9 +1245,8 @@ def test__reuse_venv_invalid(self) -> None:
12411245
def make_runner_with_mock_venv(self) -> nox.sessions.SessionRunner:
12421246
runner = self.make_runner()
12431247
runner._create_venv = mock.Mock() # type: ignore[method-assign]
1244-
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
1245-
assert runner.venv
1246-
runner.venv.env = {}
1248+
runner.venv = make_fake_env()
1249+
assert isinstance(runner.venv, nox.virtualenv.VirtualEnv)
12471250
return runner
12481251

12491252
def test_execute_noop_success(self, caplog: pytest.LogCaptureFixture) -> None:

0 commit comments

Comments
 (0)