Skip to content

Commit 9090b09

Browse files
committed
Quote arguments with whitespace when printing command
Currently, printing baked commands doesn't represent the way arguments are actually passed down to the program when values contain spaces. The solution is to take such values in single quotes. This is primarily to be able to copy printed commands and run them in a shell. BEFORE: ```python >>> from sh import ls >>> print(ls.bake('How I Met Your Mother')) /bin/ls How I Met Your Mother ``` AFTER: ```python >>> print(ls.bake('How I Met Your Mother')) /bin/ls 'How I Met Your Mother' ```
1 parent 3bf6891 commit 9090b09

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

sh.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,10 +1391,10 @@ def bake(self, *args, **kwargs):
13911391
return fn
13921392

13931393
def __str__(self):
1394-
baked_args = " ".join(self._partial_baked_args)
1395-
if baked_args:
1396-
baked_args = " " + baked_args
1397-
return self._path + baked_args
1394+
if not self._partial_baked_args:
1395+
return self._path
1396+
baked_args = " ".join(shlex_quote(arg) for arg in self._partial_baked_args)
1397+
return f"{self._path} {baked_args}"
13981398

13991399
def __eq__(self, other):
14001400
return str(self) == str(other)

tests/sh_test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,12 @@ def test_multiple_args_long_option(self):
855855
num_args = int(python(py.name, "--long-option", "one's two's three's"))
856856
self.assertEqual(num_args, 3)
857857

858+
num_args = int(python(py.name, long_option="one's two's three's"))
859+
self.assertEqual(num_args, 3)
860+
861+
cmd = str(python.bake(py.name, long_option="one two three"))
862+
self.assertTrue(cmd.endswith(" '--long-option=one two three'"), cmd)
863+
858864
def test_short_bool_option(self):
859865
py = create_tmp_test(
860866
"""
@@ -2686,6 +2692,26 @@ def test_baked_command_can_be_printed(self):
26862692
ll = ls.bake("-l")
26872693
self.assertTrue(str(ll).endswith("/ls -l"))
26882694

2695+
def test_baked_command_can_be_printed_with_whitespace_args(self):
2696+
from sh import ls
2697+
2698+
ls_himym = ls.bake("How I Met Your Mother")
2699+
self.assertTrue(str(ls_himym).endswith("/ls 'How I Met Your Mother'"))
2700+
ls_himym = ls.bake("How I 'Met' Your Mother")
2701+
self.assertTrue(
2702+
str(ls_himym).endswith("""/ls 'How I '"'"'Met'"'"' Your Mother'""")
2703+
)
2704+
ls_himym = ls.bake('How I "Met" Your Mother')
2705+
self.assertTrue(str(ls_himym).endswith("""/ls 'How I "Met" Your Mother'"""))
2706+
2707+
def test_baked_command_can_be_printed_with_whitespace_in_options(self):
2708+
from sh import ls
2709+
2710+
cmd = ls.bake(o="one two")
2711+
self.assertTrue(str(cmd).endswith("""/ls -o 'one two'"""), str(cmd))
2712+
cmd = ls.bake(opt="one two")
2713+
self.assertTrue(str(cmd).endswith("""/ls '--opt=one two'"""), str(cmd))
2714+
26892715
# https://github.com/amoffat/sh/issues/185
26902716
def test_done_callback(self):
26912717
import time

0 commit comments

Comments
 (0)