
    Pfk                        U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZmZmZmZmZmZ d dlmZmZmZ dd	lmZmZmZmZ dd
l m!Z! ddl"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 e2rd dl8Z8dZ9dZ:dZ;dZ<dZ= e>            Z?eeeeef                  e@d<   e2reZAneZA G d d          ZB G d d          ZC G d d          ZD G d deD          ZE G d deE          ZF G d d eD          ZGd!ZHd" ZIeJeKeKeIeIeLeJeJeIeKd#
ZMd$ ZN G d% d&          ZO G d' d(eO          ZPdS ))    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format_error_messageget_lib_versionstr_if_bytes   *   $s   
       DefaultParserc                       e Zd ZdefdZdS )HiredisRespSerializerargsc                 "   g }t          |d         t                    rEt          |d                                                                                   |dd         z   }n<d|d         v r2t          |d                                                   |dd         z   }	 |                    t          j        |                     nG# t          $ r: t          j
                    \  }}}t          |                              |          w xY w|S 2Pack a series of arguments into the Redis protocolr   r   N    )
isinstancestrtupleencodesplitappendhiredispack_command	TypeErrorsysexc_infor   with_traceback)selfr1   output_value	tracebacks         B/var/www/html/env/lib/python3.11/site-packages/redis/connection.pypackzHiredisRespSerializer.pack;   s    d1gs## 	5a))//1122T!""X=DDT!W__a))DH4D	=MM'.t445555 	= 	= 	="%,..AuiE""11)<<<	= s    'C ADN)__name__
__module____qualname__r   rH    r,   rG   r0   r0   :   s/        $      r,   r0   c                       e Zd ZddZd ZdS )PythonRespSerializerreturnNc                 "    || _         || _        d S N)_buffer_cutoffr9   )rB   buffer_cutoffr9   s      rG   __init__zPythonRespSerializer.__init__M   s    +r,   c           	      \   g }t          |d         t                    rEt          |d                                                                                   |dd         z   }n<d|d         v r2t          |d                                                   |dd         z   }t
                              t          t          t          |                                                    t          f          }| j
        }t          | j        |          D ]}t          |          }t          |          |k    s||k    st          |t                    ryt
                              |t          t          |                                          t          f          }|                    |           |                    |           t          }t
                              |t          t          |                                          t          |t          f          }	|                    |           |S r3   )r6   r7   r8   r9   r:   	SYM_EMPTYjoinSYM_STARlenSYM_CRLFrR   map
memoryview
SYM_DOLLARr;   )rB   r1   rC   buffrS   arg
arg_lengths          rG   rH   zPythonRespSerializer.packQ   s    d1gs## 	5a))//1122T!""X=DDT!W__a))DH4D~~xSYY)>)>)@)@(KLL+t{D)) 	 	C SJD		M))--c:.. . !~~:s:'='='?'?J  d###c""" ~~"J..00  	 	 	dr,   rO   N)rI   rJ   rK   rT   rH   rL   r,   rG   rN   rN   L   s7           + + + + +r,   rN   c            *          e Zd ZdZdddddedddedddd e            ddddd	dfd
edee	         dee
         dee
         dede	de	dedededee	         dee	         dee	         dee	         deedf         deeg df                  dee         dee         deeg df                  f&dZd Zed             Zd  Zd! Zd" Zd# Zd$ Zd% Zed&             Zed'             Zd( Zd) Zd* Zd+ Zd, Z d- Z!d6d/Z"d0 Z#d7d1Z$	 d8d.dd2d3Z%d4 Z&d5 Z'dS )9AbstractConnectionz0Manages communication to and from a Redis serverr   NFutf-8stricti   zredis-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_packerc                 J   |s|r|t          d          t          j                    | _        || _        || _        || _        || _        || _        || _	        || _
        || _        ||}|| _        || _        |t          u rg }|r|                    t                      || _        |s|rX|"t%          t'                      d          | _        nt+          j        |          | _        | j                            |           n!t%          t'                      d          | _        || _        d| _        || _        t7          |||	          | _        d| _        || _        |                     |
           g | _         d| _!        	 tE          |          }n/# tF          $ r
 tH          }Y ntJ          $ r tM          d          w xY w|dk     s|dk    rtM          d	          || _'        n'# |dk     s|dk    rtM          d	          || _'        w xY w| (                    |          | _)        dS )
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'r   r   ip  zprotocol must be an integerr-      zprotocol must be either 2 or 3)*r   osgetpidpidrf   rp   rq   rr   rv   rg   rs   rh   ri   rj   SENTINELr;   r!   retry_on_errorr"   r   rt   copydeepcopyupdate_supported_errorsro   next_health_checkru   r   encoder_sock_socket_read_size
set_parser_connect_callbacksrR   intr>   DEFAULT_RESP_VERSION
ValueErrorr   rw   _construct_command_packer_command_packer)rB   rf   rg   rh   ri   rj   r   rk   rl   rm   parser_classrn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ps                          rG   rT   zAbstractConnection.__init__   sl   >  	 	&9&E+   9;;& &#6   ,!)%3"&<# 0X%%N 	0!!,///, 		/N 		/}"9;;22

 "]511
