Skip to content

Commit

Permalink
feat: expose main as nox.main (#878)
Browse files Browse the repository at this point in the history
* feat: expose main as nox.main

Signed-off-by: Henry Schreiner <[email protected]>

* Update tutorial.rst

Co-authored-by: Stargirl Flowers <[email protected]>

* Update tutorial.rst

---------

Signed-off-by: Henry Schreiner <[email protected]>
Co-authored-by: Stargirl Flowers <[email protected]>
  • Loading branch information
henryiii and theacodes authored Oct 29, 2024
1 parent 9cb5661 commit 7a94886
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 33 deletions.
22 changes: 22 additions & 0 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,28 @@ the tags, so all three sessions:
* flake8
Running without the nox command
-------------------------------

With a few small additions to your noxfile, you can support running using only
a generalized Python runner, such as ``pipx run noxfile.py``, ``uv run
noxfile.py``, ``pdm run noxfile.py``, or ``hatch run noxfile.py``. You need to
have the following comment in your noxfile:

.. code-block:: python
# /// script
# dependencies = ["nox"]
# ///
And the following block of code:

.. code-block:: python
if __name__ == "__main__":
nox.main()
Next steps
----------

Expand Down
2 changes: 2 additions & 0 deletions nox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from __future__ import annotations

from nox import project
from nox.__main__ import main
from nox._options import noxfile_options as options
from nox._parametrize import Param as param
from nox._parametrize import parametrize_decorator as parametrize
Expand All @@ -31,4 +32,5 @@
"parametrize",
"project",
"session",
"main",
]
65 changes: 32 additions & 33 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import pytest

import nox
import nox.__main__
import nox._options
import nox.registry
import nox.sessions
Expand All @@ -46,7 +45,7 @@ def test_main_no_args(monkeypatch):

# Call the function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand Down Expand Up @@ -84,7 +83,7 @@ def test_main_long_form_args():

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand Down Expand Up @@ -118,7 +117,7 @@ def test_main_no_venv(monkeypatch, capsys):
)

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
stdout, stderr = capsys.readouterr()
assert stdout == "Noms, cheddar so good!\n"
assert (
Expand All @@ -140,7 +139,7 @@ def test_main_no_venv_error():
"--no-venv",
]
with pytest.raises(ValueError, match="You can not use"):
nox.__main__.main()
nox.main()


