HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/env/lib/python3.10/site-packages/redis/__pycache__/connection.cpython-310.pyc
o

$we\��
@s UddlZddlZddlZddlZddlZddlZddlZddlmZddl	m
Z
ddlmZm
Z
mZddlmZddlmZmZmZmZmZmZddlmZmZmZdd	lmZmZmZmZdd
l m!Z!ddl"m#Z#m$Z$ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-dd
l.m/Z/ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6e2r�ddl7Z7dZ8dZ9dZ:dZ;dZ<e=�Z>eeeeefe?d<e2r�eZ@neZ@Gdd�d�ZAGdd�d�ZBGdd�d�ZCGdd�deC�ZDGdd�deD�ZEGdd �d eC�ZFd!ZGd"d#�ZHeIeJeJeHeHeKeIeIeHd$�	ZLd%d&�ZMGd'd(�d(�ZNGd)d*�d*eN�ZOdS)+�N)�abstractmethod)�chain)�Empty�Full�	LifoQueue)�time)�Any�Callable�List�Optional�Type�Union)�parse_qs�unquote�urlparse�)�Encoder�_HiredisParser�_RESP2Parser�_RESP3Parser)�	NoBackoff)�CredentialProvider�"UsernamePasswordCredentialProvider)�AuthenticationError�$AuthenticationWrongNumberOfArgsError�ChildDeadlockedError�ConnectionError�	DataError�
RedisError�
ResponseError�TimeoutError)�Retry)�CRYPTOGRAPHY_AVAILABLE�HIREDIS_AVAILABLE�HIREDIS_PACK_AVAILABLE�
SSL_AVAILABLE�get_lib_version�str_if_bytes�*�$s
���
DefaultParserc@seZdZdefdd�ZdS)�HiredisRespSerializer�argscGs�g}t|dt�rt|d�����|dd�}nd|dvr.t|d���|dd�}z|�t�|��W|StyNt	�
�\}}}t|��|��w��2Pack a series of arguments into the Redis protocolrrN� )
�
isinstance�str�tuple�encode�split�append�hiredis�pack_command�	TypeError�sys�exc_infor�with_traceback)�selfr.�output�_�value�	traceback�rC�I/home/arjun/projects/env/lib/python3.10/site-packages/redis/connection.py�pack:s"��zHiredisRespSerializer.packN)�__name__�
__module__�__qualname__r
rErCrCrCrDr-9sr-c@seZdZddd�Zdd�ZdS)�PythonRespSerializer�returnNcCs||_||_dS�N)�_buffer_cutoffr5)r>�
buffer_cutoffr5rCrCrD�__init__Ls
zPythonRespSerializer.__init__c	Gsg}t|dt�rt|d�����|dd�}nd|dvr.t|d���|dd�}t�ttt|����t	f�}|j
}t|j|�D]>}t|�}t|�|ksZ||ksZt|t�rtt�|t
t|���t	f�}|�|�|�|�t	}qEt�|t
t|���t	|t	f�}qE|�|�|Sr/)r2r3r4r5r6�	SYM_EMPTY�join�SYM_STAR�len�SYM_CRLFrL�map�
memoryview�
SYM_DOLLARr7)r>r.r?�buffrM�arg�
arg_lengthrCrCrDrEPs<"��


��

zPythonRespSerializer.pack�rJN)rFrGrHrNrErCrCrCrDrIKs
rIc*@s�eZdZdZdddddedddedddde�ddddd	dfd
edee	dee
d
ee
dede	de	dedededee	dee	dee	dee	dee
dfdeegdfdeedeedeegdff&dd�Zdd �Zed!d"��Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zed/d0��Zed1d2��Zed3d4��Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!dMd@dA�Z"dBdC�Z#dNdDdE�Z$	dOd?ddF�dGdH�Z%dIdJ�Z&dKdL�Z'dS)P�AbstractConnectionz0Manages communication to and from a Redis serverrNF�utf-8�strictizredis-pyr+�db�password�socket_timeout�socket_connect_timeout�retry_on_timeout�encoding�encoding_errors�decode_responses�socket_read_size�health_check_interval�client_name�lib_name�lib_version�username�retry�redis_connect_func�credential_provider�protocol�command_packercCs�|s|r|durtd��t��|_||_|
|_||_||_||_||_	||_
||_|dur/|}||_||_
|tur;g}|rB|�t�||_|sI|rb|durUtt�d�|_nt�|�|_|j�|�ntt�d�|_||_d|_||_t|||	�|_d|_||_|�|
�g|_ d|_!z-zt"|�}Wnt#y�t$}Ynt%y�t&d��wW|dks�|dkr�t&d	��||_'n|dks�|dkr�t&d	��||_'w|�(|�|_)dS)
a2
        Initialize a new Connection.
        To specify a retry policy for specific errors, first set
        `retry_on_error` to a list of the error/s to retry on, then set
        `retry` to a valid `Retry` object.
        To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
        Nz�'username' and 'password' cannot be passed along with 'credential_provider'. Please provide only one of the following arguments: 
