[Python-checkins] cpython (merge 3.4 -> default): Merge 3.4 (asyncio)

victor.stinner python-checkins at python.org
Thu Dec 11 23:31:45 CET 2014


https://hg.python.org/cpython/rev/2e636ac3fdbb
changeset: 93837:2e636ac3fdbb
parent: 93835:7c2811521261
parent: 93836:17f5ddf15ced
user: Victor Stinner <victor.stinner at gmail.com>
date: Thu Dec 11 23:30:31 2014 +0100
summary:
 Merge 3.4 (asyncio)
files:
 Lib/asyncio/unix_events.py | 22 ++++++++++++
 Lib/test/test_asyncio/test_subprocess.py | 21 +++++++++++
 2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -547,6 +547,22 @@
 self._loop = None
 
 
+if hasattr(os, 'set_inheritable'):
+ # Python 3.4 and newer
+ _set_inheritable = os.set_inheritable
+else:
+ import fcntl
+
+ def _set_inheritable(fd, inheritable):
+ cloexec_flag = getattr(fcntl, 'FD_CLOEXEC', 1)
+
+ old = fcntl.fcntl(fd, fcntl.F_GETFD)
+ if not inheritable:
+ fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
+ else:
+ fcntl.fcntl(fd, fcntl.F_SETFD, old & ~cloexec_flag)
+
+
 class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport):
 
 def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs):
@@ -558,6 +574,12 @@
 # other end). Notably this is needed on AIX, and works
 # just fine on other platforms.
 stdin, stdin_w = self._loop._socketpair()
+
+ # Mark the write end of the stdin pipe as non-inheritable,
+ # needed by close_fds=False on Python 3.3 and older
+ # (Python 3.4 implements the PEP 446, socketpair returns
+ # non-inheritable sockets)
+ _set_inheritable(stdin_w.fileno(), False)
 self._proc = subprocess.Popen(
 args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr,
 universal_newlines=False, bufsize=bufsize, **kwargs)
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -198,6 +198,27 @@
 self.assertTrue(transport.pause_reading.called)
 self.assertTrue(transport.resume_reading.called)
 
+ def test_stdin_not_inheritable(self):
+ # Tulip issue #209: stdin must not be inheritable, otherwise
+ # the Process.communicate() hangs
+ @asyncio.coroutine
+ def len_message(message):
+ code = 'import sys; data = sys.stdin.read(); print(len(data))'
+ proc = yield from asyncio.create_subprocess_exec(
+ sys.executable, '-c', code,
+ stdin=asyncio.subprocess.PIPE,
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
+ close_fds=False,
+ loop=self.loop)
+ stdout, stderr = yield from proc.communicate(message)
+ exitcode = yield from proc.wait()
+ return (stdout, exitcode)
+
+ output, exitcode = self.loop.run_until_complete(len_message(b'abc'))
+ self.assertEqual(output.rstrip(), b'3')
+ self.assertEqual(exitcode, 0)
+
 
 if sys.platform != 'win32':
 # Unix
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /