Skip to content

Commit

Permalink
feat: Allow Noxfile to specify nox.options.error_on_missing_interpret…
Browse files Browse the repository at this point in the history
…ers (#725)
  • Loading branch information
samypr100 committed Jul 12, 2023
1 parent 6429b0f commit b88ecad
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
9 changes: 7 additions & 2 deletions nox/_option_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def default(self) -> bool | str | None | list[str]:

def flag_pair_merge_func(
enable_name: str,
enable_default: bool | Callable[[], bool],
disable_name: str,
command_args: Namespace,
noxfile_args: Namespace,
Expand Down Expand Up @@ -155,6 +156,10 @@ def flag_pair_merge_func(
noxfile_value = getattr(noxfile_args, enable_name)
command_value = getattr(command_args, enable_name)
disable_value = getattr(command_args, disable_name)
default_value = enable_default() if callable(enable_default) else enable_default
if default_value and disable_value is None and noxfile_value != default_value:
# Makes sure make_flag_pair with default=true can be overridden via noxfile
disable_value = True

return (command_value or noxfile_value) and not disable_value

Expand All @@ -163,7 +168,7 @@ def make_flag_pair(
name: str,
enable_flags: tuple[str, str] | tuple[str],
disable_flags: tuple[str, str] | tuple[str],
default: bool = False,
default: bool | Callable[[], bool] = False,
**kwargs: Any,
) -> tuple[Option, Option]:
"""Returns two options - one to enable a behavior and another to disable it.
Expand All @@ -178,7 +183,7 @@ def make_flag_pair(
name,
*enable_flags,
noxfile=True,
merge_func=functools.partial(flag_pair_merge_func, name, disable_name),
merge_func=functools.partial(flag_pair_merge_func, name, default, disable_name),
default=default,
**kwargs,
)
Expand Down
2 changes: 1 addition & 1 deletion nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ def _session_completer(
("--no-error-on-missing-interpreters",),
group=options.groups["execution"],
help="Error instead of skipping sessions if an interpreter can not be located.",
default="CI" in os.environ,
default=lambda: "CI" in os.environ,
),
*_option_set.make_flag_pair(
"error_on_external_run",
Expand Down
1 change: 1 addition & 0 deletions tests/resources/noxfile_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import nox

nox.options.reuse_existing_virtualenvs = True
# nox.options.error_on_missing_interpreters = {error_on_missing_interpreters} # used by tests
nox.options.sessions = ["test"]


Expand Down
53 changes: 53 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,3 +694,56 @@ def test_main_reuse_existing_virtualenvs_no_install(monkeypatch):
nox.__main__.main()
config = execute.call_args[1]["global_config"]
assert config.reuse_existing_virtualenvs and config.no_install


@pytest.mark.parametrize(
("should_set_ci_env_var", "noxfile_option_value", "expected_final_value"),
[
(True, None, True),
(True, True, True),
(True, False, False),
(False, None, False),
(False, True, True),
(False, False, False),
],
)
def test_main_noxfile_options_with_ci_override(
monkeypatch,
tmp_path,
should_set_ci_env_var,
noxfile_option_value,
expected_final_value,
):
monkeypatch.delenv("CI", raising=False) # make sure we have a clean environment
if should_set_ci_env_var:
monkeypatch.setenv("CI", "True")
# Reload nox.options taking into consideration monkeypatch.{delenv|setenv}
monkeypatch.setattr(
nox._options, "noxfile_options", nox._options.options.noxfile_namespace()
)
monkeypatch.setattr(nox, "options", nox._options.noxfile_options)

noxfile_path = Path(RESOURCES) / "noxfile_options.py"
if noxfile_option_value is not None:
# Temp noxfile with error_on_missing_interpreters set
noxfile_text = noxfile_path.read_text()
noxfile_text = noxfile_text.replace("# nox", "nox")
noxfile_text = noxfile_text.format(
error_on_missing_interpreters=noxfile_option_value
)
noxfile_path = tmp_path / "noxfile.py"
noxfile_path.write_text(noxfile_text)

monkeypatch.setattr(
sys,
"argv",
["nox", "-l", "--noxfile", str(noxfile_path)],
)

with mock.patch(
"nox.tasks.honor_list_request", return_value=0
) as honor_list_request:
with mock.patch("sys.exit"):
nox.__main__.main()
config = honor_list_request.call_args[1]["global_config"]
assert config.error_on_missing_interpreters == expected_final_value

0 comments on commit b88ecad

Please sign in to comment.