diff --git a/redis/asyncio/client.py b/redis/asyncio/client.py index 412d5a24b3..0039cea540 100644 --- a/redis/asyncio/client.py +++ b/redis/asyncio/client.py @@ -2,7 +2,6 @@ import copy import inspect import re -import ssl import warnings from typing import ( TYPE_CHECKING, @@ -72,6 +71,7 @@ from redis.typing import ChannelT, EncodableT, KeyT from redis.utils import ( HIREDIS_AVAILABLE, + SSL_AVAILABLE, _set_info_logger, deprecated_function, get_lib_version, @@ -79,6 +79,11 @@ str_if_bytes, ) +if TYPE_CHECKING and SSL_AVAILABLE: + from ssl import TLSVersion +else: + TLSVersion = None + PubSubHandler = Callable[[Dict[str, str]], Awaitable[None]] _KeyT = TypeVar("_KeyT", bound=KeyT) _ArgT = TypeVar("_ArgT", KeyT, EncodableT) @@ -226,7 +231,7 @@ def __init__( ssl_ca_certs: Optional[str] = None, ssl_ca_data: Optional[str] = None, ssl_check_hostname: bool = False, - ssl_min_version: Optional[ssl.TLSVersion] = None, + ssl_min_version: Optional[TLSVersion] = None, ssl_ciphers: Optional[str] = None, max_connections: Optional[int] = None, single_connection_client: bool = False, diff --git a/redis/asyncio/cluster.py b/redis/asyncio/cluster.py index 238f74f850..ba35a7b7b8 100644 --- a/redis/asyncio/cluster.py +++ b/redis/asyncio/cluster.py @@ -2,7 +2,6 @@ import collections import random import socket -import ssl import warnings from typing import ( Any, @@ -64,7 +63,18 @@ TryAgainError, ) from redis.typing import AnyKeyT, EncodableT, KeyT -from redis.utils import deprecated_function, get_lib_version, safe_str, str_if_bytes +from redis.utils import ( + SSL_AVAILABLE, + deprecated_function, + get_lib_version, + safe_str, + str_if_bytes, +) + +if SSL_AVAILABLE: + from ssl import TLSVersion +else: + TLSVersion = None TargetNodesT = TypeVar( "TargetNodesT", str, "ClusterNode", List["ClusterNode"], Dict[Any, "ClusterNode"] @@ -247,7 +257,7 @@ def __init__( ssl_certfile: Optional[str] = None, ssl_check_hostname: bool = False, ssl_keyfile: Optional[str] = None, - ssl_min_version: Optional[ssl.TLSVersion] = None, + ssl_min_version: Optional[TLSVersion] = None, ssl_ciphers: Optional[str] = None, protocol: Optional[int] = 2, address_remap: Optional[Callable[[Tuple[str, int]], Tuple[str, int]]] = None, diff --git a/redis/asyncio/connection.py b/redis/asyncio/connection.py index 9b5d0d8eb9..15b9219aaa 100644 --- a/redis/asyncio/connection.py +++ b/redis/asyncio/connection.py @@ -3,7 +3,6 @@ import enum import inspect import socket -import ssl import sys import warnings import weakref @@ -27,6 +26,16 @@ ) from urllib.parse import ParseResult, parse_qs, unquote, urlparse +from ..utils import SSL_AVAILABLE + +if SSL_AVAILABLE: + import ssl + from ssl import SSLContext, TLSVersion +else: + ssl = None + TLSVersion = None + SSLContext = None + from ..auth.token import TokenInterface from ..event import AsyncAfterConnectionReleasedEvent, EventDispatcher from ..utils import deprecated_args, format_error_message @@ -763,10 +772,13 @@ def __init__( ssl_ca_certs: Optional[str] = None, ssl_ca_data: Optional[str] = None, ssl_check_hostname: bool = False, - ssl_min_version: Optional[ssl.TLSVersion] = None, + ssl_min_version: Optional[TLSVersion] = None, ssl_ciphers: Optional[str] = None, **kwargs, ): + if not SSL_AVAILABLE: + raise RedisError("Python wasn't built with SSL support") + self.ssl_context: RedisSSLContext = RedisSSLContext( keyfile=ssl_keyfile, certfile=ssl_certfile, @@ -834,9 +846,12 @@ def __init__( ca_certs: Optional[str] = None, ca_data: Optional[str] = None, check_hostname: bool = False, - min_version: Optional[ssl.TLSVersion] = None, + min_version: Optional[TLSVersion] = None, ciphers: Optional[str] = None, ): + if not SSL_AVAILABLE: + raise RedisError("Python wasn't built with SSL support") + self.keyfile = keyfile self.certfile = certfile if cert_reqs is None: @@ -857,9 +872,9 @@ def __init__( self.check_hostname = check_hostname self.min_version = min_version self.ciphers = ciphers - self.context: Optional[ssl.SSLContext] = None + self.context: Optional[SSLContext] = None - def get(self) -> ssl.SSLContext: + def get(self) -> SSLContext: if not self.context: context = ssl.create_default_context() context.check_hostname = self.check_hostname diff --git a/redis/connection.py b/redis/connection.py index a298542c03..b6dee40d75 100644 --- a/redis/connection.py +++ b/redis/connection.py @@ -1,7 +1,6 @@ import copy import os import socket -import ssl import sys import threading import time @@ -49,6 +48,11 @@ str_if_bytes, ) +if SSL_AVAILABLE: + import ssl +else: + ssl = None + if HIREDIS_AVAILABLE: import hiredis