Allow file objects to be passed to loop.subprocess* functions.

Fixes #136.
This commit is contained in:
Yury Selivanov 2018-05-23 19:19:31 -04:00
parent 572524a614
commit f083090156
2 changed files with 59 additions and 7 deletions

View File

@ -342,6 +342,10 @@ class _AsyncioTests:
'data = sys.stdin.buffer.read()',
'sys.stdout.buffer.write(data)'))]
PROGRAM_ERROR = [
sys.executable, '-c', '1/0'
]
def test_stdin_not_inheritable(self):
# asyncio issue #209: stdin must not be inheritable, otherwise
# the Process.communicate() hangs
@ -363,7 +367,7 @@ class _AsyncioTests:
self.assertEqual(output.rstrip(), b'3')
self.assertEqual(exitcode, 0)
def test_stdin_stdout(self):
def test_stdin_stdout_pipe(self):
args = self.PROGRAM_CAT
@asyncio.coroutine
@ -390,6 +394,57 @@ class _AsyncioTests:
self.assertEqual(exitcode, 0)
self.assertEqual(stdout, b'some data')
def test_stdin_stdout_file(self):
args = self.PROGRAM_CAT
@asyncio.coroutine
def run(data, stderr):
proc = yield from asyncio.create_subprocess_exec(
*args,
stdin=subprocess.PIPE,
stderr=stdout,
loop=self.loop)
# feed data
proc.stdin.write(data)
yield from proc.stdin.drain()
proc.stdin.close()
exitcode = yield from proc.wait()
return exitcode
with tempfile.TemporaryFile('w+b') as new_stdout:
task = run(b'some data', new_stdout)
task = asyncio.wait_for(task, 60.0, loop=self.loop)
exitcode = self.loop.run_until_complete(task)
self.assertEqual(exitcode, 0)
new_stdout.seek(0)
self.assertEqual(new_stdout.read(), b'some data')
def test_stdin_stderr_file(self):
args = self.PROGRAM_ERROR
@asyncio.coroutine
def run(stderr):
proc = yield from asyncio.create_subprocess_exec(
*args,
stdin=subprocess.PIPE,
stderr=stderr,
loop=self.loop)
exitcode = yield from proc.wait()
return exitcode
with tempfile.TemporaryFile('w+b') as new_stderr:
task = run(new_stderr)
task = asyncio.wait_for(task, 60.0, loop=self.loop)
exitcode = self.loop.run_until_complete(task)
self.assertEqual(exitcode, 1)
new_stderr.seek(0)
self.assertIn(b'ZeroDivisionError', new_stderr.read())
def test_communicate(self):
args = self.PROGRAM_CAT

View File

@ -424,8 +424,7 @@ cdef class UVProcessTransport(UVProcess):
raise ValueError(
'subprocess.STDOUT is supported only by stderr parameter')
else:
raise ValueError(
'invalid stdin argument value {!r}'.format(_stdin))
io[0] = self._file_redirect_stdio(_stdin)
else:
io[0] = self._file_redirect_stdio(sys.stdin.fileno())
@ -453,8 +452,7 @@ cdef class UVProcessTransport(UVProcess):
raise ValueError(
'subprocess.STDOUT is supported only by stderr parameter')
else:
raise ValueError(
'invalid stdout argument value {!r}'.format(_stdout))
io[1] = self._file_redirect_stdio(_stdout)
else:
io[1] = self._file_redirect_stdio(sys.stdout.fileno())
@ -482,8 +480,7 @@ cdef class UVProcessTransport(UVProcess):
elif _stderr == subprocess_DEVNULL:
io[2] = self._file_devnull()
else:
raise ValueError(
'invalid stderr argument value {!r}'.format(_stderr))
io[2] = self._file_redirect_stdio(_stderr)
else:
io[2] = self._file_redirect_stdio(sys.stderr.fileno())