Skip to content

Commit 4499f74

Browse files
committed
Allow stdout / stderr to be redirected to DEVNULL
1 parent d26918a commit 4499f74

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

command_runner/__init__.py

+20-15
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
__author__ = "Orsiris de Jong"
1919
__copyright__ = "Copyright (C) 2015-2021 Orsiris de Jong"
2020
__licence__ = "BSD 3 Clause"
21-
__version__ = "1.2.1"
22-
__build__ = "2021090901"
21+
__version__ = "1.3.0"
22+
__build__ = "2021100501"
2323

2424
import io
2525
import os
@@ -202,8 +202,8 @@ def command_runner(
202202
timeout=3600, # type: Optional[int]
203203
shell=False, # type: bool
204204
encoding=None, # type: Optional[str]
205-
stdout=None, # type: Union[int, str]
206-
stderr=None, # type: Union[int, str]
205+
stdout=None, # type: Optional[Union[int, str]]
206+
stderr=None, # type: Optional[Union[int, str]]
207207
windows_no_window=False, # type: bool
208208
live_output=False, # type: bool
209209
method="monitor", # type: str
@@ -270,25 +270,28 @@ def command_runner(
270270

271271
# Decide whether we write to output variable only (stdout=None), to output variable and stdout (stdout=PIPE)
272272
# or to output variable and to file (stdout='path/to/file')
273+
stdout_to_file = False
273274
if stdout is None:
274275
_stdout = PIPE
275-
stdout_to_file = False
276276
elif isinstance(stdout, str):
277277
# We will send anything to file
278278
_stdout = open(stdout, "wb")
279279
stdout_to_file = True
280+
elif stdout is False:
281+
_stdout = subprocess.DEVNULL
280282
else:
281283
# We will send anything to given stdout pipe
282284
_stdout = stdout
283-
stdout_to_file = False
284285

285286
# The only situation where we don't add stderr to stdout is if a specific target file was given
287+
stderr_to_file = False
286288
if isinstance(stderr, str):
287289
_stderr = open(stderr, "wb")
288290
stderr_to_file = True
291+
elif stderr is False:
292+
_stderr = subprocess.DEVNULL
289293
else:
290294
_stderr = subprocess.STDOUT
291-
stderr_to_file = False
292295

293296
def to_encoding(
294297
process_output, # type: Union[str, bytes]
@@ -469,17 +472,19 @@ def _monitor_process(
469472
break
470473
# We still need to use process.communicate() in this loop so we don't get stuck
471474
# with poll() is not None even after process is finished
475+
if _stdout is not False:
476+
try:
477+
stdout, _ = process.communicate()
478+
# ValueError is raised on closed IO file
479+
except (TimeoutExpired, ValueError):
480+
pass
481+
exit_code = process.poll()
482+
483+
if _stdout is not False:
472484
try:
473485
stdout, _ = process.communicate()
474-
# ValueError is raised on closed IO file
475486
except (TimeoutExpired, ValueError):
476487
pass
477-
exit_code = process.poll()
478-
479-
try:
480-
stdout, _ = process.communicate()
481-
except (TimeoutExpired, ValueError):
482-
pass
483488
process_output = to_encoding(stdout, encoding, errors)
484489

485490
# On PyPy 3.7 only, we can have a race condition where we try to read the queue before
@@ -537,7 +542,7 @@ def _monitor_process(
537542
)
538543

539544
try:
540-
if method == "poller" or live_output:
545+
if method == "poller" or live_output and _stdout is not False:
541546
exit_code, output = _poll_process(process, timeout, encoding, errors)
542547
else:
543548
exit_code, output = _monitor_process(process, timeout, encoding, errors)

0 commit comments

Comments
 (0)