J..~>>>>y{{A..DJ%:"!""4x:JKK
!1%%%"$"
	HAA 	% 	% 	%$AAA 	A 	A 	A!"?@@@	A 1uuA%&FGGGDMM 1uuA%&FGGGDM#==nMMs*    F G" F<!G" #F<<G" "$Hc                     d                     d |                                 D                       }d| j        j         d| j        j         d| dS )N,c                 "    g | ]\  }}| d | S )=rL   ).0kvs      rG   
<listcomp>z/AbstractConnection.__repr__.<locals>.<listcomp>   s&    HHHTQjjQjjHHHr,   <.()>)rW   repr_pieces	__class__rJ   rI   )rB   	repr_argss     rG   __repr__zAbstractConnection.__repr__   sY    HHHHT5E5E5G5GHHHII	V4>,VVt~/FVVVVVVr,   c                     d S rQ   rL   rB   s    rG   r   zAbstractConnection.repr_pieces       r,   c                 R    	 |                                   d S # t          $ r Y d S w xY wrQ   )
disconnect	Exceptionr   s    rG   __del__zAbstractConnection.__del__   s?    	OO 	 	 	DD	s    
&&c                 r    ||S t           rt                      S t          | j        | j        j                  S rQ   )r%   r0   rN   rR   r   r9   )rB   packers     rG   r   z,AbstractConnection._construct_command_packer   s:    M# 	R(***'(;T\=PQQQr,   c                 x    t          j        |          }|| j        vr| j                            |           dS dS )a^  
        Register a callback to be called when the connection is established either
        initially or reconnected.  This allows listeners to issue commands that
        are ephemeral to the connection, for example pub/sub subscription or
        key tracking.  The callback must be a _method_ and will be kept as
        a weak reference.
        N)weakref
WeakMethodr   r;   )rB   callbackwms      rG   register_connect_callbackz,AbstractConnection.register_connect_callback   sG     ))T,,,#**2..... -,r,   c                     	 | j                             t          j        |                     dS # t          $ r Y dS w xY w)z
        De-register a previously registered callback.  It will no-longer receive
        notifications on connection events.  Calling this is not required when the
        listener goes away, since the callbacks are kept as weak methods.
        N)r   remover   r   r   )rB   r   s     rG   deregister_connect_callbackz.AbstractConnection.deregister_connect_callback   sQ    	#**7+=h+G+GHHHHH 	 	 	DD	s   ,0 
>>c                 2     || j                   | _        dS )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
        )rn   N)r   _parser)rB   r   s     rG   r   zAbstractConnection.set_parser  s     $|T5KLLLr,   c                 *     j         rdS 	  j                             fd fd          }nQ# t          j        $ r t          d          t          $ r'}t                               |                    d}~ww xY w| _         	  j	         
                                 n 	                                n## t          $ r                                    w xY wd  j        D              _         j        D ]} |            }|r |            dS )z5Connects to the Redis server if not already connectedNc                  ,                                      S rQ   )_connectr   s   rG   <lambda>z,AbstractConnection.connect.<locals>.<lambda>  s     r,   c                 .                         |           S rQ   r   )errorrB   s    rG   r   z,AbstractConnection.connect.<locals>.<lambda>  s    tu7M7M r,   zTimeout connecting to serverc                 &    g | ]} |            |S rL   rL   )r   refs     rG   r   z.AbstractConnection.connect.<locals>.<listcomp>-  s#    "S"S"S3SSUU"S3"S"S"Sr,   )r   rt   call_with_retrysockettimeoutr!   OSErrorr   _error_messageru   
