summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernát Gábor <gaborjbernat@gmail.com>2023-01-02 11:58:01 -0800
committerGitHub <noreply@github.com>2023-01-02 11:58:01 -0800
commit997128ced47936adabb2f267d2606f8eac253ad3 (patch)
treeccf2e729d76c452d715a501b1e9d0d7c0f3af476
parentd202833481f891c19ad2b096ddc63eaee10383eb (diff)
downloadtox-git-997128ced47936adabb2f267d2606f8eac253ad3.tar.gz
Better message when command parsing on empty input (#2807)
-rw-r--r--docs/changelog/2695.bugfix.rst1
-rw-r--r--src/tox/config/loader/str_convert.py2
-rw-r--r--src/tox/tox_env/python/pip/pip_install.py5
-rw-r--r--tests/config/loader/test_str_convert.py1
-rw-r--r--tests/session/cmd/test_show_config.py8
-rw-r--r--tests/tox_env/python/pip/test_pip_install.py11
6 files changed, 27 insertions, 1 deletions
diff --git a/docs/changelog/2695.bugfix.rst b/docs/changelog/2695.bugfix.rst
new file mode 100644
index 00000000..30668e9c
--- /dev/null
+++ b/docs/changelog/2695.bugfix.rst
@@ -0,0 +1 @@
+Fail more gracefully when pip :ref:`install_command` is empty - by :user:`jayaddison`.
diff --git a/src/tox/config/loader/str_convert.py b/src/tox/config/loader/str_convert.py
index e31c034f..f07545f5 100644
--- a/src/tox/config/loader/str_convert.py
+++ b/src/tox/config/loader/str_convert.py
@@ -63,6 +63,8 @@ class StrConvert(Convert[str]):
pos = splitter.instream.tell()
except ValueError:
args.append(value[pos:])
+ if len(args) == 0:
+ raise ValueError(f"attempting to parse {value!r} into a command failed")
if args[0] != "-" and args[0].startswith("-"):
args[0] = args[0][1:]
args = ["-"] + args
diff --git a/src/tox/tox_env/python/pip/pip_install.py b/src/tox/tox_env/python/pip/pip_install.py
index a148ce32..2136e862 100644
--- a/src/tox/tox_env/python/pip/pip_install.py
+++ b/src/tox/tox_env/python/pip/pip_install.py
@@ -160,7 +160,10 @@ class Pip(Installer[Python]):
outcome.assert_success()
def build_install_cmd(self, args: Sequence[str]) -> list[str]:
- cmd: Command = self._env.conf["install_command"]
+ try:
+ cmd: Command = self._env.conf["install_command"]
+ except ValueError as exc:
+ raise Fail(f"unable to determine pip install command: {str(exc)}") from exc
install_command = cmd.args
try:
opts_at = install_command.index("{packages}")
diff --git a/tests/config/loader/test_str_convert.py b/tests/config/loader/test_str_convert.py
index 49948c4f..4fe0aaff 100644
--- a/tests/config/loader/test_str_convert.py
+++ b/tests/config/loader/test_str_convert.py
@@ -62,6 +62,7 @@ def test_str_convert_ok(raw: str, value: Any, of_type: type[Any]) -> None:
("a", TypeVar, TypeError, r"a cannot cast to .*typing.TypeVar.*"),
("3", Literal["1", "2"], ValueError, r"3 must be one of \('1', '2'\)"),
("3", Union[str, int], TypeError, r"3 cannot cast to typing.Union\[str, int\]"),
+ ("", Command, ValueError, r"attempting to parse '' into a command failed"),
],
)
def test_str_convert_nok(raw: str, of_type: type[Any], msg: str, exc_type: type[Exception]) -> None:
diff --git a/tests/session/cmd/test_show_config.py b/tests/session/cmd/test_show_config.py
index 33c4fc48..646dc2bf 100644
--- a/tests/session/cmd/test_show_config.py
+++ b/tests/session/cmd/test_show_config.py
@@ -99,6 +99,14 @@ def test_show_config_exception(tox_project: ToxProjectCreator) -> None:
assert txt in outcome.out
+def test_show_config_empty_install_command_exception(tox_project: ToxProjectCreator) -> None:
+ project = tox_project({"tox.ini": "[testenv:a]\ninstall_command="})
+ outcome = project.run("c", "-e", "a", "-k", "install_command")
+ outcome.assert_success()
+ txt = "\ninstall_command = # Exception: " "ValueError(\"attempting to parse '' into a command failed\")"
+ assert txt in outcome.out
+
+
@pytest.mark.parametrize("stdout_is_atty", [True, False])
def test_pass_env_config_default(tox_project: ToxProjectCreator, stdout_is_atty: bool, mocker: MockerFixture) -> None:
mocker.patch("sys.stdout.isatty", return_value=stdout_is_atty)
diff --git a/tests/tox_env/python/pip/test_pip_install.py b/tests/tox_env/python/pip/test_pip_install.py
index bc470573..8fb70a5f 100644
--- a/tests/tox_env/python/pip/test_pip_install.py
+++ b/tests/tox_env/python/pip/test_pip_install.py
@@ -6,8 +6,10 @@ from typing import Any
from unittest.mock import Mock
import pytest
+from packaging.requirements import Requirement
from tox.pytest import CaptureFixture, ToxProjectCreator
+from tox.tox_env.errors import Fail
@pytest.mark.parametrize("arg", [object, [object]])
@@ -35,6 +37,15 @@ def test_pip_install_empty_list(tox_project: ToxProjectCreator) -> None:
assert execute_calls.call_count == 0
+def test_pip_install_empty_command_error(tox_project: ToxProjectCreator) -> None:
+ proj = tox_project({"tox.ini": "[testenv]\ninstall_command="})
+ result = proj.run("l")
+ pip = result.state.envs["py"].installer
+
+ with pytest.raises(Fail, match="unable to determine pip install command"):
+ pip.install([Requirement("name")], "section", "type")
+
+
def test_pip_install_flags_only_error(tox_project: ToxProjectCreator) -> None:
proj = tox_project({"tox.ini": "[testenv:py]\ndeps=-i a"})
result = proj.run("r")