1. 'password' and (optional) 'username'
2. 'credential_provider'rripzprotocol must be an integerr+�zprotocol must be either 2 or 3)*r�os�getpid�pidr^rhrirjrnr_rkr`rarb�SENTINELr7r �retry_on_errorr!rrl�copy�deepcopy�update_supported_errorsrg�next_health_checkrmr�encoder�_sock�_socket_read_size�
set_parser�_connect_callbacksrL�intr:�DEFAULT_RESP_VERSION�
ValueErrorrro�_construct_command_packer�_command_packer)r>r^r_r`rarbrvrcrdre�parser_classrfrgrhrirjrkrlrmrnrorp�prCrCrDrN�sh�


���zAbstractConnection.__init__cCs,d�dd�|��D��}|jj�d|�d�S)N�,cSsg|]\}}|�d|���qS)�=rC)�.0�k�vrCrCrD�
<listcomp>�sz/AbstractConnection.__repr__.<locals>.<listcomp>�<�>)rP�repr_pieces�	__class__rF)r>�	repr_argsrCrCrD�__repr__�szAbstractConnection.__repr__cC�dSrKrC�r>rCrCrDr���zAbstractConnection.repr_piecescCs$z|��WdStyYdSwrK)�
disconnect�	Exceptionr�rCrCrD�__del__�s
�zAbstractConnection.__del__cCs&|dur|Strt�St|j|jj�SrK)r$r-rIrLr{r5)r>�packerrCrCrDr��s
z,AbstractConnection._construct_command_packercCs(t�|�}||jvr|j�|�dSdSrK)�weakref�
WeakMethodrr7)r>�callback�wmrCrCrD�_register_connect_callback�s

�z-AbstractConnection._register_connect_callbackcCs.z|j�t�|��WdStyYdSwrK)r�remover�r�r�)r>r�rCrCrD�_deregister_connect_callback�s
�z/AbstractConnection._deregister_connect_callbackcCs||jd�|_dS)z�
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rfN)r}�_parser)r>r�rCrCrDr~�szAbstractConnection.set_parserc
s��jrdSz�j��fdd��fdd��}Wntjy"td��ty4}zt��|���d}~ww|�_z�j	durC��
�n��	��WntyU����wdd��j
D��_
�j
D]}|�}|rm|��qbdS)z5Connects to the Redis server if not already connectedNcs���SrK)�_connectrCr�rCrD�<lambda>	sz,AbstractConnection.connect.<locals>.<lambda>cs
��|�SrK�r�)�errorr�rCrDr�	s
zTimeout connecting to servercSsg|]}|�r|�qSrCrC)r��refrCrCrDr� sz.AbstractConnection.connect.<locals>.<listcomp>)r|rl�call_with_retry�socket�timeoutr �OSErrorr�_error_messagerm�
on_connectrr�r)r>�sock�er�r�rCr�rD�connects:���


��
��zAbstractConnection.connectcCr�rKrCr�rCrCrDr�&r�zAbstractConnection._connectcCr�rKrCr�rCrCrD�_host_error*r�zAbstractConnection._host_errorcCr�rKrC)r>�	exceptionrCrCrDr�.r�z!AbstractConnection._error_messagecCst|j�|�|j}d}|js|js|jr"|jpt|j|j�}|��}|r\|jdvr\t|jt	�r?|�
t�|j|j_|j�|�t
|�dkrKd|dg}|jd|jdg|�R�|��}nq|r�|jdg|�Rdd	i�z|��}Wnty�|jd|d
d	d�|��}Ynwt|�dkr�td
��n:|jdvr�t|jt	�r�|�
t�|j|j_|j�|�|�d|j�|��}|�d�|jkr�|�d�|jkr�td��|jr�|�dd|j�t|���dkr�td��z|jr�|�ddd|j�|��Wn	ty�Ynwz|j�r|�ddd|j�|��Wn
t�yYnw|j�r6|�d|j�t|���dk�r8td��dSdS)z=Initialize the connection, authenticate and select a databaseN)r+�2r�defaultr�HELLO�AUTH�check_healthF����r��OKzInvalid Username or Passwordsproto�protozInvalid RESP version�CLIENT�SETNAMEzError setting client name�SETINFOzLIB-NAMEzLIB-VER�SELECTzInvalid Database)r�r�rnrkr_r�get_credentialsror2rr~r�EXCEPTION_CLASSESrR�send_command�
read_responserr'r�getrrhrirrjr^)r>�parser�	auth_args�
cred_provider�response�
auth_responserCrCrDr�2s��


��


�����zAbstractConnection.on_connectcGsx|j��|j}d|_|durdSt��|jkr*z|�tj�Wn	t	y)Ynwz|�
�WdSt	y;YdSw)z!Disconnects from the Redis serverN)r��
on_disconnectr|rrrsrt�shutdownr��	SHUT_RDWRr��close)r>r.�	conn_sockrCrCrDr��s 
��zAbstractConnection.disconnectcCs*|jddd�t|���dkrtd��dS)z Send PING, expect PONG in return�PINGFr��PONGz#Bad response from PING health checkN)r�r'r�rr�rCrCrD�
_send_ping�s�zAbstractConnection._send_pingcC�|��dS)z Function to call when PING failsNr�)r>r�rCrCrD�_ping_failed��zAbstractConnection._ping_failedcCs0|jrt�|jkr|j�|j|j�dSdSdS)z3Check the health of the connection with a PING/PONGN)rgrrzrlr�r�r�r�rCrCrDr��s�zAbstractConnection.check_healthTc
Cs�|js|��|r
|��zt|t�r|g}|D]}|j�|�qWdStjy3|��t	d��t
yg}z)|��t|j�dkrNd|jd}}n
|jd}|jd}t
d|�d|�d���d}~wtyr|���w)	z2Send an already packed command to the Redis serverzTimeout writing to socketr�UNKNOWNr�Error z while writing to socket. �.N)r|r�r�r2r3�sendallr�r�r�r r�rRr.r�
BaseException)r>�commandr��itemr��errno�errmsgrCrCrD�send_packed_command�s2
�

��z&AbstractConnection.send_packed_commandcOs"|j|jj|�|�dd�d�dS)z+Pack and send a command to the Redis serverr�Tr�N)r�r�rEr�)r>r.�kwargsrCrCrDr��s


