Skip to content

Commit

Permalink
Allow file objects to be passed to loop.subprocess* functions.
Browse files Browse the repository at this point in the history
Fixes #136.
  • Loading branch information
1st1 committed May 23, 2018
1 parent 572524a commit f083090
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
57 changes: 56 additions & 1 deletion tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -363,7 +367,7 @@ def len_message(message):
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
Expand All @@ -390,6 +394,57 @@ def run(data):
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

Expand Down
9 changes: 3 additions & 6 deletions uvloop/handles/process.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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())

Expand Down

0 comments on commit f083090

Please sign in to comment.