Skip to content

Commit

Permalink
set local session posargs via notify (#397)
Browse files Browse the repository at this point in the history
* add local session posargs via notify

* add docs for notify(posargs=...)

Also SessionRunner.notify did not need to be a property.

* fix tests after notify(posargs=...) addition

* add test for notified posargs

* Add posargs to docstring for Manifest.notify

* Fix typo in docstring
  • Loading branch information
rmorshea authored Mar 12, 2021
1 parent de3d9c5 commit 3240441
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
23 changes: 21 additions & 2 deletions nox/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@
import collections.abc
import itertools
from collections import OrderedDict
from typing import Any, Iterable, Iterator, List, Mapping, Sequence, Set, Tuple, Union
from typing import (
Any,
Iterable,
Iterator,
List,
Mapping,
Optional,
Sequence,
Set,
Tuple,
Union,
)

from nox._decorators import Call, Func
from nox.sessions import Session, SessionRunner
Expand Down Expand Up @@ -257,7 +268,9 @@ def make_session(
def next(self) -> SessionRunner:
return self.__next__()

def notify(self, session: Union[str, SessionRunner]) -> bool:
def notify(
self, session: Union[str, SessionRunner], posargs: Optional[List[str]] = None
) -> bool:
"""Enqueue the specified session in the queue.
If the session is already in the queue, or has been run already,
Expand All @@ -266,6 +279,10 @@ def notify(self, session: Union[str, SessionRunner]) -> bool:
Args:
session (Union[str, ~nox.session.Session]): The session to be
enqueued.
posargs (Optional[List[str]]): If given, sets the positional
arguments *only* for the queued session. Otherwise, the
standard globally available positional arguments will be
used instead.
Returns:
bool: Whether the session was added to the queue.
Expand All @@ -282,6 +299,8 @@ def notify(self, session: Union[str, SessionRunner]) -> bool:
# the end of the queue.
for s in self._all_sessions:
if s == session or s.name == session or session in s.signatures:
if posargs is not None:
s.posargs = posargs
self._queue.append(s)
return True

Expand Down
22 changes: 16 additions & 6 deletions nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,8 @@ def env(self) -> dict:

@property
def posargs(self) -> List[str]:
"""This is set to any extra arguments
passed to ``nox`` on the commandline."""
return self._runner.global_config.posargs
"""Any extra arguments from the ``nox`` commandline or :class:`Session.notify`."""
return self._runner.posargs

@property
def virtualenv(self) -> ProcessEnv:
Expand Down Expand Up @@ -432,7 +431,11 @@ def install(self, *args: str, **kwargs: Any) -> None:

self._run("python", "-m", "pip", "install", *args, external="error", **kwargs)

def notify(self, target: "Union[str, SessionRunner]") -> None:
def notify(
self,
target: "Union[str, SessionRunner]",
posargs: Optional[Iterable[str]] = None,
) -> None:
"""Place the given session at the end of the queue.
This method is idempotent; multiple notifications to the same session
Expand All @@ -442,8 +445,14 @@ def notify(self, target: "Union[str, SessionRunner]") -> None:
target (Union[str, Callable]): The session to be notified. This
may be specified as the appropriate string (same as used for
``nox -s``) or using the function object.
posargs (Optional[Iterable[str]]): If given, sets the positional
arguments *only* for the queued session. Otherwise, the
standard globally available positional arguments will be
used instead.
"""
self._runner.manifest.notify(target)
if posargs is not None:
posargs = list(posargs)
self._runner.manifest.notify(target, posargs)

def log(self, *args: Any, **kwargs: Any) -> None:
"""Outputs a log during the session."""
Expand Down Expand Up @@ -472,7 +481,8 @@ def __init__(
self.func = func
self.global_config = global_config
self.manifest = manifest
self.venv = None # type: Optional[ProcessEnv]
self.venv: Optional[ProcessEnv] = None
self.posargs: List[str] = global_config.posargs

@property
def description(self) -> Optional[str]:
Expand Down
22 changes: 18 additions & 4 deletions tests/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ def create_mock_sessions():


def create_mock_config():
cfg = mock.sentinel.CONFIG
cfg = mock.sentinel.MOCKED_CONFIG
cfg.force_venv_backend = None
cfg.default_venv_backend = None
cfg.extra_pythons = None
cfg.posargs = []
return cfg


Expand Down Expand Up @@ -223,9 +224,7 @@ def session_func():
],
)
def test_extra_pythons(python, extra_pythons, expected):
cfg = mock.sentinel.CONFIG
cfg.force_venv_backend = None
cfg.default_venv_backend = None
cfg = create_mock_config()
cfg.extra_pythons = extra_pythons

manifest = Manifest({}, cfg)
Expand Down Expand Up @@ -345,6 +344,21 @@ def my_session(session):
assert len(manifest) == 1


def test_notify_with_posargs():
cfg = create_mock_config()
manifest = Manifest({}, cfg)

session = manifest.make_session("my_session", Func(lambda session: None))[0]
manifest.add_session(session)

# delete my_session from the queue
manifest.filter_by_name(())

assert session.posargs is cfg.posargs
assert manifest.notify("my_session", posargs=["--an-arg"])
assert session.posargs == ["--an-arg"]


def test_notify_error():
manifest = Manifest({}, create_mock_config())
with pytest.raises(ValueError):
Expand Down
6 changes: 5 additions & 1 deletion tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,11 @@ def test_notify(self):

session.notify("other")

runner.manifest.notify.assert_called_once_with("other")
runner.manifest.notify.assert_called_once_with("other", None)

session.notify("other", posargs=["--an-arg"])

runner.manifest.notify.assert_called_with("other", ["--an-arg"])

def test_log(self, caplog):
caplog.set_level(logging.INFO)
Expand Down

0 comments on commit 3240441

Please sign in to comment.