Skip to content

Commit cd09009

Browse files
committed
Fixed bug where it wasn't possible for restore_output to know if the command was piping
1 parent 373c404 commit cd09009

File tree

1 file changed

+19
-22
lines changed

1 file changed

+19
-22
lines changed

cmd2/cmd2.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,10 @@ class EmptyStatement(Exception):
303303
DisabledCommand = namedtuple('DisabledCommand', ['command_function', 'help_function'])
304304

305305
# Used to restore state after redirection ends
306-
RedirectionSavedState = namedtuple('RedirectionSavedState', ['self_stdout', 'sys_stdout', 'pipe_proc'])
306+
# redirecting and piping are used to know what needs to be restored
307+
RedirectionSavedState = utils.namedtuple_with_defaults('RedirectionSavedState',
308+
['redirecting', 'self_stdout', 'sys_stdout',
309+
'piping', 'pipe_proc'])
307310

308311

309312
class Cmd(cmd.Cmd):
@@ -1724,7 +1727,7 @@ def onecmd_plus_hooks(self, line: str) -> bool:
17241727

17251728
# See if we need to update self.redirecting
17261729
if not already_redirecting:
1727-
self.redirecting = all(val is not None for val in saved_state)
1730+
self.redirecting = saved_state.redirecting or saved_state.piping
17281731

17291732
try:
17301733
timestart = datetime.datetime.now()
@@ -1886,13 +1889,12 @@ def _redirect_output(self, statement: Statement) -> RedirectionSavedState:
18861889
"""Handles output redirection for >, >>, and |.
18871890
18881891
:param statement: a parsed statement from the user
1889-
:return: A RedirectionSavedState object. All elements will be None if no redirection was done.
1892+
:return: A RedirectionSavedState object
18901893
"""
18911894
import io
18921895
import subprocess
18931896

1894-
# Default to no redirection
1895-
ret_val = RedirectionSavedState(None, None, None)
1897+
ret_val = RedirectionSavedState(redirecting=False, piping=False)
18961898

18971899
if not self.allow_redirection:
18981900
return ret_val
@@ -1908,9 +1910,8 @@ def _redirect_output(self, statement: Statement) -> RedirectionSavedState:
19081910
# We want Popen to raise an exception if it fails to open the process. Thus we don't set shell to True.
19091911
try:
19101912
pipe_proc = subprocess.Popen(statement.pipe_to, stdin=pipe_read, stdout=self.stdout)
1911-
ret_val = RedirectionSavedState(self_stdout=self.stdout,
1912-
sys_stdout=None,
1913-
pipe_proc=self.pipe_proc)
1913+
ret_val = RedirectionSavedState(redirecting=True, self_stdout=self.stdout,
1914+
piping=True, pipe_proc=self.pipe_proc)
19141915
self.stdout = pipe_write
19151916
self.pipe_proc = pipe_proc
19161917
except Exception as ex:
@@ -1932,18 +1933,14 @@ def _redirect_output(self, statement: Statement) -> RedirectionSavedState:
19321933
mode = 'a'
19331934
try:
19341935
new_stdout = open(statement.output_to, mode)
1935-
ret_val = RedirectionSavedState(self_stdout=self.stdout,
1936-
sys_stdout=sys.stdout,
1937-
pipe_proc=None)
1936+
ret_val = RedirectionSavedState(redirecting=True, self_stdout=self.stdout, sys_stdout=sys.stdout)
19381937
sys.stdout = self.stdout = new_stdout
19391938
except OSError as ex:
19401939
self.perror('Not redirecting because - {}'.format(ex), traceback_war=False)
19411940
else:
19421941
# going to a paste buffer
19431942
new_stdout = tempfile.TemporaryFile(mode="w+")
1944-
ret_val = RedirectionSavedState(self_stdout=self.stdout,
1945-
sys_stdout=sys.stdout,
1946-
pipe_proc=None)
1943+
ret_val = RedirectionSavedState(redirecting=True, self_stdout=self.stdout, sys_stdout=sys.stdout)
19471944
sys.stdout = self.stdout = new_stdout
19481945
if statement.output == constants.REDIRECTION_APPEND:
19491946
self.poutput(get_paste_buffer())
@@ -1958,7 +1955,7 @@ def _restore_output(self, statement: Statement, saved_state: RedirectionSavedSta
19581955
:param saved_state: contains information needed to restore state data
19591956
"""
19601957
# Check if self.stdout was redirected
1961-
if saved_state.self_stdout is not None:
1958+
if saved_state.redirecting:
19621959
# If we redirected output to the clipboard
19631960
if statement.output and not statement.output_to:
19641961
self.stdout.seek(0)
@@ -1972,14 +1969,14 @@ def _restore_output(self, statement: Statement, saved_state: RedirectionSavedSta
19721969
finally:
19731970
self.stdout = saved_state.self_stdout
19741971

1975-
# Check if output was being piped to a process
1976-
if saved_state.pipe_proc is not None:
1977-
self.pipe_proc.communicate()
1978-
self.pipe_proc = saved_state.pipe_proc
1972+
# Check if sys.stdout was redirected
1973+
if saved_state.sys_stdout is not None:
1974+
sys.stdout = saved_state.sys_stdout
19791975

1980-
# Check if sys.stdout was redirected
1981-
if saved_state.sys_stdout is not None:
1982-
sys.stdout = saved_state.sys_stdout
1976+
# Check if output was being piped to a process
1977+
if saved_state.piping:
1978+
self.pipe_proc.communicate()
1979+
self.pipe_proc = saved_state.pipe_proc
19831980

19841981
def cmd_func(self, command: str) -> Optional[Callable]:
19851982
"""

0 commit comments

Comments
 (0)