�zAbstractConnection.send_commandc
Cs`|j}|s	|��|��}z|j�|�WSty/}z|��td|�d|j����d}~ww)z8Poll the socket to see if there's data that can be read.�Error while reading from z: N)	r|r�r�r��can_readr�r�rr.)r>r�r��
host_errorr�rCrCrDr��s��zAbstractConnection.can_read)�disconnect_on_error�push_requestc
Cs�|��}z|jdvrts|jj||d�}n|jj|d�}Wn>tjy2|r+|��td|����t	yN}z|r?|��t
d|�d|j����d}~wty[|rZ|���w|j
rft�|j
|_t|t�rpz|�~w|S)z0Read the response from a previously sent command)�3rq)�disable_decodingr�)r�zTimeout reading from r�z : N)r�ror#r�r�r�r�r�r r�rr.r�rgrrzr2r)r>r�r�r�r�r�r�rCrCrDr��s>	�����
z AbstractConnection.read_responsecGs|jj|�S)r0)r�rE)r>r.rCrCrDr9r�zAbstractConnection.pack_commandc	Cs�g}g}d}|j}|D]B}|jj|�D]9}t|�}||ks&||ks&t|t�r4|r0|�t�|��d}g}||ks=t|t�rC|�|�q|�|�||7}qq|rX|�t�|��|S)z.Pack multiple commands into the Redis protocolr)	rLr�rErRr2rUr7rOrP)	r>�commandsr?�pieces�
buffer_lengthrM�cmd�chunk�chunklenrCrCrD�
pack_commandss.�

�z AbstractConnection.pack_commands�T)r)F)(rFrGrH�__doc__rur,r&r�rr3�float�boolr
rr	rrNr�rr�r�r�r�r�r~r�r�r�r�r�r�r�r�r�r�r�r�r�r9r�rCrCrCrDr[~s��������	�
��
�����
����
�Y
#


Z

��.r[csLeZdZdZ					d�fdd�	Zd	d
�Zdd�Zd
d�Zdd�Z�Z	S)�
Connectionz4Manages TCP communication to and from a Redis server�	localhost��FNrcs<||_t|�|_||_|pi|_||_t�jdi|��dS�NrC)�hostr��port�socket_keepalive�socket_keepalive_options�socket_type�superrN)r>r�r�r�r�r�r��r�rCrDrN7s	

zConnection.__init__cCs6d|jfd|jfd|jfg}|jr|�d|jf�|S)Nr�r�r^rh)r�r�r^rhr7�r>r�rCrCrDr�GszConnection.repr_piecescCsd}t�|j|j|jtj�D]k}|\}}}}}d}zDt�|||�}|�tjtjd�|j	rH|�tj
tjd�|j�
�D]\}	}
|�tj|	|
�q;|�|j�|�|�|�|j�|WStyy}z|}|duro|��WYd}~qd}~ww|dur�|�td��)zCreate a TCP socket connectionNrz)socket.getaddrinfo returned an empty list)r��getaddrinfor�r�r��SOCK_STREAM�
setsockopt�IPPROTO_TCP�TCP_NODELAYr��
SOL_SOCKET�SO_KEEPALIVEr��items�
settimeoutrar�r`r�r�)r>�err�res�family�socktyper��	canonname�socket_addressr�r�r�r@rCrCrDr�Ms4�

��zConnection._connectcCs|j�d|j��S)N�:)r�r�r�rCrCrDr�vszConnection._host_errorcCs�|��}t|j�dkr*z
d|�d|jd�d�WSty)d|jd��YSwzd|jd�d|�d	|jd�d�WStyNd|jd��YSw)
NrzError connecting to z.                         rr�zConnection Error: r�z connecting to �. )r�rRr.�AttributeError�r>r�r�rCrCrDr�ys&
������zConnection._error_message)r�r�FNr�
rFrGrHr�rNr�r�r�r��
__classcell__rCrCr�rDr�4s�)r�csFeZdZdZ												d	�fdd�	Z�fdd�Z�ZS)
�
SSLConnectionz�Manages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    N�requiredFc
s�tstd��||_||_|durtj}nt|t�r1tjtjtj	d�}||vr-td|����||}||_
||_||_||_
||_||_|	|_|
|_||_||_t�jdi|
��dS)aeConstructor

        Args:
            ssl_keyfile: Path to an ssl private key. Defaults to None.
            ssl_certfile: Path to an ssl certificate. Defaults to None.
            ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required). Defaults to "required".
            ssl_ca_certs: The path to a file of concatenated CA certificates in PEM format. Defaults to None.
            ssl_ca_data: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates.
            ssl_check_hostname: If set, match the hostname during the SSL handshake. Defaults to False.
            ssl_ca_path: The path to a directory containing several CA certificates in PEM format. Defaults to None.
            ssl_password: Password for unlocking an encrypted private key. Defaults to None.

            ssl_validate_ocsp: If set, perform a full ocsp validation (i.e not a stapled verification)
            ssl_validate_ocsp_stapled: If set, perform a validation on a stapled ocsp response
            ssl_ocsp_context: A fully initialized OpenSSL.SSL.Context object to be used in verifying the ssl_ocsp_expected_cert
            ssl_ocsp_expected_cert: A PEM armoured string containing the expected certificate to be returned from the ocsp verification service.

        Raises:
            RedisError
        z$Python wasn't built with SSL supportN)�none�optionalrz+Invalid SSL Certificate Requirements Flag: rC)r%r�keyfile�certfile�ssl�	CERT_NONEr2r3�
