From 1bb84db387a276a459aa208ba2244ab187bae52b Mon Sep 17 00:00:00 2001 From: Oli Kingshott Date: Mon, 30 Apr 2018 23:25:38 +0800 Subject: [PATCH] add explicit load_backend function --- urllib3/_async/connection.py | 9 +++--- urllib3/_backends/__init__.py | 53 ++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/urllib3/_async/connection.py b/urllib3/_async/connection.py index cae10637..9e389619 100644 --- a/urllib3/_async/connection.py +++ b/urllib3/_async/connection.py @@ -30,7 +30,7 @@ ) from urllib3.packages import six from ..util import ssl_ as ssl_util -from .._backends import SyncBackend +from .._backends import load_backend from .._backends._common import LoopAbort try: @@ -306,13 +306,14 @@ class HTTP1Connection(object): #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] - def __init__(self, host, port, backend=None, + def __init__(self, host, port, + backend_name="sync", backend_args=None, socket_options=_DEFAULT_SOCKET_OPTIONS, source_address=None, tunnel_host=None, tunnel_port=None, tunnel_headers=None): self.is_verified = False - - self._backend = backend or SyncBackend() + self._backend_args = backend_args or {} + self._backend = load_backend(backend_name)(**self._backend_args) self._host = host self._port = port self._socket_options = ( diff --git a/urllib3/_backends/__init__.py b/urllib3/_backends/__init__.py index d3753330..0b7f4c21 100644 --- a/urllib3/_backends/__init__.py +++ b/urllib3/_backends/__init__.py @@ -1,9 +1,54 @@ +import logging + from urllib3.packages import six -from .sync_backend import SyncBackend -__all__ = ['SyncBackend'] -if six.PY3: +def load_trio_backend(): + if not six.PY3: + raise ValueError("trio backend requires Python 3") from .trio_backend import TrioBackend + return TrioBackend + + +def load_twisted_backend(): + if not six.PY3: + raise ValueError("twisted backend requires Python 3") from .twisted_backend import TwistedBackend - __all__ += ['TrioBackend', 'TwistedBackend'] + return TwistedBackend + + +def load_sync_backend(): + from .sync_backend import SyncBackend + return SyncBackend + + +BACKENDS = { + "sync": load_sync_backend, + "trio": load_trio_backend, + "twisted": load_twisted_backend, +} + + +def available_backends(): + """ + Returns a list of backend names that we are able to successfully import. + """ + output = [] + for backend_name, load_backend_fn in sorted(BACKENDS.items()): + try: + load_backend_fn() + output.append(backend_name) + except: # noqa + logging.exception("{} not available".format(backend_name)) + return output + + +def load_backend(backend_name): + if backend_name in BACKENDS: + return BACKENDS[backend_name]() + else: + valid_backends = ", ".join(sorted(BACKENDS.keys())) + raise ValueError("Backend must be one of: {}".format(valid_backends)) + + +__all__ = ['available_backends', 'load_backend']