-
-
Notifications
You must be signed in to change notification settings - Fork 151
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
set local session posargs via notify #397
Conversation
c0cf017
to
36a3471
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, I like the approach with the property setter :) Public API stays read-only, which is good. I left some minor suggestions inline, what do you think? Otherwise, I think this just needs tests and an update to the docstring for session.notify
.
f48be2b
to
91fc9cb
Compare
Also SessionRunner.notify did not need to be a property.
91fc9cb
to
c7f3954
Compare
c7f3954
to
06a01ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rmorshea this is pretty much good to go :) I just noticed a few more small things, could you take another look? Comments are inline.
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we inoculate global_config.posargs
against mutation here?
self.posargs: List[str] = global_config.posargs | |
self.posargs: List[str] = global_config.posargs[:] |
Now that every session conceptually has their own posargs
, I think it makes sense to prevent one session from accidentally mutating the default posargs
of other sessions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh dear, this breaks a whole lot of tests 😅
Essentially, there are three groups of tests that break:
- Tests that compare posargs using
is
instead of==
- Tests that construct a namespace manually without including posargs
- Tests that construct a namespace manually and set posargs to a mock sentinel
Here's a patch that would make this green again.
(Some of these could be turned into fixtures.)
diff --git a/tests/test__option_set.py b/tests/test__option_set.py
index 3ad8b59..d05bd7f 100644
--- a/tests/test__option_set.py
+++ b/tests/test__option_set.py
@@ -55,7 +55,7 @@ class TestOptionSet:
optionset.namespace(non_existant_option="meep")
def test_session_completer(self):
- parsed_args = _options.options.namespace(sessions=(), keywords=())
+ parsed_args = _options.options.namespace(sessions=(), keywords=(), posargs=[])
all_nox_sessions = _options._session_completer(
prefix=None, parsed_args=parsed_args
)
@@ -65,7 +65,9 @@ class TestOptionSet:
assert len(set(some_expected_sessions) - set(all_nox_sessions)) == 0
def test_session_completer_invalid_sessions(self):
- parsed_args = _options.options.namespace(sessions=("baz",), keywords=())
+ parsed_args = _options.options.namespace(
+ sessions=("baz",), keywords=(), posargs=[]
+ )
all_nox_sessions = _options._session_completer(
prefix=None, parsed_args=parsed_args
)
diff --git a/tests/test_manifest.py b/tests/test_manifest.py
index 35eb775..b0c3ac9 100644
--- a/tests/test_manifest.py
+++ b/tests/test_manifest.py
@@ -354,7 +354,7 @@ def test_notify_with_posargs():
# delete my_session from the queue
manifest.filter_by_name(())
- assert session.posargs is cfg.posargs
+ assert session.posargs == cfg.posargs
assert manifest.notify("my_session", posargs=["--an-arg"])
assert session.posargs == ["--an-arg"]
diff --git a/tests/test_sessions.py b/tests/test_sessions.py
index 150c15e..518ab0c 100644
--- a/tests/test_sessions.py
+++ b/tests/test_sessions.py
@@ -66,9 +66,7 @@ class TestSession:
signatures=["test"],
func=func,
global_config=_options.options.namespace(
- posargs=mock.sentinel.posargs,
- error_on_external_run=False,
- install_only=False,
+ posargs=[], error_on_external_run=False, install_only=False
),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
@@ -100,7 +98,7 @@ class TestSession:
assert session.name is runner.friendly_name
assert session.env is runner.venv.env
- assert session.posargs is runner.global_config.posargs
+ assert session.posargs == runner.global_config.posargs
assert session.virtualenv is runner.venv
assert session.bin_paths is runner.venv.bin_paths
assert session.bin is runner.venv.bin_paths[0]
@@ -351,7 +349,7 @@ class TestSession:
name="test",
signatures=["test"],
func=mock.sentinel.func,
- global_config=_options.options.namespace(posargs=mock.sentinel.posargs),
+ global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.CondaEnv)
@@ -390,7 +388,7 @@ class TestSession:
name="test",
signatures=["test"],
func=mock.sentinel.func,
- global_config=_options.options.namespace(posargs=mock.sentinel.posargs),
+ global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.CondaEnv)
@@ -447,7 +445,7 @@ class TestSession:
name="test",
signatures=["test"],
func=mock.sentinel.func,
- global_config=_options.options.namespace(posargs=mock.sentinel.posargs),
+ global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
@@ -476,7 +474,7 @@ class TestSession:
name="test",
signatures=["test"],
func=mock.sentinel.func,
- global_config=_options.options.namespace(posargs=mock.sentinel.posargs),
+ global_config=_options.options.namespace(posargs=[]),
manifest=mock.create_autospec(nox.manifest.Manifest),
)
runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv)
@@ -564,7 +562,7 @@ class TestSessionRunner:
global_config=_options.options.namespace(
noxfile=os.path.join(os.getcwd(), "noxfile.py"),
envdir="envdir",
- posargs=mock.sentinel.posargs,
+ posargs=[],
reuse_existing_virtualenvs=False,
error_on_missing_interpreters=False,
),
@@ -580,7 +578,7 @@ class TestSessionRunner:
assert runner.func is not None
assert callable(runner.func)
assert isinstance(runner.description, str)
- assert runner.global_config.posargs == mock.sentinel.posargs
+ assert runner.global_config.posargs == []
assert isinstance(runner.manifest, nox.manifest.Manifest)
def test_str_and_friendly_name(self):
diff --git a/tests/test_tasks.py b/tests/test_tasks.py
index 65f3112..ca477ff 100644
--- a/tests/test_tasks.py
+++ b/tests/test_tasks.py
@@ -139,7 +139,7 @@ def test_discover_session_functions_decorator():
mock_module = argparse.Namespace(
__name__=foo.__module__, foo=foo, bar=bar, notasession=notasession
)
- config = _options.options.namespace(sessions=(), keywords=())
+ config = _options.options.namespace(sessions=(), keywords=(), posargs=())
# Get the manifest and establish that it looks like what we expect.
manifest = tasks.discover_manifest(mock_module, config)
@@ -149,7 +149,9 @@ def test_discover_session_functions_decorator():
def test_filter_manifest():
- config = _options.options.namespace(sessions=(), pythons=(), keywords=())
+ config = _options.options.namespace(
+ sessions=(), pythons=(), keywords=(), posargs=()
+ )
manifest = Manifest({"foo": session_func, "bar": session_func}, config)
return_value = tasks.filter_manifest(manifest, config)
assert return_value is manifest
@@ -157,14 +159,18 @@ def test_filter_manifest():
def test_filter_manifest_not_found():
- config = _options.options.namespace(sessions=("baz",), pythons=(), keywords=())
+ config = _options.options.namespace(
+ sessions=("baz",), pythons=(), keywords=(), posargs=()
+ )
manifest = Manifest({"foo": session_func, "bar": session_func}, config)
return_value = tasks.filter_manifest(manifest, config)
assert return_value == 3
def test_filter_manifest_pythons():
- config = _options.options.namespace(sessions=(), pythons=("3.8",), keywords=())
+ config = _options.options.namespace(
+ sessions=(), pythons=("3.8",), keywords=(), posargs=()
+ )
manifest = Manifest(
{"foo": session_func_with_python, "bar": session_func, "baz": session_func},
config,
@@ -175,7 +181,9 @@ def test_filter_manifest_pythons():
def test_filter_manifest_keywords():
- config = _options.options.namespace(sessions=(), pythons=(), keywords="foo or bar")
+ config = _options.options.namespace(
+ sessions=(), pythons=(), keywords="foo or bar", posargs=()
+ )
manifest = Manifest(
{"foo": session_func, "bar": session_func, "baz": session_func}, config
)
@@ -230,7 +238,7 @@ def test_verify_manifest_empty():
def test_verify_manifest_nonempty():
- config = _options.options.namespace(sessions=(), keywords=())
+ config = _options.options.namespace(sessions=(), keywords=(), posargs=())
manifest = Manifest({"session": session_func}, config)
return_value = tasks.verify_manifest_nonempty(manifest, global_config=config)
assert return_value == manifest
I think we can also choose to be pragmatic here, and keep this as it is. After all, the mutability of session.posargs
is undocumented and an implementation detail, and should not be used in Noxfiles. What do you think?
@theacodes What's your take on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're thinking about making breaking change we should also consider turning posargs
into a tuple. Having posargs
be a list just seems like you're offering people enough rope to hang themselves with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that a tuple would be preferable. (Changing the type might not even constitute a breaking change; the exact type is not documented and most Noxfiles probably just unpack into session.run
.) But I think we can merge this without addressing the issue here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll create an issue to capture this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See here: #400
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'd be happy for this to be merged without making session.posargs
immutable. (To be clear it's already mutable on the main branch, this PR does not change that.) We can deal with that in a separate PR if required.
@cjolowicz I think this is good to merge. |
ping: @cjolowicz - I think this is good to merge |
Looks great, thanks, y'all! |
Closes: #391
Once the basic API has been reviewed and accepted I'll add tests for this feature.