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

feat: support default=False #810

Merged
merged 1 commit into from
Apr 8, 2024
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
6 changes: 5 additions & 1 deletion docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ with ``@nox.session``. For example:

You can also configure sessions to run against multiple Python versions as described in :ref:`virtualenv config` and parametrize sessions as described in :ref:`parametrized sessions <parametrized>`.

By default, all sessions will be run if no sessions are specified. You can
remove sessions from this default list by passing ``default=False`` in the
``@nox.session(...)`` decorator. You can also specify a list of sessions to run by
default using the ``nox.options.sessions = [...]`` configuration option.

Session description
-------------------
Expand Down Expand Up @@ -421,7 +425,7 @@ Nox has various :doc:`command line arguments <usage>` that can be used to modify
def tests(session):
...

Or, if you wanted to provide a set of sessions that are run by default:
Or, if you wanted to provide a set of sessions that are run by default (this overrides the ``default=`` argument to sessions):

.. code-block:: python

Expand Down
5 changes: 5 additions & 0 deletions nox/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ def __init__(
venv_params: Any = None,
should_warn: Mapping[str, Any] | None = None,
tags: Sequence[str] | None = None,
*,
default: bool = True,
) -> None:
self.func = func
self.python = python
Expand All @@ -78,6 +80,7 @@ def __init__(
self.venv_params = venv_params
self.should_warn = dict(should_warn or {})
self.tags = list(tags or [])
self.default = default

def __call__(self, *args: Any, **kwargs: Any) -> Any:
return self.func(*args, **kwargs)
Expand All @@ -94,6 +97,7 @@ def copy(self, name: str | None = None) -> Func:
self.venv_params,
self.should_warn,
self.tags,
default=self.default,
)


Expand Down Expand Up @@ -125,6 +129,7 @@ def __init__(self, func: Func, param_spec: Param) -> None:
func.venv_params,
func.should_warn,
func.tags,
default=func.default,
)
self.call_spec = call_spec
self.session_signature = session_signature
Expand Down
5 changes: 5 additions & 0 deletions nox/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ def filter_by_name(self, specified_sessions: Iterable[str]) -> None:
if missing_sessions:
raise KeyError(f"Sessions not found: {', '.join(missing_sessions)}")

def filter_by_default(self) -> None:
"""Filter sessions in the queue based on the default flag."""

self._queue = [x for x in self._queue if x.func.default]

def filter_by_python_interpreter(self, specified_pythons: Sequence[str]) -> None:
"""Filter sessions in the queue based on the user-specified
python interpreter versions.
Expand Down
14 changes: 13 additions & 1 deletion nox/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def session_decorator(
venv_backend: Any | None = ...,
venv_params: Any | None = ...,
tags: Sequence[str] | None = ...,
*,
default: bool = ...,
) -> Callable[[F], F]:
...

Expand All @@ -56,6 +58,8 @@ def session_decorator(
venv_backend: Any | None = None,
venv_params: Any | None = None,
tags: Sequence[str] | None = None,
*,
default: bool = True,
) -> F | Callable[[F], F]:
"""Designate the decorated function as a session."""
# If `func` is provided, then this is the decorator call with the function
Expand All @@ -75,6 +79,7 @@ def session_decorator(
venv_backend=venv_backend,
venv_params=venv_params,
tags=tags,
default=default,
)

if py is not None and python is not None:
Expand All @@ -88,7 +93,14 @@ def session_decorator(

final_name = name or func.__name__
fn = Func(
func, python, reuse_venv, final_name, venv_backend, venv_params, tags=tags
func,
python,
reuse_venv,
final_name,
venv_backend,
venv_params,
tags=tags,
default=default,
)
_REGISTRY[final_name] = fn
return fn
Expand Down
4 changes: 3 additions & 1 deletion nox/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ def filter_manifest(manifest: Manifest, global_config: Namespace) -> Manifest |
# This can raise KeyError if a specified session does not exist;
# log this if it happens. The sessions does not come from the Noxfile
# if keywords is not empty.
if global_config.sessions is not None:
if global_config.sessions is None:
manifest.filter_by_default()
else:
try:
manifest.filter_by_name(global_config.sessions)
except KeyError as exc:
Expand Down
36 changes: 36 additions & 0 deletions tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def session_func():
session_func.venv_backend = None
session_func.should_warn = {}
session_func.tags = []
session_func.default = True


def session_func_with_python():
Expand All @@ -48,6 +49,7 @@ def session_func_with_python():

session_func_with_python.python = "3.8"
session_func_with_python.venv_backend = None
session_func_with_python.default = True


def session_func_venv_pythons_warning():
Expand Down Expand Up @@ -346,6 +348,40 @@ def bar():
assert len(manifest) == 2


@pytest.mark.parametrize("selection", [None, ["qux"], ["quuz"], ["qux", "quuz"]])
def test_default_false(selection):
@nox.session()
def qux():
pass

@nox.session()
def quux():
pass

@nox.session(default=False)
def quuz():
pass

@nox.session(default=False)
def corge():
pass

config = _options.options.namespace(sessions=selection, pythons=(), posargs=[])
manifest = Manifest(
{
"qux": qux,
"quux": quux,
"quuz": quuz,
"corge": corge,
},
config,
)
return_value = tasks.filter_manifest(manifest, config)
assert return_value is manifest
expected = 2 if selection is None else len(selection)
assert len(manifest) == expected


def test_honor_list_request_noop():
config = _options.options.namespace(list_sessions=False)
manifest = {"thing": mock.sentinel.THING}
Expand Down
Loading