summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-09-21 16:33:43 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-09-21 16:33:43 (GMT)
commit5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391 (patch)
tree09d044b9d851a9869cf1b2fba06a6c42565f5830 /Lib/asyncio
parentf7dc7fb74d7c44a60f36a69437125f5ff70e32e5 (diff)
downloadcpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.zip
cpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.tar.gz
cpython-5e4a7d8dc7781a4c0dfacecdc4db0eb34beb1391.tar.bz2
Issue #23630, asyncio: host parameter of loop.create_server() can now be a
sequence of strings. Patch written by Yann Sionneau.
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/base_events.py35
-rw-r--r--Lib/asyncio/events.py3
2 files changed, 30 insertions, 8 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index c205445..a50e005 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -18,6 +18,7 @@ import collections
import concurrent.futures
import heapq
import inspect
+import itertools
import logging
import os
import socket
@@ -787,6 +788,15 @@ class BaseEventLoop(events.AbstractEventLoop):
return transport, protocol
@coroutine
+ def _create_server_getaddrinfo(self, host, port, family, flags):
+ infos = yield from self.getaddrinfo(host, port, family=family,
+ type=socket.SOCK_STREAM,
+ flags=flags)
+ if not infos:
+ raise OSError('getaddrinfo({!r}) returned empty list'.format(host))
+ return infos
+
+ @coroutine
def create_server(self, protocol_factory, host=None, port=None,
*,
family=socket.AF_UNSPEC,
@@ -795,7 +805,13 @@ class BaseEventLoop(events.AbstractEventLoop):
backlog=100,
ssl=None,
reuse_address=None):
- """Create a TCP server bound to host and port.
+ """Create a TCP server.
+
+ The host parameter can be a string, in that case the TCP server is bound
+ to host and port.
+
+ The host parameter can also be a sequence of strings and in that case
+ the TCP server is bound to all hosts of the sequence.
Return a Server object which can be used to stop the service.
@@ -813,13 +829,18 @@ class BaseEventLoop(events.AbstractEventLoop):
reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
sockets = []
if host == '':
- host = None
+ hosts = [None]
+ elif (isinstance(host, str) or
+ not isinstance(host, collections.Iterable)):
+ hosts = [host]
+ else:
+ hosts = host
- infos = yield from self.getaddrinfo(
- host, port, family=family,
- type=socket.SOCK_STREAM, proto=0, flags=flags)
- if not infos:
- raise OSError('getaddrinfo() returned empty list')
+ fs = [self._create_server_getaddrinfo(host, port, family=family,
+ flags=flags)
+ for host in hosts]
+ infos = yield from tasks.gather(*fs, loop=self)
+ infos = itertools.chain.from_iterable(infos)
completed = False
try:
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index d5f0d45..1e42ddd 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -305,7 +305,8 @@ class AbstractEventLoop:
If host is an empty string or None all interfaces are assumed
and a list of multiple sockets will be returned (most likely
- one for IPv4 and another one for IPv6).
+ one for IPv4 and another one for IPv6). The host parameter can also be a
+ sequence (e.g. list) of hosts to bind to.
family can be set to either AF_INET or AF_INET6 to force the
socket to use IPv4 or IPv6. If not set it will be determined