mirror of https://github.com/python/cpython
Merge 3.4 (asyncio)
This commit is contained in:
commit
c028b95789
|
@ -75,7 +75,11 @@ class _StopError(BaseException):
|
||||||
def _check_resolved_address(sock, address):
|
def _check_resolved_address(sock, address):
|
||||||
# Ensure that the address is already resolved to avoid the trap of hanging
|
# 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.
|
# 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
|
family = sock.family
|
||||||
|
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET:
|
||||||
host, port = address
|
host, port = address
|
||||||
elif family == socket.AF_INET6:
|
elif family == socket.AF_INET6:
|
||||||
|
@ -83,22 +87,34 @@ def _check_resolved_address(sock, address):
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
type_mask = 0
|
# On Windows, socket.inet_pton() is only available since Python 3.4
|
||||||
if hasattr(socket, 'SOCK_NONBLOCK'):
|
if hasattr(socket, 'inet_pton'):
|
||||||
type_mask |= socket.SOCK_NONBLOCK
|
# getaddrinfo() is slow and has known issue: prefer inet_pton()
|
||||||
if hasattr(socket, 'SOCK_CLOEXEC'):
|
# if available
|
||||||
type_mask |= socket.SOCK_CLOEXEC
|
try:
|
||||||
# Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is
|
socket.inet_pton(family, host)
|
||||||
# already resolved.
|
except OSError as exc:
|
||||||
try:
|
raise ValueError("address must be resolved (IP address), "
|
||||||
socket.getaddrinfo(host, port,
|
"got host %r: %s"
|
||||||
family=family,
|
% (host, exc))
|
||||||
type=(sock.type & ~type_mask),
|
else:
|
||||||
proto=sock.proto,
|
# Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is
|
||||||
flags=socket.AI_NUMERICHOST)
|
# already resolved.
|
||||||
except socket.gaierror as err:
|
type_mask = 0
|
||||||
raise ValueError("address must be resolved (IP address), got %r: %s"
|
if hasattr(socket, 'SOCK_NONBLOCK'):
|
||||||
% (address, err))
|
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):
|
def _raise_stop_error(*args):
|
||||||
raise _StopError
|
raise _StopError
|
||||||
|
|
|
@ -437,7 +437,8 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
def sock_connect(self, sock, address):
|
def sock_connect(self, sock, address):
|
||||||
try:
|
try:
|
||||||
base_events._check_resolved_address(sock, address)
|
if self._debug:
|
||||||
|
base_events._check_resolved_address(sock, address)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
fut = futures.Future(loop=self)
|
fut = futures.Future(loop=self)
|
||||||
fut.set_exception(err)
|
fut.set_exception(err)
|
||||||
|
|
|
@ -214,7 +214,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
# It's now up to the protocol to handle the connection.
|
# It's now up to the protocol to handle the connection.
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
if self.get_debug():
|
if self._debug:
|
||||||
context = {
|
context = {
|
||||||
'message': ('Error on transport creation '
|
'message': ('Error on transport creation '
|
||||||
'for incoming connection'),
|
'for incoming connection'),
|
||||||
|
@ -312,7 +312,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
This method is a coroutine.
|
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")
|
raise ValueError("the socket must be non-blocking")
|
||||||
fut = futures.Future(loop=self)
|
fut = futures.Future(loop=self)
|
||||||
self._sock_recv(fut, False, sock, n)
|
self._sock_recv(fut, False, sock, n)
|
||||||
|
@ -350,7 +350,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
This method is a coroutine.
|
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")
|
raise ValueError("the socket must be non-blocking")
|
||||||
fut = futures.Future(loop=self)
|
fut = futures.Future(loop=self)
|
||||||
if data:
|
if data:
|
||||||
|
@ -393,11 +393,12 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
This method is a coroutine.
|
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")
|
raise ValueError("the socket must be non-blocking")
|
||||||
fut = futures.Future(loop=self)
|
fut = futures.Future(loop=self)
|
||||||
try:
|
try:
|
||||||
base_events._check_resolved_address(sock, address)
|
if self._debug:
|
||||||
|
base_events._check_resolved_address(sock, address)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
fut.set_exception(err)
|
fut.set_exception(err)
|
||||||
else:
|
else:
|
||||||
|
@ -453,7 +454,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
|
|
||||||
This method is a coroutine.
|
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")
|
raise ValueError("the socket must be non-blocking")
|
||||||
fut = futures.Future(loop=self)
|
fut = futures.Future(loop=self)
|
||||||
self._sock_accept(fut, False, sock)
|
self._sock_accept(fut, False, sock)
|
||||||
|
|
|
@ -1437,6 +1437,10 @@ class EventLoopTestsMixin:
|
||||||
'selector': self.loop._selector.__class__.__name__})
|
'selector': self.loop._selector.__class__.__name__})
|
||||||
|
|
||||||
def test_sock_connect_address(self):
|
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))]
|
addresses = [(socket.AF_INET, ('www.python.org', 80))]
|
||||||
if support.IPV6_ENABLED:
|
if support.IPV6_ENABLED:
|
||||||
addresses.extend((
|
addresses.extend((
|
||||||
|
|
Loading…
Reference in New Issue