|
18 | 18 | __author__ = "Orsiris de Jong"
|
19 | 19 | __copyright__ = "Copyright (C) 2015-2021 Orsiris de Jong"
|
20 | 20 | __licence__ = "BSD 3 Clause"
|
21 |
| -__version__ = "1.2.1" |
22 |
| -__build__ = "2021090901" |
| 21 | +__version__ = "1.3.0" |
| 22 | +__build__ = "2021100501" |
23 | 23 |
|
24 | 24 | import io
|
25 | 25 | import os
|
@@ -202,8 +202,8 @@ def command_runner(
|
202 | 202 | timeout=3600, # type: Optional[int]
|
203 | 203 | shell=False, # type: bool
|
204 | 204 | 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]] |
207 | 207 | windows_no_window=False, # type: bool
|
208 | 208 | live_output=False, # type: bool
|
209 | 209 | method="monitor", # type: str
|
@@ -270,25 +270,28 @@ def command_runner(
|
270 | 270 |
|
271 | 271 | # Decide whether we write to output variable only (stdout=None), to output variable and stdout (stdout=PIPE)
|
272 | 272 | # or to output variable and to file (stdout='path/to/file')
|
| 273 | + stdout_to_file = False |
273 | 274 | if stdout is None:
|
274 | 275 | _stdout = PIPE
|
275 |
| - stdout_to_file = False |
276 | 276 | elif isinstance(stdout, str):
|
277 | 277 | # We will send anything to file
|
278 | 278 | _stdout = open(stdout, "wb")
|
279 | 279 | stdout_to_file = True
|
| 280 | + elif stdout is False: |
| 281 | + _stdout = subprocess.DEVNULL |
280 | 282 | else:
|
281 | 283 | # We will send anything to given stdout pipe
|
282 | 284 | _stdout = stdout
|
283 |
| - stdout_to_file = False |
284 | 285 |
|
285 | 286 | # The only situation where we don't add stderr to stdout is if a specific target file was given
|
| 287 | + stderr_to_file = False |
286 | 288 | if isinstance(stderr, str):
|
287 | 289 | _stderr = open(stderr, "wb")
|
288 | 290 | stderr_to_file = True
|
| 291 | + elif stderr is False: |
| 292 | + _stderr = subprocess.DEVNULL |
289 | 293 | else:
|
290 | 294 | _stderr = subprocess.STDOUT
|
291 |
| - stderr_to_file = False |
292 | 295 |
|
293 | 296 | def to_encoding(
|
294 | 297 | process_output, # type: Union[str, bytes]
|
@@ -469,17 +472,19 @@ def _monitor_process(
|
469 | 472 | break
|
470 | 473 | # We still need to use process.communicate() in this loop so we don't get stuck
|
471 | 474 | # 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: |
472 | 484 | try:
|
473 | 485 | stdout, _ = process.communicate()
|
474 |
| - # ValueError is raised on closed IO file |
475 | 486 | except (TimeoutExpired, ValueError):
|
476 | 487 | pass
|
477 |
| - exit_code = process.poll() |
478 |
| - |
479 |
| - try: |
480 |
| - stdout, _ = process.communicate() |
481 |
| - except (TimeoutExpired, ValueError): |
482 |
| - pass |
483 | 488 | process_output = to_encoding(stdout, encoding, errors)
|
484 | 489 |
|
485 | 490 | # 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(
|
537 | 542 | )
|
538 | 543 |
|
539 | 544 | try:
|
540 |
| - if method == "poller" or live_output: |
| 545 | + if method == "poller" or live_output and _stdout is not False: |
541 | 546 | exit_code, output = _poll_process(process, timeout, encoding, errors)
|
542 | 547 | else:
|
543 | 548 | exit_code, output = _monitor_process(process, timeout, encoding, errors)
|
|
0 commit comments