Skip to content

Commit ca7f24b

Browse files
committed
Only enabling/disabling stdout storage in the call PyscriptBridge makes to onecmd_plus_hooks.
All nested calls to onecmd_plus_hooks keep capturing stdout to match the behavior of stdout redirection being enabled during nested commands.
1 parent 47b531d commit ca7f24b

File tree

2 files changed

+12
-18
lines changed

2 files changed

+12
-18
lines changed

cmd2/cmd2.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,10 +1675,13 @@ def parseline(self, line: str) -> Tuple[str, str, str]:
16751675
statement = self.statement_parser.parse_command_only(line)
16761676
return statement.command, statement.args, statement.command_and_args
16771677

1678-
def onecmd_plus_hooks(self, line: str) -> bool:
1678+
def onecmd_plus_hooks(self, line: str, pyscript_bridge_call: bool = False) -> bool:
16791679
"""Top-level function called by cmdloop() to handle parsing a line and running the command and all of its hooks.
16801680
16811681
:param line: line of text read from input
1682+
:param pyscript_bridge_call: This should only ever be set to True by PyscriptBridge to signify the beginning
1683+
of an app() call in a pyscript. It is used to enable/disable the storage of the
1684+
command's stdout.
16821685
:return: True if cmdloop() should exit, False otherwise
16831686
"""
16841687
import datetime
@@ -1718,10 +1721,9 @@ def onecmd_plus_hooks(self, line: str) -> bool:
17181721
try:
17191722
# Get sigint protection while we set up redirection
17201723
with self.sigint_protection:
1721-
if self._in_py:
1722-
# Start saving output at this point to match the same period output is redirected
1724+
if pyscript_bridge_call:
1725+
# Start saving command's stdout at this point
17231726
self.stdout.pause_storage = False
1724-
sys.stderr.pause_storage = False
17251727

17261728
redir_error, saved_state = self._redirect_output(statement)
17271729
self.cur_pipe_proc_reader = saved_state.pipe_proc_reader
@@ -1768,10 +1770,9 @@ def onecmd_plus_hooks(self, line: str) -> bool:
17681770
if not already_redirecting:
17691771
self.redirecting = False
17701772

1771-
if self._in_py:
1772-
# Stop saving command's output before command finalization hooks run
1773+
if pyscript_bridge_call:
1774+
# Stop saving command's stdout before command finalization hooks run
17731775
self.stdout.pause_storage = True
1774-
sys.stderr.pause_storage = True
17751776

17761777
except EmptyStatement:
17771778
# don't do anything, but do allow command finalization hooks to run
@@ -1801,12 +1802,6 @@ def _run_cmdfinalization_hooks(self, stop: bool, statement: Optional[Statement])
18011802
return data.stop
18021803
except Exception as ex:
18031804
self.perror(ex)
1804-
finally:
1805-
with self.sigint_protection:
1806-
if self._in_py:
1807-
# Restore ability to save output now that the command finalization hooks are done
1808-
self.stdout.pause_storage = False
1809-
sys.stderr.pause_storage = False
18101805

18111806
def runcmds_plus_hooks(self, cmds: List[str]) -> bool:
18121807
"""Convenience method to run multiple commands by onecmd_plus_hooks.

cmd2/pyscript_bridge.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,19 @@ def __call__(self, command: str, echo: Optional[bool] = None) -> CommandResult:
8787
# This will be used to capture _cmd2_app.stdout and sys.stdout
8888
copy_cmd_stdout = StdSim(self._cmd2_app.stdout, echo)
8989

90+
# Pause the storing of stdout until onecmd_plus_hooks enables it
91+
copy_cmd_stdout.pause_storage = True
92+
9093
# This will be used to capture sys.stderr
9194
copy_stderr = StdSim(sys.stderr, echo)
9295

93-
# Pause the storing of any output until onecmd_plus_hooks enables it
94-
copy_cmd_stdout.pause_storage = True
95-
copy_stderr.pause_storage = True
96-
9796
self._cmd2_app._last_result = None
9897

9998
try:
10099
self._cmd2_app.stdout = copy_cmd_stdout
101100
with redirect_stdout(copy_cmd_stdout):
102101
with redirect_stderr(copy_stderr):
103-
self._cmd2_app.onecmd_plus_hooks(command)
102+
self._cmd2_app.onecmd_plus_hooks(command, pyscript_bridge_call=True)
104103
finally:
105104
self._cmd2_app.stdout = copy_cmd_stdout.inner_stream
106105

0 commit comments

Comments
 (0)