Skip to content

Commit a2df310

Browse files
committed
Added pipe buffer size that can be tweaked if stdin/stdout need to be larger when piping to shell commands.
Fixed error caused by BrokenPipeError not existing in Python 2.
1 parent 751f936 commit a2df310

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

cmd2.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@
8282
except ImportError:
8383
pass
8484

85+
# BrokenPipeError is only in Python 3. Use IOError for Python 2.
86+
if six.PY3:
87+
BROKEN_PIPE_ERROR = BrokenPipeError
88+
else:
89+
BROKEN_PIPE_ERROR = IOError
90+
8591
__version__ = '0.7.6'
8692

8793
# Pyparsing enablePackrat() can greatly speed up parsing, but problems have been seen in Python 3 in the past
@@ -539,6 +545,9 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, use_ipython=False
539545
# Used when piping command output to a shell command
540546
self.pipe_proc = None
541547

548+
# Size of the stdin/stdout buffers used when piping command output to a shell command
549+
self._pipe_buffer_size = io.DEFAULT_BUFFER_SIZE
550+
542551
# ----- Methods related to presenting output to the user -----
543552

544553
@property
@@ -575,7 +584,7 @@ def poutput(self, msg, end='\n'):
575584
self.stdout.write(msg_str)
576585
if not msg_str.endswith(end):
577586
self.stdout.write(end)
578-
except BrokenPipeError:
587+
except BROKEN_PIPE_ERROR:
579588
# This occurs if a command's output is being piped to another process and that process closes before the
580589
# command is finished. We intentionally don't print a warning message here since we know that stdout
581590
# will be restored by the _restore_output() method. If you would like your application to print a
@@ -805,9 +814,9 @@ def _redirect_output(self, statement):
805814

806815
# Open each side of the pipe and set stdout accordingly
807816
# noinspection PyTypeChecker
808-
self.stdout = io.open(write_fd, write_mode)
817+
self.stdout = io.open(write_fd, write_mode, buffering=self._pipe_buffer_size)
809818
# noinspection PyTypeChecker
810-
subproc_stdin = io.open(read_fd, read_mode)
819+
subproc_stdin = io.open(read_fd, read_mode, buffering=self._pipe_buffer_size)
811820

812821
# We want Popen to raise an exception if it fails to open the process. Thus we don't set shell to True.
813822
try:
@@ -852,7 +861,7 @@ def _restore_output(self, statement):
852861
try:
853862
# Close the file or pipe that stdout was redirected to
854863
self.stdout.close()
855-
except BrokenPipeError:
864+
except BROKEN_PIPE_ERROR:
856865
pass
857866
finally:
858867
# Restore self.stdout
@@ -2352,7 +2361,7 @@ def __nonzero__(self):
23522361
if __name__ == '__main__':
23532362
# If run as the main application, simply start a bare-bones cmd2 application with only built-in functionality.
23542363

2355-
# Set "use_iptyhon" to True to include the ipy command if IPython is installed, which supports advanced interactive
2364+
# Set "use_ipython" to True to include the ipy command if IPython is installed, which supports advanced interactive
23562365
# debugging of your application via introspection on self.
23572366
app = Cmd(use_ipython=False)
23582367
app.cmdloop()

0 commit comments

Comments
 (0)