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

nox.options.pythons ignored when nox.options.sessions is present #356

Closed
cjolowicz opened this issue Nov 13, 2020 · 0 comments · Fixed by #357
Closed

nox.options.pythons ignored when nox.options.sessions is present #356

cjolowicz opened this issue Nov 13, 2020 · 0 comments · Fixed by #357

Comments

@cjolowicz
Copy link
Collaborator

Describe the bug

When both nox.options.sessions and nox.options.pythons are specified in noxfile.py, the latter setting is ignored.

How to reproduce

import nox

nox.options.sessions = ("tests",)
nox.options.pythons = ("3.9",)

@nox.session(python=("3.9", "3.10"))
def tests(session):
    pass

@nox.session(python=("3.9", "3.10"))
def launch_missiles(session):
    pass

Run nox without options.

Actual behavior

  • The tests session is run on Python 3.9 and 3.10.
  • The launch_missiles session is not run at all.
nox > Running session tests-3.9
nox > Creating virtual environment (virtualenv) using python3.9 in .nox/tests-3-9
nox > Session tests-3.9 was successful.
nox > Running session tests-3.10
nox > Creating virtual environment (virtualenv) using python3 in .nox/tests-3-10
nox > Session tests-3.10 was successful.
nox > Ran multiple sessions:
nox > * tests-3.9: success
nox > * tests-3.10: success

Expected behavior

  • The tests session is run on Python 3.9.
  • The tests session is not run on Python 3.10.
  • The launch_missiles session is not run at all.
nox > Running session tests-3.9
nox > Creating virtual environment (virtualenv) using python3.9 in .nox/tests-3-9
nox > Session tests-3.9 was successful.

Discussion

Before going into details, I'd like to thank you for creating and maintaining a wonderful tool! 💚

The function OptionSet.merge_namespaces merges options set in noxfile.py into the command-line options. Where applicable, this is done with the help of custom merge functions. The options --sessions, --keywords, and --pythons are handled by a custom merge function _session_filters_merge_func, which ensures that noxfile.py is ignored for all of these options if any of them are set on the command-line.

For example, if noxfile.py contains nox.options.keywords = "not launch_missiles", we want the user to still be able to trigger the session explicitly using --session=launch_missiles; the custom merge function achieves that. Without the custom merge function, the user would be forced to use --keywords instead of --sessions.

Unfortunately, OptionSet.merge_namespaces merges the command-line options in place. Merge functions such as _session_filters_merge_func inspect command_args to see if other options have been specified on the command-line. When the options are merged in place, this check produces false positives.

For example, nox.options.sessions is copied into command_args as a part of the merge; so it will appear to have been specified on the command-line when merging nox.options.pythons, causing the latter to be ignored.

Note that this is unrelated to the new --pythons option. For example, consider the following two nox files:

import nox

nox.options.sessions = ("tests",)
nox.options.keywords = "tests or launch_missiles"

@nox.session
def tests(session):
    pass

@nox.session
def launch_missiles(session):
    pass
import nox

nox.options.sessions = ("tests", "launch_missiles")
nox.options.keywords = "tests"

@nox.session
def tests(session):
    pass

@nox.session
def launch_missiles(session):
    pass

In the first version, sessions excludes launch_missiles, while keywords contains all sessions. When Nox is run without options, it will ignore keywords because sessions was already merged into the command-line options, and appears to have been specified on the command-line. As a result, only the tests session is run.

In the second version, sessions lists all sessions, while keywords excludes launch_missiles. When Nox is run without options, it will again ignore keywords because sessions was already merged into the command-line options. As a result, both tests and launch_missiles are run.

The order of precedence is determined by the declaration of options in nox._options: sessions -- pythons -- keywords.

Proposed solution

As a fix, I would propose that OptionSet.merge_namespaces copy command_args initially, and use that copy as the input for the merge functions, instead of the instance that is being mutated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant