diff --git a/nox/sessions.py b/nox/sessions.py index 83ea1675..b1836a00 100644 --- a/nox/sessions.py +++ b/nox/sessions.py @@ -360,7 +360,11 @@ def _run( return nox.command.run(args, env=env, paths=self.bin_paths, **kwargs) def conda_install( - self, *args: str, auto_offline: bool = True, **kwargs: Any + self, + *args: str, + auto_offline: bool = True, + channel: Union[str, Sequence[str]] = "", + **kwargs: Any, ) -> None: """Install invokes `conda install`_ to install packages inside of the session's environment. @@ -369,7 +373,7 @@ def conda_install( session.conda_install('pandas') session.conda_install('numpy', 'scipy') - session.conda_install('--channel=conda-forge', 'dask==2.1.0') + session.conda_install('dask==2.1.0', channel='conda-forge') To install packages from a ``requirements.txt`` file:: @@ -387,6 +391,10 @@ def conda_install( # Install in editable mode. session.install('-e', '.', '--no-deps') + You can specify a conda channel using `channel=`; a falsy value will + not change the current channels. You can specify a list of channels if + needed. + Additional keyword args are the same as for :meth:`run`. .. _conda install: @@ -413,12 +421,18 @@ def conda_install( if "silent" not in kwargs: kwargs["silent"] = True - extraopts = () # type: Tuple[str, ...] + extraopts = [] # type: List[str] if auto_offline and venv.is_offline(): logger.warning( "Automatically setting the `--offline` flag as conda repo seems unreachable." ) - extraopts = ("--offline",) + extraopts.append("--offline") + + if channel: + if isinstance(channel, str): + extraopts.append(f"--channel={channel}") + else: + extraopts += [f"--channel={c}" for c in channel] self._run( venv.conda_cmd, diff --git a/tests/test_sessions.py b/tests/test_sessions.py index a7d16425..d5a895d2 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -385,7 +385,12 @@ def test_conda_install_not_a_condaenv(self): ) @pytest.mark.parametrize("offline", [False, True], ids="offline={}".format) @pytest.mark.parametrize("conda", ["conda", "mamba"], ids=str) - def test_conda_install(self, auto_offline, offline, conda): + @pytest.mark.parametrize( + "channel", + ["", "conda-forge", ["conda-forge", "bioconda"]], + ids=["default", "conda-forge", "bioconda"], + ) + def test_conda_install(self, auto_offline, offline, conda, channel): runner = nox.sessions.SessionRunner( name="test", signatures=["test"], @@ -405,8 +410,14 @@ class SessionNoSlots(nox.sessions.Session): session = SessionNoSlots(runner=runner) with mock.patch.object(session, "_run", autospec=True) as run: - args = ("--offline",) if auto_offline and offline else () - session.conda_install("requests", "urllib3", auto_offline=auto_offline) + args = ["--offline"] if auto_offline and offline else [] + if channel and isinstance(channel, str): + args.append(f"--channel={channel}") + else: + args += [f"--channel={c}" for c in channel] + session.conda_install( + "requests", "urllib3", auto_offline=auto_offline, channel=channel + ) run.assert_called_once_with( conda, "install",