on_connectr   r   r   )rB   socker   r   s   `    rG   connectzAbstractConnection.connect  sp   : 	F	::--'''')M)M)M)M DD ~ 	? 	? 	?=>>> 	: 	: 	:!$"5"5a"8"8999	: 

	&.!!!! ''--- 	 	 	OO	 #T"S$2I"S"S"S* 	 	CsuuH 	 	s!   !. 'A<"A77A<1B9 9 Cc                     d S rQ   rL   r   s    rG   r   zAbstractConnection._connect3  r   r,   c                     d S rQ   rL   r   s    rG   _host_errorzAbstractConnection._host_error7  r   r,   c                 F    t          |                                 |          S rQ   )r'   r   )rB   	exceptions     rG   r   z!AbstractConnection._error_message;  s    #D$4$4$6$6	BBBr,   c                    | j                             |            | j         }d}| j        s| j        s| j        r5| j        pt          | j        | j                  }|                                }|r| j        dvrt          | j         t                    rE| 
                    t                     |j        | j         _        | j                             |            t          |          dk    r
d|d         g} | j        d| j        dg|R   |                                 }np|r | j        dg|R dd	i 	 |                                 }nB# t           $ r5 |                     d|d
         d	           |                                 }Y nw xY wt#          |          dk    rt%          d          n| j        dvrt          | j         t                    rE| 
                    t                     |j        | j         _        | j                             |            |                     d| j                   |                                 }|                    d          | j        k    r-|                    d          | j        k    rt)          d          | j        rP|                     dd| j                   t#          |                                           dk    rt)          d          	 | j        r1|                     ddd| j                   |                                  n# t.          $ r Y nw xY w	 | j        r1|                     ddd| j                   |                                  n# t.          $ r Y nw xY w| j        rO|                     d| j                   t#          |                                           dk    rt)          d          dS dS )z=Initialize the connection, authenticate and select a databaseN)r-   2r   defaultr   HELLOAUTHcheck_healthFr   OKzInvalid Username or Passwords   protoprotozInvalid RESP versionCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTzInvalid Database)r   r   rv   rs   rg   r   get_credentialsrw   r6   r   r   r   EXCEPTION_CLASSESrY   send_commandread_responser   r)   r   getr   rp   rq   r    rr   rf   )rB   parser	auth_argscred_providerresponseauth_responses         rG   r   zAbstractConnection.on_connect>  s"   %%%	# 	8 	8 	8( T5dmT]SS  &5577I  -	>h66$,55 .---171I.''---9~~""&	!5	Dgt}fIyIIII))++HH
  	> DfEyEEEuEEE5 $ 2 2 4 47 5 5 5
 !!&)B-e!LLL $ 2 2 4 45 M**d22)*HIII 3 ](**$,55 .---171I.''---gt}555))++HX&&$-77LL))T]::%&<===  	Ch	43CDDDD..0011T99%&ABBB	} %!!(Iz4=QQQ""$$$ 	 	 	D		 %!!(Iy$BRSSS""$$$ 	 	 	D	 7 	:h000D..0011T99%&8999	: 	:99s6   4E	 	<FF(8L! !
L.-L.28M+ +
M87M8c                 P   | j                                          | j        }d| _        |dS t          j                    | j        k    r8	 |                    t          j                   n# t          t          f$ r Y nw xY w	 |                                 dS # t          $ r Y dS w xY w)z!Disconnects from the Redis serverN)r   on_disconnectr   r{   r|   r}   shutdownr   	SHUT_RDWRr   r>   close)rB   r1   	conn_socks      rG   r   zAbstractConnection.disconnect  s    ""$$$J	
F9;;$(""""6#34444Y'   	OO 	 	 	DD	s$   	A) )A=<A=B 
B%$B%c                     |                      dd           t          |                                           dk    rt          d          dS )z Send PING, expect PONG in returnPINGFr   PONGz#Bad response from PING health checkN)r   r)   r   r   r   s    rG   
_send_pingzAbstractConnection._send_ping  sQ    &u555**,,--77!"GHHH 87r,   c                 .    |                                   dS )z Function to call when PING failsNr   )rB   r   s     rG   _ping_failedzAbstractConnection._ping_failed      r,   c                     | j         r>t                      | j        k    r)| j                            | j        | j                   dS dS dS )z3Check the health of the connection with a PING/PONGN)ro   r   r   rt   r   r   r   r   s    rG   r   zAbstractConnection.check_health  sT    % 	K$&&43I*I*IJ&&t8IJJJJJ	K 	K*I*Ir,   Tc                 r   | j         s|                                  |r|                                  	 t          |t                    r|g}|D ]}| j                             |           dS # t          j        $ r$ |                                  t          d          t          $ rq}|                                  t          |j                  dk    rd|j        d         }}n|j        d         }|j        d         }t          d| d| d          d}~wt          $ r |                                   w xY w)	z2Send an already packed command to the Redis serverzTimeout writing to socketr   UNKNOWNr   zError z while writing to socket. r   N)r   r   r   r6   r7   sendallr   r   r   r!   r   rY   r1   r   BaseException)rB   commandr   itemr   errnoerrmsgs          rG   send_packed_commandz&AbstractConnection.send_packed_command  sk   z 	LLNNN 	 	'3'' $") ) )
""4(((() )~ 	< 	< 	<OO:;;; 	W 	W 	WOO16{{a )16!9vq	!"U5"U"UF"U"U"UVVV 	 	 	
 OO	s   7A, ,;D6'A,D#D6c                 v    |                       | j        j        | |                    dd                     dS )z+Pack and send a command to the Redis serverr   Tr   N)r   r   rH   r   )rB   r1   kwargss      rG   r   zAbstractConnection.send_command  sJ      %D %t,ND99 	! 	
 	
 	
 	
 	
r,   c                    | j         }|s|                                  |                                 }	 | j                            |          S # t
          $ r3}|                                  t          d| d|j                   d}~ww xY w)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   r   r1   )rB   r   r   
host_errorr   s        rG   r   zAbstractConnection.can_read  s    z 	LLNNN%%''
	V<((111 	V 	V 	VOO!"Tj"T"TAF"T"TUUU	Vs   A 
B
.BB
)disconnect_on_errorpush_requestc                r   |                                  }	 | j        dv r$t          s| j                            ||          }n| j                            |          }n# t
          j        $ r) |r|                                  t          d|           t          $ r5}|r|                                  t          d| d|j                   d}~wt          $ r |r|                                   w xY w| j        rt                      | j        z   | _        t!          |t"                    r		 |# ~w xY w|S )z0Read the response from a previously sent command)3rz   )disable_decodingr  )r  zTimeout reading from r   z : N)r   rw   r$   r   r   r   r   r   r!   r   r   r1   r   ro   r   r   r6   r    )rB   r  r   r  r   r   r   s          rG   r   z AbstractConnection.read_response  s    %%''
	}((1B(<55%5L 6    <55GW5XX~ 	E 	E 	E" "!!!CzCCDDD 	 	 	" "!!!!GJGGqvGG    	 	 	 # "!!!	 % 	I%)VVd.H%HD"h.. 	s%   AA A C40C%C4/D1 1D4c                       | j         j        | S )r4   )r   rH   )rB   r1   s     rG   r=   zAbstractConnection.pack_command  s    (t#($//r,   c                    g }g }d}| j         }|D ]} | j        j        | D ]}t          |          }||k    s||k    st	          |t
                    r3|r-|                    t                              |                     d}g }||k    st	          |t
                    r|                    |           |                    |           ||z  }|r-|                    t                              |                     |S )z.Pack multiple commands into the Redis protocolr   )	rR   r   rH   rY   r6   r\   r;   rV   rW   )	rB   commandsrC   piecesbuffer_lengthrS   cmdchunkchunklens	            rG   pack_commandsz AbstractConnection.pack_commands!  s(   + 	. 	.C2-2C8 . .u::!M11-//!%44 0  >innV&<&<===$%MFm++z%/L/L+MM%((((MM%(((!X-MM!.$  	2MM)..00111r,   T)r   )F)(rI   rJ   rK   __doc__r~   r.   r(   r   r   r7   floatboolr   r	   r
   r   rT   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r=   r  rL   r,   rG   rc   rc      sd       66 "&*.26!&'!&" %%&%)",%4_%6%6"&"&;?<@"#7;-WN WNWN 3-WN !	WN
 !)WN WN WN WN WN WN  #WN c]WN 3-WN  c]!WN" 3-#WN$ S$Y%WN& %Xb$h%78'WN( &&89)WN* 3-+WN, !"d(!34-WN WN WN WNrW W W   ^  R R R
/ 
/ 
/	 	 	M M M! ! !F   ^   ^C C CX: X: X:t  (I I I  K K K
   >
 
 
V V V V  , !, , , , ,\0 0 0    r,   rc   c                   @     e Zd ZdZ	 	 	 	 	 d fd	Zd Zd	 Zd
 Z xZS )
Connectionz4Manages TCP communication to and from a Redis server	localhost  FNr   c                     || _         t          |          | _        || _        |pi | _        || _         t                      j        di | d S NrL   )hostr   portsocket_keepalivesocket_keepalive_optionssocket_typesuperrT   )rB   r  r  r  r  r  r   r   s          rG   rT   zConnection.__init__C  sY     	II	 0(@(FB%&""6"""""r,   c                     d| j         fd| j        fd| j        fg}| j        r|                    d| j        f           |S )Nr  r  rf   rp   )r  r  rf   rp   r;   rB   r  s     rG   r   zConnection.repr_piecesS  sL    49%	':T47OL 	=MM=$*:;<<<r,   c                    d}t          j        | j        | j        | j        t           j                  D ]<}|\  }}}}}d}	 t          j         |||          }|                    t           j        t           j        d           | j	        rk|                    t           j
        t           j        d           | j                                        D ]&\  }	}
|                    t           j        |	|
           '|                    | j                   |                    |           |                    | j                   |c S # t$          $ r#}|}||                                 Y d}~6d}~ww xY w||t%          d          )zCreate a TCP socket connectionNr   z)socket.getaddrinfo returned an empty list)r   getaddrinfor  r  r  SOCK_STREAM
setsockoptIPPROTO_TCPTCP_NODELAYr  
SOL_SOCKETSO_KEEPALIVEr  items
settimeoutri   r   rh   r   r   )rB   errresfamilysocktyper   	canonnamesocket_addressr   r   r   rD   s               rG   r   zConnection._connectY  s   
 %Ity$"2F4F
 
 	! 	!C BE>FHeYD!}VXu== 2F4FJJJ ( BOOF$5v7JANNN $ = C C E E B B1(:AqAAAA  ;<<< ^,,,  3444 ! ! !#JJLLL!
 ?IABBBs   C=E
E.E))E.c                 $    | j          d| j         S )N:)r  r  r   s    rG   r   zConnection._host_error  s    )))di)))r,   )r  r  FNr   	rI   rJ   rK   r  rT   r   r   r   __classcell__r   s   @rG   r  r  @  s        :: !%# # # # # #   'C 'C 'CR* * * * * * *r,   r  c                   J     e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd	Z fdZ xZS )SSLConnectionzManages 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                    t           st          d          || _        || _        |t          j        }nWt          |t                    rBt          j        t          j        t          j	        d}||vrt          d|           ||         }|| _
        || _        || _        || _        || _        || _        |	| _        |
| _        || _        || _        || _        || _         t-                      j        di | dS )a  Constructor

        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.
            ssl_min_version: The lowest supported SSL version. It affects the supported SSL versions of the SSLContext. None leaves the default provided by ssl module.
            ssl_ciphers: A string listing the ciphers that are allowed to be used. Defaults to None, which means that the default ciphers are used. See https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_ciphers for more information.

        Raises:
            RedisError
        z$Python wasn't built with SSL supportN)noneoptionalr7  z+Invalid SSL Certificate Requirements Flag: rL   )r&   r   keyfilecertfilessl	CERT_NONEr6   r7   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_certssl_min_versionssl_ciphersr  rT   )rB   ssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_ca_datassl_check_hostnamessl_ca_pathssl_passwordrG  rH  rI  rJ  rK  rL  r   	CERT_REQSr   s                    rG   rT   zSSLConnection.__init__  s   P  	ECDDD"$ MMMs++ 
	5-- I
 I-- Q-QQ   &m4M&$""0$0!!2)B& 0&<#.&""6"""""r,   c                    t                                                      }t          j                    }| j        |_        | j        |_        | j        s| j        r'|	                    | j        | j        | j
                   | j        | j        | j        '|                    | j        | j        | j                   | j        | j        |_        | j        r|                    | j                   |                    || j                  }| j        du rt,          du rt/          d          | j        r| j        rt/          d          | j        rd	dl}d
dlm} | j        Y|j                            |j        j                  }|                     | j                   |!                    | j                   n| j        }|"                    || j#                   |j        $                    |tK          j%                              }|&                                 |'                    | j        | j(        f           |)                                 |*                                 |S | j        du rOt,          rHd
dlm+}  ||| j        | j(        | j                  }	|	,                                r|S t[          d          |S )z Wrap the socket with SSL support)r<  r;  rg   N)cafilecapathcadata)server_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.r   r   )ocsp_staple_verifier)OCSPVerifierzocsp validation error).r  r   r=  create_default_contextrE  rA  verify_moder<  r;  load_cert_chainrF  rB  rD  rC  load_verify_locationsrK  minimum_versionrL  set_cipherswrap_socketr  rG  r#   r   rH  OpenSSLocspr[  rI  SSLContextSSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackrJ  r  r   request_ocspr   r  do_handshaker   r\  is_validr   )rB   r   contextsslsockrd  r[  
staple_ctxconr\  or   s             rG   r   zSSLConnection._connect  s   ww!!,..!%!4"n= 	DL 	##2 $    M%|'|'))}T\$, *    +&*&:G# 	2 0111%%dDI%FF!T)).D.M.M=>>>) 	d.D 	   ) 	NNN222222 $,$[001JKK
//>>>..t|<<<<!2
//$d&A  
 +((V]__EECKKDI.///LLNNNN !T)).D)******WdiDMJJAzz|| ?%&=>>>r,   )NNr7  NNFNNFFNNNN)rI   rJ   rK   r  rT   r   r3  r4  s   @rG   r6  r6    s            "'#F# F# F# F# F# F#PE E E E E E E E Er,   r6  c                   6     e Zd ZdZd fd	Zd Zd Zd Z xZS )	UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server Nc                 V     t                      j        di | || _        || _        d S r  )r  rT   pathrh   )rB   rx  rh   r   r   s       rG   rT   z#UnixDomainSocketConnection.__init__  s5    ""6"""	,r,   c                 p    d| j         fd| j        fg}| j        r|                    d| j        f           |S )Nrx  rf   rp   )rx  rf   rp   r;   r  s     rG   r   z&UnixDomainSocketConnection.repr_pieces$  sC    49%dg7 	=MM=$*:;<<<r,   c                     t          j         t           j        t           j                  }|                    | j                   |                    | j                   |                    | j                   |S )z&Create a Unix domain socket connection)r   AF_UNIXr"  r)  ri   r   rx  rh   )rB   r   s     rG   r   z#UnixDomainSocketConnection._connect*  s[    }V^V-?@@3444TY+,,,r,   c                     | j         S rQ   )rx  r   s    rG   r   z&UnixDomainSocketConnection._host_error2  s
    yr,   )rv  Nr2  r4  s   @rG   ru  ru    sp        ::- - - - - -
          r,   ru  )0FFALSENNOc                     | | dk    rd S t          | t                    r|                                 t          v rdS t	          |           S )Nrv  F)r6   r7   upperFALSE_STRINGSr  )rE   s    rG   to_boolr  9  sI    }t% %++--="@"@u;;r,   )
rf   rh   ri   r  rj   r   max_connectionsro   rR  r   c                 \   |                      d          s9|                      d          s$|                      d          st          d          t          |           } i }t          | j                                                  D ]\  }}|rt          |          dk    rnt          |d                   }t          	                    |          }|r8	  ||          ||<   [# t          t          f$ r t          d| d          w xY w|||<   | j        rt          | j                  |d<   | j        rt          | j                  |d	<   | j        d
k    r)| j        rt          | j                  |d<   t          |d<   n| j        rt          | j                  |d<   | j        rt%          | j                  |d<   | j        rUd|vrQ	 t%          t          | j                                      dd                    |d<   n# t(          t          f$ r Y nw xY w| j        dk    r
t*          |d<   |S )Nzredis://z	rediss://zunix://zRRedis URL must specify one of the following schemes (redis://, rediss://, unix://)r   zInvalid value for `z` in connection URL.rs   rg   unixrx  connection_classr  r  rf   /rv  rediss)
startswithr   r   r   queryr(  rY   r   URL_QUERY_ARGUMENT_PARSERSr   r>   rs   rg   schemerx  ru  hostnamer  r   replaceAttributeErrorr6  )urlr   namerE   r   s        rG   	parse_urlr  O  su   z""
>>+&&
 >>)$$

 5
 
 	

 3--CF	**0022 
% 
%e 		%SZZ!^^E!H%%E/33D99F %W#)6%==F4LL!:. W W W$%U4%U%U%UVVVW  %t
| 3$S\22z
| 3$S\22z zV8 	/$SX..F6N%?!"" < 	3$S\22F6N8 	+ ]]F6N 8 	F**"738#4#4#<#<S"#E#EFFt"J/    :!!)6F%&Ms   C!!%D8H   HHc                       e Zd ZdZed             Zedfdee         fdZ	de
e
ffdZddZdd	Zd
e
ddfdZdefdZddZddZdddefdZddeddfdZddZddZdS )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``.
    c                 x    t          |          }d|v r|d         |d<   |                    |            | di |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.
        r  rL   )r  update)clsr  r   url_optionss       rG   from_urlzConnectionPool.from_url  sP    R  nn''.45G.HK*+k"""s}}V}}r,   Nr  c                     |pd}t          |t                    r|dk     rt          d          || _        || _        || _        t          j                    | _        | 	                                 d S )Nl        r   z,"max_connections" must be a positive integer)
r6   r   r   r  connection_kwargsr  	threadingLock
_fork_lockreset)rB   r  r  r  s       rG   rT   zConnectionPool.__init__  st     *2U/3// 	M?Q3F3FKLLL 0!2. $.**

r,   rO   c                     dt          |           j         dt          |           j         dt           | j        di | j                   dS )Nr   r   r   r   rL   )typerJ   rI   reprr  r  r   s    rG   r   zConnectionPool.__repr__  so    JT

% J JT

(; J J*T*DDT-CDDEEJ J J	
r,   c                     t          j                    | _        d| _        g | _        t                      | _        t          j                    | _	        d S )Nr   )
r  r  _lock_created_connections_available_connectionsset_in_use_connectionsr{   r|   r}   r   s    rG   r  zConnectionPool.reset  s@    ^%%
$%!&(##&55  9;;r,   c                 Z   | j         t          j                    k    r| j                            d          }|st
          	 | j         t          j                    k    r|                                  | j                                         d S # | j                                         w xY wd S )N   )r   )r}   r{   r|   r  acquirer   r  release)rB   acquireds     rG   	_checkpidzConnectionPool._checkpid  s    F 8ry{{""..q.99H +***8ry{{**JJLLL'')))))'')))) #"s   0B B(command_namer  c                    |                                   | j        5  	 | j                                        }n$# t          $ r |                                 }Y nw xY w| j                            |           ddd           n# 1 swxY w Y   	 |                                 	 |	                                rt          d          nb# t          t          f$ rN |                                 |                                 |	                                rt          d          Y nw xY wn$# t          $ r |                     |            w xY w|S )zGet a connection from the poolNConnection has dataConnection not ready)r  r  r  pop
IndexErrormake_connectionr  addr   r   r   r   r   r   r  rB   r  keysoptions
connections        rG   get_connectionzConnectionPool.get_connection&  s   Z 	5 	54!8<<>>

 4 4 4!1133


4$((444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5	   
B&&(( A)*?@@@A#W- B B B%%'''""$$$&&(( B)*@AAAB BB
  	 	 	 LL$$$		 sb   B8BABABB	BD* ##C D* AD&#D* %D&&D* *!Ec                     | j         }t          |                    dd          |                    dd          |                    dd                    S )z,Return an encoder based on encoding settingsrk   rd   rl   re   rm   F)rk   rl   rm   )r  r   r   )rB   r   s     rG   get_encoderzConnectionPool.get_encoderG  sV    'ZZ
G44"JJ'8(CC#ZZ(:EBB
 
 
 	
r,   c                     | j         | j        k    rt          d          | xj         dz  c_          | j        di | j        S )zCreate a new connectionzToo many connectionsr   rL   )r  r  r   r  r  r   s    rG   r  zConnectionPool.make_connectionP  sR    $(<<<!"8999!!Q&!!$t$>>t'=>>>r,   r  c                    |                                   | j        5  	 | j                            |           n# t          $ r Y nw xY w|                     |          r| j                            |           n2| xj        dz  c_        |	                                 	 ddd           dS 	 ddd           dS # 1 swxY w Y   dS )z(Releases the connection back to the poolr   N)
r  r  r  r   KeyErrorowns_connectionr  r;   r  r   rB   r  s     rG   r  zConnectionPool.releaseW  sI   Z 	 	(//
;;;;    
 ##J// +22:>>>>
 ))Q.))%%'''!	 	 	 	 	 	 	 	 ?	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s2   B99B9
AB9AAB99B= B=c                 "    |j         | j         k    S rQ   )r}   r  s     rG   r  zConnectionPool.owns_connectionl  s    ~))r,   Tinuse_connectionsc                     |                                   | j        5  |rt          | j        | j                  }n| j        }|D ]}|                                 	 ddd           dS # 1 swxY w Y   dS )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)r  r  r   r  r  r   )rB   r  connectionsr  s       rG   r   zConnectionPool.disconnecto  s     	Z 		( 		(  :#/1I  #9) ( (
%%''''(		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		(s   >A((A,/A,c                 .    |                                   dS )z-Close the pool, disconnecting all connectionsNr   r   s    rG   r   zConnectionPool.close  r   r,   rt   r"   c                     | j                             d|i           | j        D ]	}||_        
| j        D ]	}||_        
d S )Nrt   )r  r  r  rt   r  )rB   rt   conns      rG   	set_retryzConnectionPool.set_retry  s^    %%w&6777/ 	 	DDJJ, 	 	DDJJ	 	r,   ra   )rO   r  )r  r  rO   Nr  )rt   r"   rO   N)rI   rJ   rK   r  classmethodr  r  r   r   rT   r7   r   r  r  r  r   r  r  r  r  r  r   r   r  rL   r,   rG   r  r    s         . . [.d $)-  "#   2
3* 
 
 
 
   "-* -* -* -*^3 \    B
W 
 
 
 
? ? ? ?   **, *3 * * * *( (D (D ( ( ( ((        r,   r  c                   J     e Zd ZdZddeef fd	Zd Zd Zd Z	d Z
d	 Z x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      c                 \    || _         || _         t                      j        d||d| d S )N)r  r  rL   )queue_classr   r  rT   )rB   r  r   r  r  r  r   s         rG   rT   zBlockingConnectionPool.__init__  sS     ' 	
-+	
 	
  	
 	
 	
 	
 	
r,   c                     |                      | j                  | _        	 	 | j                            d            n# t          $ r Y nw xY w-g | _        t          j                    | _        d S rQ   )	r  r  pool
put_nowaitr   _connectionsr{   r|   r}   r   s    rG   r  zBlockingConnectionPool.reset  s    $$T%9::			$$T****   	  9;;s   = 
A
	A
c                 ^     | j         di | j        }| j                            |           |S )zMake a fresh connection.rL   )r  r  r  r;   r  s     rG   r  z&BlockingConnectionPool.make_connection  s:    *T*DDT-CDD
  ,,,r,   c                 `   |                                   d}	 | j                            d| j                  }n# t          $ r t          d          w xY w||                                 }	 |                                 	 |                                rt          d          nb# t
          t          f$ rN |
                                 |                                 |                                rt          d          Y nw xY wn$# t          $ r |                     |            w xY w|S )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   zNo connection available.r  r  )r  r  r   r   r   r   r  r   r   r   r   r   r  r  s        rG   r  z%BlockingConnectionPool.get_connection  sz    	 
	>T4<HHJJ 	> 	> 	> ""<===	> --//J	   
