-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasyncio_subprocess_run.py
60 lines (50 loc) · 2.06 KB
/
asyncio_subprocess_run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import asyncio
from subprocess import PIPE, TimeoutExpired, CalledProcessError, CompletedProcess
import io
import locale
async def run(args, input=None, capture_output=False, shell=False, timeout=None,
check=False, encoding=None, errors=None, text=None,
universal_newlines=None, **kwargs):
text = encoding or errors or text or universal_newlines
# universal_newlines is deprecated, use text instead
if text and not encoding:
encoding = locale.getpreferredencoding()
if input is not None:
if kwargs.get('stdin') is not None:
raise ValueError('stdin and input arguments may not both be used.')
kwargs['stdin'] = PIPE
if text:
input = input.encode(encoding, errors)
if capture_output:
if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
raise ValueError('stdout and stderr arguments may not be used '
'with capture_output.')
kwargs['stdout'] = PIPE
kwargs['stderr'] = PIPE
def _maybe_text(data):
if text and data is not None:
return io.TextIOWrapper(
io.BytesIO(data),
encoding=encoding, errors=errors).read()
return data
if shell:
proc = await asyncio.create_subprocess_shell(args, **kwargs)
else:
proc = await asyncio.create_subprocess_exec(*args, **kwargs)
coro = asyncio.create_task(proc.communicate(input))
try:
stdout, stderr = await asyncio.wait_for(asyncio.shield(coro), timeout)
except asyncio.TimeoutError:
proc.kill()
stdout, stderr = await coro
raise TimeoutExpired(
args, timeout, _maybe_text(stdout), _maybe_text(stderr))
except asyncio.CancelledError:
proc.kill()
raise
if check and proc.returncode != 0:
raise CalledProcessError(
proc.returncode, args,
_maybe_text(stdout), _maybe_text(stderr))
return CompletedProcess(
args, proc.returncode, _maybe_text(stdout), _maybe_text(stderr))