CERT_OPTIONAL�
CERT_REQUIRED�	cert_reqs�ca_certs�ca_data�ca_path�check_hostname�certificate_password�ssl_validate_ocsp�ssl_validate_ocsp_stapled�ssl_ocsp_context�ssl_ocsp_expected_certr�rN)r>�ssl_keyfile�ssl_certfile�
ssl_cert_reqs�ssl_ca_certs�ssl_ca_data�ssl_check_hostname�ssl_ca_path�ssl_passwordr"r#r$r%r��	CERT_REQSr�rCrDrN�s6$
��zSSLConnection.__init__c
s�t���}t��}|j|_|j|_|js|jr"|j	|j|j|j
d�|jdus1|jdus1|j
dur<|j|j|j|j
d�|j||jd�}|jdurQtdurQtd��|jr[|jr[td��|jr�d	dl}d
dlm}|jdur�|j�|jj�}|�|j�|�|j�n|j}|�||j�|j� |t!�!��}|�"�|�#|j|j$f�|�%�|�&�|S|jdur�tr�d
dlm'}|||j|j$|j�}	|	�(�r�|St)d
��|S)z Wrap the socket with SSL support)rrr_N)�cafile�capath�cadata)�server_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.rr)�ocsp_staple_verifier)�OCSPVerifierzocsp validation error)*r�r�r�create_default_contextr r�verify_moderr�load_cert_chainr!rrr�load_verify_locations�wrap_socketr�r"r"rr#�OpenSSL�ocspr3r$�SSL�Context�
SSLv23_METHOD�use_certificate_file�use_privatekey_file�set_ocsp_client_callbackr%r�r��request_ocspr�r��do_handshaker�r4�is_validr)
r>r��context�sslsockr:r3�
staple_ctx�conr4�or�rCrDr��s^
�


��
�zSSLConnection._connect)NNrNNFNNFFNN)rFrGrHr�rNr�rrCrCr�rDr�s �BrcsBeZdZdZd�fdd�	Zdd�Zdd	�Zd
d�Zdd
�Z�Z	S)�UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server�Ncs"||_||_t�jdi|��dSr�)�pathr`r�rN)r>rLr`r�r�rCrDrNsz#UnixDomainSocketConnection.__init__cCs.d|jfd|jfg}|jr|�d|jf�|S)NrLr^rh)rLr^rhr7r�rCrCrDr�#sz&UnixDomainSocketConnection.repr_piecescCs8t�tjtj�}|�|j�|�|j�|�|j�|S)z&Create a Unix domain socket connection)r��AF_UNIXr�rrar�rLr`)r>r�rCrCrDr�)s
z#UnixDomainSocketConnection._connectcCs|jSrK)rLr�rCrCrDr�1sz&UnixDomainSocketConnection._host_errorcCsR|��}t|j�dkrd|�d|jd�d�Sd|jd�d|�d|jd�d�S)Nrz!Error connecting to unix socket: r
rr�r�z connecting to unix socket: )r�rRr.rrCrCrDr�4s����z)UnixDomainSocketConnection._error_message)rKNrrCrCr�rDrJsrJ)�0�F�FALSE�N�NOcCs6|dus|dkr
dSt|t�r|��tvrdSt|�S)NrKF)r2r3�upper�
FALSE_STRINGSr�)rArCrCrD�to_boolFs
rU)	r^r`rar�rbrv�max_connectionsrgr+c
Cs�|�d�s|�d�s|�d�std��t|�}i}t|j���D]7\}}|rWt|�dkrWt|d�}t�	|�}|rSz||�||<Wq t
tfyRtd|�d���w|||<q |jrbt|j�|d<|jrlt|j�|d	<|j
d
kr�|jr{t|j�|d<t|d<|S|jr�t|j�|d
<|jr�t|j�|d<|jr�d|vr�ztt|j��dd��|d<Wnttfy�Ynw|j
dkr�t|d<|S)Nzredis://z	rediss://zunix://zRRedis URL must specify one of the following schemes (redis://, rediss://, unix://)rzInvalid value for `z` in connection URL.rkr_�unixrL�connection_classr�r�r^�/rK�rediss)�
startswithr�rr�queryrrRr�URL_QUERY_ARGUMENT_PARSERSr�r:rkr_�schemerLrJ�hostnamer�r��replacerr)�urlr��namerAr�rCrCrD�	parse_url[sZ����
��
��
rcc@s�eZdZdZedd��Zedfdeefdd�Z	de
e
ffd	d
�Zd&dd�Zd&d
d�Z
de
ddfdd�Zdefdd�Zd'dd�Zd(dd�Zdddefdd�Zd)deddfdd�Zd&d d!�Zd*d$d%�ZdS)+�ConnectionPoola�
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.exceptions.ConnectionError` when the pool's
    limit is reached.

    By default, TCP connections are created unless ``connection_class``
    is specified. Use class:`.UnixDomainSocketConnection` for
    unix sockets.

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    cKs4t|�}d|vr|d|d<|�|�|di|��S)a
        Return a connection pool configured from the given URL.

        For example::

            redis://[[username]:[password]]@localhost:6379/0
            rediss://[[username]:[password]]@localhost:6379/0
            unix://[username@]/path/to/socket.sock?db=0[&password=password]

        Three URL schemes are supported:

        - `redis://` creates a TCP socket connection. See more at:
          <https://www.iana.org/assignments/uri-schemes/prov/redis>
        - `rediss://` creates a SSL wrapped TCP socket connection. See more at:
          <https://www.iana.org/assignments/uri-schemes/prov/rediss>
        - ``unix://``: creates a Unix Domain Socket connection.

        The username, password, hostname, path and all querystring values
        are passed through urllib.parse.unquote in order to replace any
        percent-encoded values with their corresponding characters.

        There are several ways to specify a database number. The first value
        found will be used:

            1. A ``db`` querystring option, e.g. redis://localhost?db=0
            2. If using the redis:// or rediss:// schemes, the path argument
               of the url, e.g. redis://localhost/0
            3. A ``db`` keyword argument to this function.

        If none of these options are specified, the default db=0 is used.

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        rXNrC)rc�update)�clsrar��url_optionsrCrCrD�from_url�s
)
zConnectionPool.from_urlNrVcKsJ|pd}t|t�r
|dkrtd��||_||_||_t��|_|�	�dS)Nlrz,"max_connections" must be a positive integer)
r2r�r�rX�connection_kwargsrV�	threading�Lock�
_fork_lock�reset)r>rXrVrirCrCrDrN�s