B&&(( A)*?@@@A#W- B B B%%'''""$$$&&(( B)*@AAAB BB
  	 	 	LL$$$	
 s:   !: A.D
 #B' &D
 'ADD
 DD
 
!D+c                    |                                   |                     |          s0|                                 | j                            d           dS 	 | j                            |           dS # t
          $ r Y dS w xY w)z)Releases the connection back to the pool.N)r  r  r   r  r  r   r  s     rG   r  zBlockingConnectionPool.release  s     	##J// 	
 !!###I  &&&F	I  ,,,,, 	 	 	 DD	s   A7 7
BBc                 j    |                                   | j        D ]}|                                 dS )z(Disconnects all connections in the pool.N)r  r  r   r  s     rG   r   z!BlockingConnectionPool.disconnect(  sC    + 	$ 	$J!!####	$ 	$r,   )rI   rJ   rK   r  r  r   rT   r  r  r  r  r   r3  r4  s   @rG   r  r    s         F #
 
 
 
 
 
   0  2 2 2h  *$ $ $ $ $ $ $r,   r  )Qr   r{   r   r=  r?   r  r   abcr   	itertoolsr   queuer   r   r   r   typingr	   r
   r   r   r   r   urllib.parser   r   r   _parsersr   r   r   r   backoffr   credentialsr   r   
exceptionsr   r   r   r   r   r   r    r!   rt   r"   utilsr#   r$   r%   r&   r'   r(   r)   r<   rX   r]   rZ   rV   r   objectr~   __annotations__r.   r0   rN   rc   r  r6  ru  r  r  r   r  listr  r  r  r  rL   r,   rG   <module>r     sJ    				  



 



                  ( ( ( ( ( ( ( ( ( (       = = = = = = = = = = = = = = = = 4 4 4 4 4 4 4 4 4 4 I I I I I I I I I I I I       O O O O O O O O	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	                         NNN
	 688E,nDEF F F F !"MM M       $0 0 0 0 0 0 0 0f~ ~ ~ ~ ~ ~ ~ ~BC* C* C* C* C*# C* C* C*LS S S S SJ S S Sl    !3   4 /   # !  6 6 6rD D D D D D D DN]$ ]$ ]$ ]$ ]$^ ]$ ]$ ]$ ]$ ]$r,   