def test_main_short_form_args(monkeypatch):
Expand All @@ -166,7 +165,7 @@ def test_main_short_form_args(monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand All @@ -187,7 +186,7 @@ def test_main_explicit_sessions(monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand All @@ -205,7 +204,7 @@ def test_main_explicit_sessions_with_spaces_in_names(monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand Down Expand Up @@ -246,7 +245,7 @@ def test_main_list_option_from_nox_env_var(monkeypatch, var, option, env, values

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand Down Expand Up @@ -274,7 +273,7 @@ def test_default_venv_backend_option(monkeypatch, options, env, expected):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand All @@ -290,7 +289,7 @@ def test_main_positional_args(capsys, monkeypatch):
with mock.patch.object(sys, "exit", fake_exit), pytest.raises(
ValueError, match="asdf!"
):
nox.__main__.main()
nox.main()
_, stderr = capsys.readouterr()
assert "Unknown argument(s) '1 2 3'" in stderr
fake_exit.assert_called_once_with(2)
Expand All @@ -300,7 +299,7 @@ def test_main_positional_args(capsys, monkeypatch):
with mock.patch.object(sys, "exit", fake_exit), pytest.raises(
ValueError, match="asdf!"
):
nox.__main__.main()
nox.main()
_, stderr = capsys.readouterr()
assert "Unknown argument(s) '1 2 3'" in stderr
fake_exit.assert_called_once_with(2)
Expand All @@ -313,7 +312,7 @@ def test_main_positional_with_double_hyphen(monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand All @@ -331,7 +330,7 @@ def test_main_positional_flag_like_with_double_hyphen(monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(0)
assert execute.called

Expand All @@ -346,7 +345,7 @@ def test_main_version(capsys, monkeypatch):
with contextlib.ExitStack() as stack:
execute = stack.enter_context(mock.patch("nox.workflow.execute"))
exit_mock = stack.enter_context(mock.patch("sys.exit"))
nox.__main__.main()
nox.main()
_, err = capsys.readouterr()
assert VERSION in err
exit_mock.assert_not_called()
Expand All @@ -359,7 +358,7 @@ def test_main_help(capsys, monkeypatch):
with contextlib.ExitStack() as stack:
execute = stack.enter_context(mock.patch("nox.workflow.execute"))
exit_mock = stack.enter_context(mock.patch("sys.exit"))
nox.__main__.main()
nox.main()
out, _ = capsys.readouterr()
assert "help" in out
exit_mock.assert_not_called()
Expand All @@ -371,7 +370,7 @@ def test_main_failure(monkeypatch):
with mock.patch("nox.workflow.execute") as execute:
execute.return_value = 1
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_once_with(1)


Expand All @@ -389,7 +388,7 @@ def test_main_nested_config(capsys, monkeypatch):
)

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
stdout, stderr = capsys.readouterr()
assert stdout == "Noms, cheddar so good!\n"
assert "Session snack(cheese='cheddar') was successful." in stderr
Expand All @@ -410,7 +409,7 @@ def test_main_session_with_names(capsys, monkeypatch):
)

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
stdout, stderr = capsys.readouterr()
assert stdout == "Noms, cheddar so good!\n"
assert "Session cheese list(cheese='cheddar') was successful." in stderr
Expand All @@ -423,7 +422,7 @@ def _run_nox(*args):
monkeypatch.setattr(sys, "argv", ["nox", *args])

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
stdout, stderr = capsys.readouterr()
returncode = sys_exit.call_args[0][0]

Expand Down Expand Up @@ -567,7 +566,7 @@ def test_main_noxfile_options(monkeypatch, generate_noxfile_options):
honor_list_request.return_value = 0

with mock.patch("sys.exit"):
nox.__main__.main()
nox.main()

assert honor_list_request.called

Expand Down Expand Up @@ -597,7 +596,7 @@ def test_main_noxfile_options_disabled_by_flag(monkeypatch, generate_noxfile_opt
honor_list_request.return_value = 0

with mock.patch("sys.exit"):
nox.__main__.main()
nox.main()

assert honor_list_request.called

Expand All @@ -619,7 +618,7 @@ def test_main_noxfile_options_sessions(monkeypatch, generate_noxfile_options):
honor_list_request.return_value = 0

with mock.patch("sys.exit"):
nox.__main__.main()
nox.main()

assert honor_list_request.called

Expand Down Expand Up @@ -670,7 +669,7 @@ def test_main_noxfile_options_with_pythons_override(
)

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
_, stderr = capsys.readouterr()
sys_exit.assert_called_once_with(0)

Expand All @@ -697,7 +696,7 @@ def test_main_noxfile_options_with_sessions_override(
)

with mock.patch("sys.exit") as sys_exit:
nox.__main__.main()
nox.main()
_, stderr = capsys.readouterr()
sys_exit.assert_called_once_with(0)

Expand All @@ -721,7 +720,7 @@ def test_main_color_from_isatty(monkeypatch, isatty_value, expected):

# Call the main function.
with mock.patch.object(sys, "exit"):
nox.__main__.main()
nox.main()

config = execute.call_args[1]["global_config"]
assert config.color == expected
Expand All @@ -744,7 +743,7 @@ def test_main_color_options(monkeypatch, color_opt, expected):

# Call the main function.
with mock.patch.object(sys, "exit"):
nox.__main__.main()
nox.main()

config = execute.call_args[1]["global_config"]
assert config.color == expected
Expand All @@ -757,7 +756,7 @@ def test_main_color_conflict(capsys, monkeypatch):

# Call the main function.
with mock.patch.object(sys, "exit") as exit:
nox.__main__.main()
nox.main()
exit.assert_called_with(1)

_, err = capsys.readouterr()
Expand All @@ -769,7 +768,7 @@ def test_main_force_python(monkeypatch):
monkeypatch.setattr(sys, "argv", ["nox", "--force-python=3.11"])
with mock.patch("nox.workflow.execute", return_value=0) as execute:
with mock.patch.object(sys, "exit"):
nox.__main__.main()
nox.main()
config = execute.call_args[1]["global_config"]
assert config.pythons == config.extra_pythons == ["3.11"]

Expand All @@ -778,7 +777,7 @@ def test_main_reuse_existing_virtualenvs_no_install(monkeypatch):
monkeypatch.setattr(sys, "argv", ["nox", "-R"])
with mock.patch("nox.workflow.execute", return_value=0) as execute:
with mock.patch.object(sys, "exit"):
nox.__main__.main()
nox.main()
config = execute.call_args[1]["global_config"]
assert (
config.reuse_existing_virtualenvs
Expand Down Expand Up @@ -831,7 +830,7 @@ def test_main_noxfile_options_with_ci_override(
"nox.tasks.honor_list_request", return_value=0
) as honor_list_request:
with mock.patch("sys.exit"):
nox.__main__.main()
nox.main()
config = honor_list_request.call_args[1]["global_config"]
assert config.error_on_missing_interpreters == expected_final_value

Expand All @@ -849,7 +848,7 @@ def test_main_reuse_venv_cli_flags(monkeypatch, generate_noxfile_options, reuse_
monkeypatch.setattr(sys, "argv", ["nox", "--reuse-venv", reuse_venv])
with mock.patch("nox.workflow.execute", return_value=0) as execute:
with mock.patch.object(sys, "exit"):
nox.__main__.main()
nox.main()
config = execute.call_args[1]["global_config"]
assert (
not config.reuse_existing_virtualenvs
Expand Down Expand Up @@ -916,6 +915,6 @@ def test_main_noxfile_options_reuse_venv_compat_check(
"nox.tasks.honor_list_request", return_value=0
) as honor_list_request:
with mock.patch("sys.exit"):
nox.__main__.main()
nox.main()
config = honor_list_request.call_args[1]["global_config"]
assert config.reuse_venv == expected

0 comments on commit 7a94886

Please sign in to comment.