cpython: 8967d9a1bc17 (original) (raw)
Mercurial > cpython
changeset 91930:8967d9a1bc17
Merge with Python 3.4 (asyncio) - Close #22063: socket operations (socket,recv, sock_sendall, sock_connect, sock_accept) now raise an exception in debug mode if sockets are in blocking mode. - asyncio: Use the new os.set_blocking() function of Python 3.5 if available [#22063]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Tue, 29 Jul 2014 23:09:56 +0200 |
parents | 129951f3d16f(current diff)7e70ec207889(diff) |
children | 741e58bcaa65 |
files | Lib/asyncio/unix_events.py Lib/test/test_asyncio/test_events.py Lib/test/test_asyncio/test_unix_events.py |
diffstat | 5 files changed, 48 insertions(+), 4 deletions(-)[+] [-] Lib/asyncio/proactor_events.py 8 Lib/asyncio/selector_events.py 8 Lib/asyncio/unix_events.py 14 Lib/test/test_asyncio/test_events.py 18 Lib/test/test_asyncio/test_unix_events.py 4 |
line wrap: on
line diff
--- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -385,12 +385,18 @@ class BaseProactorEventLoop(base_events. self._selector = None def sock_recv(self, sock, n):
if self.get_debug() and sock.gettimeout() != 0:[](#l1.7)
raise ValueError("the socket must be non-blocking")[](#l1.8) return self._proactor.recv(sock, n)[](#l1.9)
def sock_sendall(self, sock, data):
if self.get_debug() and sock.gettimeout() != 0:[](#l1.12)
raise ValueError("the socket must be non-blocking")[](#l1.13) return self._proactor.send(sock, data)[](#l1.14)
def sock_connect(self, sock, address):
if self.get_debug() and sock.gettimeout() != 0:[](#l1.17)
raise ValueError("the socket must be non-blocking")[](#l1.18) try:[](#l1.19) base_events._check_resolved_address(sock, address)[](#l1.20) except ValueError as err:[](#l1.21)
@@ -401,6 +407,8 @@ class BaseProactorEventLoop(base_events. return self._proactor.connect(sock, address) def sock_accept(self, sock):
if self.get_debug() and sock.gettimeout() != 0:[](#l1.26)
raise ValueError("the socket must be non-blocking")[](#l1.27) return self._proactor.accept(sock)[](#l1.28)
--- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -256,6 +256,8 @@ class BaseSelectorEventLoop(base_events. This method is a coroutine. """
if self.get_debug() and sock.gettimeout() != 0:[](#l2.7)
raise ValueError("the socket must be non-blocking")[](#l2.8) fut = futures.Future(loop=self)[](#l2.9) self._sock_recv(fut, False, sock, n)[](#l2.10) return fut[](#l2.11)
@@ -292,6 +294,8 @@ class BaseSelectorEventLoop(base_events. This method is a coroutine. """
if self.get_debug() and sock.gettimeout() != 0:[](#l2.16)
raise ValueError("the socket must be non-blocking")[](#l2.17) fut = futures.Future(loop=self)[](#l2.18) if data:[](#l2.19) self._sock_sendall(fut, False, sock, data)[](#l2.20)
@@ -333,6 +337,8 @@ class BaseSelectorEventLoop(base_events. This method is a coroutine. """
if self.get_debug() and sock.gettimeout() != 0:[](#l2.25)
raise ValueError("the socket must be non-blocking")[](#l2.26) fut = futures.Future(loop=self)[](#l2.27) try:[](#l2.28) base_events._check_resolved_address(sock, address)[](#l2.29)
@@ -374,6 +380,8 @@ class BaseSelectorEventLoop(base_events. This method is a coroutine. """
if self.get_debug() and sock.gettimeout() != 0:[](#l2.34)
raise ValueError("the socket must be non-blocking")[](#l2.35) fut = futures.Future(loop=self)[](#l2.36) self._sock_accept(fut, False, sock)[](#l2.37) return fut[](#l2.38)
--- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -258,6 +258,16 @@ class _UnixSelectorEventLoop(selector_ev return server +if hasattr(os, 'set_blocking'):
- def _set_nonblocking(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)[](#l3.12)
flags = flags | os.O_NONBLOCK[](#l3.13)
fcntl.fcntl(fd, fcntl.F_SETFL, flags)[](#l3.14)
+ + class _UnixReadPipeTransport(transports.ReadTransport): max_size = 256 * 1024 # max bytes we read in one event loop iteration @@ -273,7 +283,7 @@ class _UnixReadPipeTransport(transports. stat.S_ISSOCK(mode) or stat.S_ISCHR(mode)): raise ValueError("Pipe transport is for pipes/sockets only.")
os.set_blocking(self._fileno, False)[](#l3.24)
_set_nonblocking(self._fileno)[](#l3.25) self._protocol = protocol[](#l3.26) self._closing = False[](#l3.27) self._loop.add_reader(self._fileno, self._read_ready)[](#l3.28)
@@ -366,7 +376,7 @@ class _UnixWritePipeTransport(transports stat.S_ISCHR(mode)): raise ValueError("Pipe transport is only for " "pipes, sockets and character devices")
os.set_blocking(self._fileno, False)[](#l3.33)
_set_nonblocking(self._fileno)[](#l3.34) self._protocol = protocol[](#l3.35) self._buffer = [][](#l3.36) self._conn_lost = 0[](#l3.37)
--- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -383,6 +383,24 @@ class EventLoopTestsMixin: self.assertEqual(read, data) def _basetest_sock_client_ops(self, httpd, sock):
# in debug mode, socket operations must fail[](#l4.7)
# if the socket is not in blocking mode[](#l4.8)
self.loop.set_debug(True)[](#l4.9)
sock.setblocking(True)[](#l4.10)
with self.assertRaises(ValueError):[](#l4.11)
self.loop.run_until_complete([](#l4.12)
self.loop.sock_connect(sock, httpd.address))[](#l4.13)
with self.assertRaises(ValueError):[](#l4.14)
self.loop.run_until_complete([](#l4.15)
self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n'))[](#l4.16)
with self.assertRaises(ValueError):[](#l4.17)
self.loop.run_until_complete([](#l4.18)
self.loop.sock_recv(sock, 1024))[](#l4.19)
with self.assertRaises(ValueError):[](#l4.20)
self.loop.run_until_complete([](#l4.21)
self.loop.sock_accept(sock))[](#l4.22)
# test in non-blocking mode[](#l4.24) sock.setblocking(False)[](#l4.25) self.loop.run_until_complete([](#l4.26) self.loop.sock_connect(sock, httpd.address))[](#l4.27)
--- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -306,7 +306,7 @@ class UnixReadPipeTransportTests(test_ut self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5
blocking_patcher = mock.patch('os.set_blocking')[](#l5.7)
blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking')[](#l5.8) blocking_patcher.start()[](#l5.9) self.addCleanup(blocking_patcher.stop)[](#l5.10)
@@ -469,7 +469,7 @@ class UnixWritePipeTransportTests(test_u self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5
blocking_patcher = mock.patch('os.set_blocking')[](#l5.16)
blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking')[](#l5.17) blocking_patcher.start()[](#l5.18) self.addCleanup(blocking_patcher.stop)[](#l5.19)