OLD | NEW |
---|---|
1 # coding=utf8 | 1 # coding=utf8 |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 """Collection of subprocess wrapper functions. | 5 """Collection of subprocess wrapper functions. |
6 | 6 |
7 In theory you shouldn't need anything else in subprocess, or this module failed. | 7 In theory you shouldn't need anything else in subprocess, or this module failed. |
8 """ | 8 """ |
9 | 9 |
10 import cStringIO | 10 import cStringIO |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 kwargs['stdin'] = stdin | 455 kwargs['stdin'] = stdin |
456 stdin = None | 456 stdin = None |
457 | 457 |
458 proc = Popen(args, **kwargs) | 458 proc = Popen(args, **kwargs) |
459 if stdin: | 459 if stdin: |
460 return proc.communicate(stdin, timeout, nag_timer), proc.returncode | 460 return proc.communicate(stdin, timeout, nag_timer), proc.returncode |
461 else: | 461 else: |
462 return proc.communicate(None, timeout, nag_timer), proc.returncode | 462 return proc.communicate(None, timeout, nag_timer), proc.returncode |
463 | 463 |
464 | 464 |
465 def communicate_and_stream(args, **kwargs): | |
M-A Ruel
2016/03/08 23:54:08
There's a function to do something similar in gcli
| |
466 """Same as communicate, but will not just capture, but also stream output | |
467 streams while command is running. | |
468 | |
469 Returns ((stdout, stderr), returncode). | |
470 | |
471 By default, streams and captures both stdout and stderr. You can silence any | |
472 of the streams, but passing std{err,out} special PIPE or VOID, depending on | |
473 whether you want it captured or completely ignored. | |
474 | |
475 This useful for commands that take time to run, such that it's useful to both | |
476 capture output but also steram as parent process std{out,err}. | |
477 """ | |
478 # communicate method above won't capture anything if std{err,out} is callable. | |
479 # So, capture it ourselves essentially the same way. | |
480 # Aslo, because callbacks are called in asynchroneous thread, we can stream | |
Paweł Hajdan Jr.
2016/03/08 23:52:24
nit: Aslo -> Also ; asynchroneous -> asynchronous
| |
481 # output directly with simple labmbda, no need for yet another thread. | |
482 def combine_funcs(f1, f2): | |
483 def f(x): | |
484 f1(x) | |
485 f2(x) | |
486 return f | |
487 | |
488 result = {} | |
489 for stream in ('stderr', 'stdout'): | |
490 if stream in kwargs: | |
491 # Don't stream/capture streams that user specified explicitely. | |
Paweł Hajdan Jr.
2016/03/08 23:52:24
nit: explicitely -> explicitly
| |
492 continue | |
493 result[stream] = [] # Container to hold results data chunks. | |
494 kwargs[stream] = combine_funcs( | |
495 result[stream].append, | |
496 getattr(sys, stream).write) | |
497 | |
498 (out, err), returncode = communicate(args, **kwargs) | |
499 if 'stderr' in result: | |
500 assert not err | |
501 err = ''.join(result['stderr']) | |
502 if 'stdout' in result: | |
503 assert not out | |
504 out = ''.join(result['stdout']) | |
505 return (out, err), returncode | |
506 | |
507 | |
465 def call(args, **kwargs): | 508 def call(args, **kwargs): |
466 """Emulates subprocess.call(). | 509 """Emulates subprocess.call(). |
467 | 510 |
468 Automatically convert stdout=PIPE or stderr=PIPE to VOID. | 511 Automatically convert stdout=PIPE or stderr=PIPE to VOID. |
469 In no case they can be returned since no code path raises | 512 In no case they can be returned since no code path raises |
470 subprocess2.CalledProcessError. | 513 subprocess2.CalledProcessError. |
471 """ | 514 """ |
472 if kwargs.get('stdout') == PIPE: | 515 if kwargs.get('stdout') == PIPE: |
473 kwargs['stdout'] = VOID | 516 kwargs['stdout'] = VOID |
474 if kwargs.get('stderr') == PIPE: | 517 if kwargs.get('stderr') == PIPE: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 | 558 |
516 - Throws if return code is not 0. | 559 - Throws if return code is not 0. |
517 - Works even prior to python 2.7. | 560 - Works even prior to python 2.7. |
518 - Blocks stdin by default if not specified since no output will be visible. | 561 - Blocks stdin by default if not specified since no output will be visible. |
519 - As per doc, "The stdout argument is not allowed as it is used internally." | 562 - As per doc, "The stdout argument is not allowed as it is used internally." |
520 """ | 563 """ |
521 kwargs.setdefault('stdin', VOID) | 564 kwargs.setdefault('stdin', VOID) |
522 if 'stdout' in kwargs: | 565 if 'stdout' in kwargs: |
523 raise ValueError('stdout argument not allowed, it would be overridden.') | 566 raise ValueError('stdout argument not allowed, it would be overridden.') |
524 return check_call_out(args, stdout=PIPE, **kwargs)[0] | 567 return check_call_out(args, stdout=PIPE, **kwargs)[0] |
OLD | NEW |