Chromium Code Reviews| Index: subprocess2.py |
| diff --git a/subprocess2.py b/subprocess2.py |
| index a00592f4774a83eaa8e697d38c8ab7a921903fa9..37b9b64394a4606a9405dcb2acfaa20b755fa198 100644 |
| --- a/subprocess2.py |
| +++ b/subprocess2.py |
| @@ -462,6 +462,49 @@ def communicate(args, timeout=None, nag_timer=None, nag_max=None, **kwargs): |
| return proc.communicate(None, timeout, nag_timer), proc.returncode |
| +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
|
| + """Same as communicate, but will not just capture, but also stream output |
| + streams while command is running. |
| + |
| + Returns ((stdout, stderr), returncode). |
| + |
| + By default, streams and captures both stdout and stderr. You can silence any |
| + of the streams, but passing std{err,out} special PIPE or VOID, depending on |
| + whether you want it captured or completely ignored. |
| + |
| + This useful for commands that take time to run, such that it's useful to both |
| + capture output but also steram as parent process std{out,err}. |
| + """ |
| + # communicate method above won't capture anything if std{err,out} is callable. |
| + # So, capture it ourselves essentially the same way. |
| + # 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
|
| + # output directly with simple labmbda, no need for yet another thread. |
| + def combine_funcs(f1, f2): |
| + def f(x): |
| + f1(x) |
| + f2(x) |
| + return f |
| + |
| + result = {} |
| + for stream in ('stderr', 'stdout'): |
| + if stream in kwargs: |
| + # Don't stream/capture streams that user specified explicitely. |
|
Paweł Hajdan Jr.
2016/03/08 23:52:24
nit: explicitely -> explicitly
|
| + continue |
| + result[stream] = [] # Container to hold results data chunks. |
| + kwargs[stream] = combine_funcs( |
| + result[stream].append, |
| + getattr(sys, stream).write) |
| + |
| + (out, err), returncode = communicate(args, **kwargs) |
| + if 'stderr' in result: |
| + assert not err |
| + err = ''.join(result['stderr']) |
| + if 'stdout' in result: |
| + assert not out |
| + out = ''.join(result['stdout']) |
| + return (out, err), returncode |
| + |
| + |
| def call(args, **kwargs): |
| """Emulates subprocess.call(). |