zConnectionPool.__init__rJcCs(t|�j�dt|jdi|j����d�S)Nr�r�rC)�typerF�reprrXrir�rCrCrDr��s��zConnectionPool.__repr__cCs,t��|_d|_g|_t�|_t��|_	dS)Nr)
rjrk�_lock�_created_connections�_available_connections�set�_in_use_connectionsrrrsrtr�rCrCrDrm�s

zConnectionPool.resetcCsl|jt��kr4|jjdd�}|st�z|jt��kr&|��W|j��dSW|j��dS|j��wdS)N�)r�)rtrrrsrl�acquirerrm�release)r>�acquiredrCrCrD�	_checkpids#
��zConnectionPool._checkpid�command_namer�c	Os�|��|j�#z|j��}Wn
ty|��}Ynw|j�|�Wd�n1s-wYz.|��z|�	�r@t
d��WW|St
tfy`|��|��|�	�r\t
d��YW|Swt
ym|�|��w)zGet a connection from the poolN�Connection has data�Connection not ready)ryrprr�pop�
IndexError�make_connectionrt�addr�r�rr�r�r�rw�r>rz�keys�options�
connectionrCrCrD�get_connection2s8���
���
�zConnectionPool.get_connectioncCs,|j}t|�dd�|�dd�|�dd�d�S)z,Return an encoder based on encoding settingsrcr\rdr]reF)rcrdre)rirr�)r>r�rCrCrD�get_encoderSs


�zConnectionPool.get_encodercCs4|j|jkr
td��|jd7_|jdi|j��S)zCreate a new connectionzToo many connectionsrNrC)rqrVrrXrir�rCrCrDr\szConnectionPool.make_connectionr�c	Cs�|��|j�;z|j�|�Wn	tyYnw|�|�r&|j�|�n|jd8_|�	�	Wd�dSWd�dS1sEwYdS)z(Releases the connection back to the poolrN)
ryrprtr��KeyError�owns_connectionrrr7rqr��r>r�rCrCrDrwcs�
�	"�zConnectionPool.releasecCs|j|jkSrK)rtr�rCrCrDr�xszConnectionPool.owns_connectionT�inuse_connectionscCs`|��|j�|rt|j|j�}n|j}|D]}|��qWd�dS1s)wYdS)z�
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other threads. Otherwise only disconnect
        connections that are idle in the pool.
        N)ryrprrrrtr�)r>r��connectionsr�rCrCrDr�{s�
�"�zConnectionPool.disconnectcCr�)z-Close the pool, disconnecting all connectionsNr�r�rCrCrDr��r�zConnectionPool.closerlr!cCs8|j�d|i�|jD]}||_q|jD]}||_qdS)Nrl)rirerrrlrt)r>rl�connrCrCrD�	set_retry�s

�zConnectionPool.set_retryrZ)rJr�)r�r�rJNr�)rlr!rJN)rFrGrHr��classmethodrhr�rr�rNr3r�rmryr�rr�rrwr�r�r�r�r�rCrCrCrDrd�s(
2�
�

/!
	

rdcsReZdZdZddeef�fdd�	Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Z�ZS)�BlockingConnectionPoola
    Thread-safe blocking connection pool::

        >>> from redis.client import Redis
        >>> client = Redis(connection_pool=BlockingConnectionPool())

    It performs the same function as the default
    :py:class:`~redis.ConnectionPool` implementation, in that,
    it maintains a pool of reusable connections that can be shared by
    multiple redis clients (safely across threads if required).

    The difference is that, in the event that a client tries to get a
    connection from the pool when all of connections are in use, rather than
    raising a :py:class:`~redis.ConnectionError` (as the default
    :py:class:`~redis.ConnectionPool` implementation does), it
    makes the client wait ("blocks") for a specified number of seconds until
    a connection becomes available.

    Use ``max_connections`` to increase / decrease the pool size::

        >>> pool = BlockingConnectionPool(max_connections=10)

    Use ``timeout`` to tell it either how many seconds to wait for a connection
    to become available, or to block forever:

        >>> # Block forever.
        >>> pool = BlockingConnectionPool(timeout=None)

        >>> # Raise a ``ConnectionError`` after five seconds if a connection is
        >>> # not available.
        >>> pool = BlockingConnectionPool(timeout=5)
    �2�cs(||_||_t�jd||d�|��dS)N)rXrVrC)�queue_classr�r�rN)r>rVr�rXr�rir�rCrDrN�s�
�zBlockingConnectionPool.__init__cCsJ|�|j�|_	z|j�d�Wn	tyYnwqg|_t��|_dSrK)	r�rV�pool�
put_nowaitr�_connectionsrrrsrtr�rCrCrDrm�s��zBlockingConnectionPool.resetcCs"|jdi|j��}|j�|�|S)zMake a fresh connection.NrC)rXrir�r7r�rCrCrDr�sz&BlockingConnectionPool.make_connectionc	Os�|��d}z|jjd|jd�}Wntytd��w|dur%|��}z.|��z|��r3td��WW|Stt	fyS|�
�|��|��rOtd��YW|Swty`|�|��w)a7
        Get a connection, blocking for ``self.timeout`` until a connection
        is available from the pool.

        If the connection returned is ``None`` then creates a new connection.
        Because we use a last-in first-out queue, the existing connections
        (having been returned to the pool after the initial ``None`` values
        were added) will be returned before ``None`` values. This means we only
        create new connections when we need to, i.e.: the actual number of
        connections will only increase in response to demand.
        NT)�blockr�zNo connection available.r{r|)
ryr�r�r�rrrr�r�r�r�r�rwr�rCrCrDr��s8
�����
�z%BlockingConnectionPool.get_connectioncCsR|��|�|�s|��|j�d�dSz	|j�|�WdSty(YdSw)z)Releases the connection back to the pool.N)ryr�r�r�r�rr�rCrCrDrws
�zBlockingConnectionPool.releasecCs |��|jD]}|��qdS)z(Disconnects all connections in the pool.N)ryr�r�r�rCrCrDr�4s

�z!BlockingConnectionPool.disconnect)
rFrGrHr�r�rrNrmrr�rwr�rrCrCr�rDr��s#�4r�)Prwrrr�rr;rjr��abcr�	itertoolsr�queuerrrr�typingrr	r
rrr
�urllib.parserrr�_parsersrrrr�backoffr�credentialsrr�
exceptionsrrrrrrrr rlr!�utilsr"r#r$r%r&r'r8rQrVrSrOr��objectru�__annotations__r,r-rIr[r�rrJrTrUr�r��listr]rcrdr�rCrCrCrD�<module>st
 (
 	39[
(	�
9