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 users specifying an undeclared parametrization of python #361

Merged
merged 27 commits into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8759209
feat: support users specifying an undeclared parametrization of python
crwilcox Nov 20, 2020
b016d61
fix: short circuit to throwing a key error earlier
crwilcox Nov 20, 2020
2b4e553
refactor to avoid 'uncovered' region
crwilcox Nov 20, 2020
3659f3e
simplify code, manage coverage
crwilcox Nov 21, 2020
73ae618
fix type issue
crwilcox Nov 21, 2020
b672b70
feat: add extra-python argument to control additional pythons
crwilcox Nov 24, 2020
08569a7
test: make sure mock has extra_pythons field
crwilcox Nov 24, 2020
6cf1b99
dedupe extra pythons that match existing pythons.
crwilcox Nov 24, 2020
974e222
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Nov 24, 2020
169ede8
Update nox/manifest.py
crwilcox Nov 24, 2020
dc5dd73
revert: revert to before previous commit due to a bug
crwilcox Nov 25, 2020
3c43215
Add a method to ensure a unique and ordered session list.
crwilcox Nov 26, 2020
46f32f2
Treat extra_python as an override when no python is specified for a s…
crwilcox Nov 26, 2020
9d86ff0
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Nov 26, 2020
57d6a5c
Use parametrized tests
crwilcox Nov 30, 2020
e4ab2b5
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Nov 30, 2020
62e5948
Simplify handling of extra pythons
crwilcox Nov 30, 2020
7bb69a2
blacken
crwilcox Nov 30, 2020
e496dc1
docs: add a bit in usage.rst about using extra-pythons
crwilcox Dec 1, 2020
b6337f5
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Dec 1, 2020
afe79e4
Update docs/usage.rst
crwilcox Dec 2, 2020
7812152
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Dec 19, 2020
0d3bc44
docs: Expand on using python with extra-pythons
crwilcox Dec 23, 2020
bb37f02
Update docs/usage.rst
crwilcox Dec 28, 2020
9363b62
Update docs/usage.rst
crwilcox Dec 28, 2020
164e4ad
Merge branch 'master' into allow-non-specified-python-versions
crwilcox Dec 29, 2020
94b41b3
test: add a test to show unique list behavior is correct
crwilcox Dec 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,28 @@ By default, Nox deletes and recreates virtualenvs every time it is run. This is

If the Noxfile sets ``nox.options.reuse_existing_virtualenvs``, you can override the Noxfile setting from the command line by using ``--no-reuse-existing-virtualenvs``.

.. _opt-running-extra-pythons:

Running additional Python versions
----------------------------------
In addition to Nox supporting executing single sessions, it also supports runnings python versions that aren't specified using ``--extra-pythons``.

.. code-block:: console

nox --extra-pythons 3.8 3.9

This will, in addition to specified python versions in the Noxfile, also create sessions for the specified versions.

This option can be combined with ``--python`` to replace, instead of appending, the Python interpreter for a given session::

nox --python 3.10 --extra-python 3.10 -s lint

Also, you can specify ``python`` in place of a specific version. This will run the session
using the ``python`` specified for the current ``PATH``::

nox --python python --extra-python python -s lint


.. _opt-stop-on-first-error:

Stopping if any session fails
Expand Down
8 changes: 8 additions & 0 deletions nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,14 @@ def _session_completer(
group=options.groups["secondary"],
help="Directory where nox will store virtualenvs, this is ``.nox`` by default.",
),
_option_set.Option(
"extra_pythons",
"--extra-pythons",
"--extra-python",
group=options.groups["secondary"],
nargs="*",
help="Additionally, run sessions using the given python interpreter versions.",
),
*_option_set.make_flag_pair(
"stop_on_first_error",
("-x", "--stop-on-first-error"),
Expand Down
21 changes: 21 additions & 0 deletions nox/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import argparse
import collections.abc
import itertools
from collections import OrderedDict
from typing import Any, Iterable, Iterator, List, Mapping, Sequence, Set, Tuple, Union

from nox._decorators import Call, Func
Expand All @@ -23,6 +24,11 @@
WARN_PYTHONS_IGNORED = "python_ignored"


def _unique_list(*args: str) -> List[str]:
"""Return a list without duplicates, while preserving order."""
return list(OrderedDict.fromkeys(args))

crwilcox marked this conversation as resolved.
Show resolved Hide resolved

class Manifest:
"""Session manifest.

Expand Down Expand Up @@ -184,6 +190,21 @@ def make_session(
func.should_warn[WARN_PYTHONS_IGNORED] = func.python
func.python = False

if self._config.extra_pythons:
# If extra python is provided, expand the func.python list to
# include additional python interpreters
extra_pythons = self._config.extra_pythons # type: List[str]
if isinstance(func.python, (list, tuple, set)):
func.python = _unique_list(*func.python, *extra_pythons)
elif not multi and func.python:
# If this is multi, but there is only a single interpreter, it
# is the reentrant case. The extra_python interpreter shouldn't
# be added in that case. If func.python is False, the session
# has no backend; if None, it uses the same interpreter as Nox.
# Otherwise, add the extra specified python.
assert isinstance(func.python, str)
func.python = _unique_list(func.python, *extra_pythons)

# If the func has the python attribute set to a list, we'll need
# to expand them.
if isinstance(func.python, (list, tuple, set)):
Expand Down
37 changes: 37 additions & 0 deletions tests/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def create_mock_config():
cfg = mock.sentinel.CONFIG
cfg.force_venv_backend = None
cfg.default_venv_backend = None
cfg.extra_pythons = None
return cfg


Expand Down Expand Up @@ -203,6 +204,42 @@ def session_func():
assert len(manifest) == 2


@pytest.mark.parametrize(
"python,extra_pythons,expected",
[
(None, [], [None]),
(None, ["3.8"], [None]),
(None, ["3.8", "3.9"], [None]),
(False, [], [False]),
(False, ["3.8"], [False]),
(False, ["3.8", "3.9"], [False]),
("3.5", [], ["3.5"]),
("3.5", ["3.8"], ["3.5", "3.8"]),
("3.5", ["3.8", "3.9"], ["3.5", "3.8", "3.9"]),
(["3.5", "3.9"], [], ["3.5", "3.9"]),
(["3.5", "3.9"], ["3.8"], ["3.5", "3.9", "3.8"]),
(["3.5", "3.9"], ["3.8", "3.4"], ["3.5", "3.9", "3.8", "3.4"]),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be good to have a case where an interpreter in extra_pythons is already in python (to test the _unique_list function).

(["3.5", "3.9"], ["3.5", "3.9"], ["3.5", "3.9"]),
],
)
def test_extra_pythons(python, extra_pythons, expected):
cfg = mock.sentinel.CONFIG
cfg.force_venv_backend = None
cfg.default_venv_backend = None
cfg.extra_pythons = extra_pythons

manifest = Manifest({}, cfg)

def session_func():
pass

func = Func(session_func, python=python)
for session in manifest.make_session("my_session", func):
manifest.add_session(session)

assert expected == [session.func.python for session in manifest._all_sessions]


def test_add_session_parametrized():
manifest = Manifest({}, create_mock_config())

Expand Down