Skip to content

Commit 62976a9

Browse files
authored
Do not fail when commands do not parse with shlex (#2141)
Instead fallback to literal value. Signed-off-by: Bernát Gábor <[email protected]>
1 parent 5b9122b commit 62976a9

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

docs/changelog/1944.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
If the command expression fails to parse with shlex fallback to literal pass through of the remaining elements
2+
- by :user:`gaborbernat`.

src/tox/config/loader/str_convert.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,17 @@ def to_command(value: str) -> Command:
4949
is_win = sys.platform == "win32"
5050
splitter = shlex.shlex(value, posix=not is_win)
5151
splitter.whitespace_split = True
52-
if is_win: # pragma: win32 cover
53-
args: List[str] = []
52+
args: List[str] = []
53+
pos = 0
54+
try:
5455
for arg in splitter:
55-
# on Windows quoted arguments will remain quoted, strip it
56-
if len(arg) > 1 and arg[0] == arg[-1] and arg.startswith(("'", '"')):
56+
if is_win and len(arg) > 1 and arg[0] == arg[-1] and arg.startswith(("'", '"')): # pragma: win32 cover
57+
# on Windows quoted arguments will remain quoted, strip it
5758
arg = arg[1:-1]
5859
args.append(arg)
59-
else:
60-
args = list(splitter)
60+
pos = splitter.instream.tell()
61+
except ValueError:
62+
args.append(value[pos:])
6163
return Command(args)
6264

6365
@staticmethod

tests/config/loader/test_str_convert.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,15 @@ def test_str_convert_ok(raw: str, value: Any, of_type: Type[Any]) -> None:
6565
def test_str_convert_nok(raw: str, of_type: Type[Any], msg: str, exc_type: Type[Exception]) -> None:
6666
with pytest.raises(exc_type, match=msg):
6767
result = StrConvert().to(raw, of_type, {}) # noqa
68+
69+
70+
@pytest.mark.parametrize(
71+
("value", "expected"),
72+
[
73+
("python ' ok", ["python", "' ok"]),
74+
('python " ok', ["python", '" ok']),
75+
],
76+
)
77+
def test_invalid_shell_expression(value: str, expected: List[str]) -> None:
78+
result = StrConvert().to_command(value).args
79+
assert result == expected

whitelist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ IGN
103103
impl
104104
INET
105105
insort
106+
instream
106107
intersphinx
107108
isalpha
108109
isatty

0 commit comments

Comments
 (0)