[Python-checkins] cpython (merge 3.4 -> default): Merge 3.4 (asyncio)
victor.stinner
python-checkins at python.org
Wed Feb 4 14:54:24 CET 2015
https://hg.python.org/cpython/rev/cf4894e8f707
changeset: 94502:cf4894e8f707
parent: 94499:9c46707e5526
parent: 94501:8b52ca4d11b8
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Feb 04 14:51:50 2015 +0100
summary:
Merge 3.4 (asyncio)
files:
Lib/asyncio/base_events.py | 48 ++++++++++-----
Lib/asyncio/proactor_events.py | 3 +-
Lib/asyncio/selector_events.py | 13 ++--
Lib/test/test_asyncio/test_events.py | 4 +
4 files changed, 45 insertions(+), 23 deletions(-)
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -75,7 +75,11 @@
def _check_resolved_address(sock, address):
# Ensure that the address is already resolved to avoid the trap of hanging
# the entire event loop when the address requires doing a DNS lookup.
+ #
+ # getaddrinfo() is slow (around 10 us per call): this function should only
+ # be called in debug mode
family = sock.family
+
if family == socket.AF_INET:
host, port = address
elif family == socket.AF_INET6:
@@ -83,22 +87,34 @@
else:
return
- type_mask = 0
- if hasattr(socket, 'SOCK_NONBLOCK'):
- type_mask |= socket.SOCK_NONBLOCK
- if hasattr(socket, 'SOCK_CLOEXEC'):
- type_mask |= socket.SOCK_CLOEXEC
- # Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is
- # already resolved.
- try:
- socket.getaddrinfo(host, port,
- family=family,
- type=(sock.type & ~type_mask),
- proto=sock.proto,
- flags=socket.AI_NUMERICHOST)
- except socket.gaierror as err:
- raise ValueError("address must be resolved (IP address), got %r: %s"
- % (address, err))
+ # On Windows, socket.inet_pton() is only available since Python 3.4
+ if hasattr(socket, 'inet_pton'):
+ # getaddrinfo() is slow and has known issue: prefer inet_pton()
+ # if available
+ try:
+ socket.inet_pton(family, host)
+ except OSError as exc:
+ raise ValueError("address must be resolved (IP address), "
+ "got host %r: %s"
+ % (host, exc))
+ else:
+ # Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is
+ # already resolved.
+ type_mask = 0
+ if hasattr(socket, 'SOCK_NONBLOCK'):
+ type_mask |= socket.SOCK_NONBLOCK
+ if hasattr(socket, 'SOCK_CLOEXEC'):
+ type_mask |= socket.SOCK_CLOEXEC
+ try:
+ socket.getaddrinfo(host, port,
+ family=family,
+ type=(sock.type & ~type_mask),
+ proto=sock.proto,
+ flags=socket.AI_NUMERICHOST)
+ except socket.gaierror as err:
+ raise ValueError("address must be resolved (IP address), "
+ "got host %r: %s"
+ % (host, err))
def _raise_stop_error(*args):
raise _StopError
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -437,7 +437,8 @@
def sock_connect(self, sock, address):
try:
- base_events._check_resolved_address(sock, address)
+ if self._debug:
+ base_events._check_resolved_address(sock, address)
except ValueError as err:
fut = futures.Future(loop=self)
fut.set_exception(err)
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -214,7 +214,7 @@
# It's now up to the protocol to handle the connection.
except Exception as exc:
- if self.get_debug():
+ if self._debug:
context = {
'message': ('Error on transport creation '
'for incoming connection'),
@@ -312,7 +312,7 @@
This method is a coroutine.
"""
- if self.get_debug() and sock.gettimeout() != 0:
+ if self._debug and sock.gettimeout() != 0:
raise ValueError("the socket must be non-blocking")
fut = futures.Future(loop=self)
self._sock_recv(fut, False, sock, n)
@@ -350,7 +350,7 @@
This method is a coroutine.
"""
- if self.get_debug() and sock.gettimeout() != 0:
+ if self._debug and sock.gettimeout() != 0:
raise ValueError("the socket must be non-blocking")
fut = futures.Future(loop=self)
if data:
@@ -393,11 +393,12 @@
This method is a coroutine.
"""
- if self.get_debug() and sock.gettimeout() != 0:
+ if self._debug and sock.gettimeout() != 0:
raise ValueError("the socket must be non-blocking")
fut = futures.Future(loop=self)
try:
- base_events._check_resolved_address(sock, address)
+ if self._debug:
+ base_events._check_resolved_address(sock, address)
except ValueError as err:
fut.set_exception(err)
else:
@@ -453,7 +454,7 @@
This method is a coroutine.
"""
- if self.get_debug() and sock.gettimeout() != 0:
+ if self._debug and sock.gettimeout() != 0:
raise ValueError("the socket must be non-blocking")
fut = futures.Future(loop=self)
self._sock_accept(fut, False, sock)
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -1437,6 +1437,10 @@
'selector': self.loop._selector.__class__.__name__})
def test_sock_connect_address(self):
+ # In debug mode, sock_connect() must ensure that the address is already
+ # resolved (call _check_resolved_address())
+ self.loop.set_debug(True)
+
addresses = [(socket.AF_INET, ('www.python.org', 80))]
if support.IPV6_ENABLED:
addresses.extend((
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list