Skip to content

Commit

Permalink
Don't use shell by default. Fixes pycontribs#100, pycontribs#103
Browse files Browse the repository at this point in the history
  • Loading branch information
jonashaag committed Dec 22, 2023
1 parent 1681e02 commit 10d5df6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ repos:
- pytest>=6.1.2
- enrich>=1.2.5
- repo: https://github.com/PyCQA/pylint
rev: v3.0.0a6
rev: v3.0.3
hooks:
- id: pylint
additional_dependencies:
Expand Down
7 changes: 5 additions & 2 deletions src/subprocess_tee/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
from asyncio import StreamReader
from importlib.metadata import PackageNotFoundError, version # type: ignore
from shlex import join
from shlex import join, quote
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union

try:
Expand Down Expand Up @@ -127,7 +127,10 @@ def run(args: Union[str, List[str]], **kwargs: Any) -> CompletedProcess:
quiet: False - Avoid printing output
"""
if isinstance(args, str):
cmd = args
if kwargs.get("shell"):
cmd = args
else:
cmd = quote(args)
else:
# run was called with a list instead of a single item but asyncio
# create_subprocess_shell requires command as a single string, so
Expand Down
4 changes: 2 additions & 2 deletions test/test_rich.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_rich_console_ex() -> None:
# an exception. Some libraries may still sometimes send bytes to the
# streams, notable example being click.
# sys.stdout.write(b"epsilon\n") # type: ignore
proc = run("echo 123")
proc = run("echo 123", shell=True)
assert proc.stdout == "123\n"
text = console.export_text()
assert text == "alpha\nbeta\ngamma\ndelta\n123\n"
Expand All @@ -30,7 +30,7 @@ def test_rich_console_ex_ansi() -> None:
print()
console = Console(force_terminal=True, record=True, redirect=True)
console.print("[green]this from Console.print()[/green]", style="red")
proc = run(r'echo -e "\033[31mred\033[0m"')
proc = run(r'echo -e "\033[31mred\033[0m"', shell=True)
assert proc.returncode == 0
assert "red" in proc.stdout

Expand Down
18 changes: 12 additions & 6 deletions test/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

def test_run_string() -> None:
"""Valida run() called with a single string command."""
cmd = "echo 111 && >&2 echo 222"
cmd = "echo 111 && echo 222 >&2"
old_result = subprocess.run(
cmd,
shell=True,
Expand All @@ -20,7 +20,7 @@ def test_run_string() -> None:
stderr=subprocess.PIPE,
check=False,
)
result = run(cmd)
result = run(cmd, shell=True)
assert result.returncode == old_result.returncode
assert result.stdout == old_result.stdout
assert result.stderr == old_result.stderr
Expand Down Expand Up @@ -74,32 +74,38 @@ def test_run_echo(capsys: CaptureFixture[str]) -> None:
def test_run_with_env(env: Dict[str, str]) -> None:
"""Validate that passing custom env to run() works."""
env["FOO"] = "BAR"
result = run("echo $FOO", env=env, echo=True)
result = run("echo $FOO", env=env, echo=True, shell=True)
assert result.stdout == "BAR\n"


def test_run_shell() -> None:
"""Validate run call with multiple shell commands works."""
cmd = "echo a && echo b && false || exit 4"
# "python --version"
result = run(cmd, echo=True)
result = run(cmd, echo=True, shell=True)
assert result.returncode == 4
assert result.stdout == "a\nb\n"


def test_run_shell_false() -> None:
"""Shell commands should not work if 'shell=False'."""
with pytest.raises(subprocess.CalledProcessError):
run("echo 42", check=True)


def test_run_shell_undefined() -> None:
"""Validate run call with multiple shell commands works."""
cmd = "echo a && echo b && false || exit 4"
# "python --version"
result = run(cmd, echo=True, env={})
result = run(cmd, echo=True, env={}, shell=True)
assert result.returncode == 4
assert result.stdout == "a\nb\n"


def test_run_cwd() -> None:
"""Validate that run accepts cwd and respects it."""
cmd = "pwd"
result = run(cmd, echo=True, cwd="/")
result = run(cmd, echo=True, cwd="/", shell=True)
assert result.returncode == 0
assert result.stdout == "/\n"

Expand Down

0 comments on commit 10d5df6

Please sign in to comment.