
    Ki                     >   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Zd dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z' dd	l(m)Z) e)rd dl*Z*d d
l*m+Z+m,Z,m-Z- ndZ*dZ,dZ+dZ-ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5 ddl(m6Z6m7Z7 ejp                  dk\  rd dl m9Z: nd dl:m9Z: d dl;m<Z<m=Z=m>Z>m?Z?m@Z@ d dlAmBZB d dlCmDZD d dlEmFZF d dlGmHZHmIZI d dlJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZR d dlSmTZT d dlUmVZV d dlWmXZXmYZY ddlZm[Z[m\Z\m]Z]m^Z^m_Z_ dZ`dZadZbdZcdZd G d  d!ej                        Zfefj                  Zheee^e_e]f      eid"<   eXre]Zjne^Zj G d# d$e      Zk G d% d&e      Zleekelf   Zm G d' d(      Zn G d) d*en      Zo G d+ d,eo      Zp G d- d.      Zq G d/ d0en      Zrd1Zsd2eet   fd3Zud4 Zv eewexexeueueweweuevevexd5      Zyeezed6e{f   f   eid7<    G d8 d9ed:;      Z|d<ezd2e|fd=Z} ed>d?@      Z~ G dA d?      Z G dB dCe      Zy)D    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalProtocolSetTupleType	TypedDictTypeVarUnion)ParseResultparse_qsunquoteurlparse   )DB_CLIENT_CONNECTION_POOL_NAMEDB_CLIENT_CONNECTION_STATEAttributeBuilderConnectionStateget_pool_name)SSL_AVAILABLE)
SSLContext
TLSVersionVerifyFlags)TokenInterface)
DriverInforesolve_driver_info)!AsyncAfterConnectionReleasedEventEventDispatcher)deprecated_argsformat_error_message)      r(   )timeout)record_connection_closedrecord_connection_countrecord_connection_create_timerecord_connection_wait_timerecord_error_count)Retry)	NoBackoff)DEFAULT_RESP_VERSION)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorConnectionError	DataErrorMaxConnectionsError
RedisErrorResponseErrorTimeoutError)CloseReason)
EncodableT)HIREDIS_AVAILABLEstr_if_bytes)
BaseParserEncoder_AsyncHiredisParser_AsyncRESP2Parser_AsyncRESP3Parser   *   $s   
   
    c                       e Zd Z e       Zy)	_SentinelN)__name__
__module____qualname__objectsentinel rI   d/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/redis/asyncio/connection.pyrK   rK   d   s	    xHrI   rK   DefaultParserc                       e Zd ZddZy)ConnectCallbackProtocolc                      y NrQ   self
connections     rR   __call__z ConnectCallbackProtocol.__call__s   s    rI   NrZ   AbstractConnectionrL   rM   rN   r[   rQ   rI   rR   rU   rU   r   s    =rI   rU   c                       e Zd ZddZy)AsyncConnectCallbackProtocolc                    K   y wrW   rQ   rX   s     rR   r[   z%AsyncConnectCallbackProtocol.__call__w   s        Nr\   r^   rQ   rI   rR   r`   r`   v   s    CrI   r`   c            1       <   e Zd ZdZdZ eddgd      ddddd	ed
dd	edddddddddeddddde	e
ef   dee
   dee   dee   dede	eef   de
de
dedee   dededee
   dee
   dee
   dee   dee
   dee   dee   d ee   d!ee   d"ee   d#ee   f.d$       Zefd%efd&Zd' Zd( Zed)        Ze d*        Z!d+ Z"d, Z#dee   d-dfd.Z$d/ Z%	 d[d1ed2efd3Z&d4 Z'd5 Z(d6 Z)ed7        Z*ed-e
fd8       Z+d9e,d-e
fd:Z-d; Z.d\d<Z/d]d1ed-dfd=Z0	 	 	 	 d^d>ed?ee1   d@ee   dAed-df
dBZ2dC Z3dD Z4dE Z5dFe6e7   d-dfdGZ8	 d]dFe	e7e
e6e7   f   d1ed-dfdHZ9dIedJed-dfdKZ:dL Z;	 	 d_d0d	dMdNedOee   dPedQee   fdRZ<dIe=d-e>e7   fdSZ?dTe6e6e=      d-e>e7   fdUZ@dV ZAdW ZBdXeCfdYZDdZ ZEy)`r]   z0Manages communication to and from a Redis server)dbusernameclient_namelib_namelib_versioncredential_providerpasswordsocket_timeoutsocket_connect_timeoutredis_connect_funcretry_on_timeoutretry_on_errorhealth_check_intervalnext_health_checklast_active_atencoderssl_contextprotocol_reader_writer_parser_connect_callbacks_buffer_cutoff_lock_socket_read_size__dict__rg   rh   zbUse 'driver_info' parameter instead. lib_name and lib_version will be removed in a future version.)args_to_warnreasonr   NFutf-8stricti   r   )rd   rj   rk   rl   rn   ro   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizerp   rf   rg   rh   driver_infore   retryrm   encoder_classri   ru   event_dispatcherrd   rj   rk   rl   rn   ro   r   r   r   r   r   rp   rf   r   re   r   rm   r   ri   ru   r   c                   |s|r|t        d      |t               | _        n|| _        || _        || _        t        |||      | _        || _        || _        || _	        || _
        ||}|| _        || _        |t        u rg }|rS|j                  t               |j                  t         j"                         |j                  t$        j                         || _        |s|rR|st)        t+               d      | _        nt/        j0                  |      | _        | j,                  j3                  |       nt)        t+               d      | _        || _        d| _         ||||	      | _        || _        d| _        d| _        || _         | jC                  |
       g | _"        d| _#        d| _$        d| _%        	 tM        |      }|dk  s|d	kD  rtO        d
      || _+        y# tP        $ r tR        }Y || _+        ytT        $ r tO        d      w xY w)ag  
        Initialize a new async Connection.

        Parameters
        ----------
        driver_info : DriverInfo, optional
            Driver metadata for CLIENT SETINFO. If provided, lib_name and lib_version
            are ignored. If not provided, a DriverInfo will be created from lib_name
            and lib_version (or defaults if those are also None).
        lib_name : str, optional
            **Deprecated.** Use driver_info instead. Library name for CLIENT SETINFO.
        lib_version : str, optional
            **Deprecated.** Use driver_info instead. Library version for CLIENT SETINFO.
        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   ip  Fr   r(   zprotocol must be either 2 or 3zprotocol must be an integer),r8   r%   _event_dispatcherrd   rf   r#   r   ri   rj   re   rk   rl   rn   SENTINELappendr<   socketr*   asyncioro   r0   r1   r   copydeepcopyupdate_supported_errorsrp   rq   rs   rm   rv   rw   r|   
set_parserry   rz   _re_auth_token_should_reconnectintr7   	TypeErrorr2   
ValueErrorru   )rY   rd   rj   rk   rl   rn   ro   r   r   r   r   r   rp   rf   rg   rh   r   re   r   rm   r   ri   ru   r   ps                            rR   __init__zAbstractConnection.__init__   s   \ &9&E+  #%4%6D"%5D"& /{HkR#6   ,!)%3"&<# 0X%N!!,/!!&..1!!'"6"67,N"9;2
 "]]51
JJ..~>y{A.DJ%:"(*$X@PQ"47;7;!1%NP"8<!&	HHA 1uA%&FGG  	%$A   	A!"?@@	As   5G H	5H		_warningsc                     t        | dd       rA|j                  d| t        |        	 t        j                          | j                          y y # t        $ r Y y w xY w)Nrw   zunclosed Connection )source)getattrwarnResourceWarningr   get_running_loop_closeRuntimeError)rY   r   s     rR   __del__zAbstractConnection.__del__  sb     4D)NN&th/  ((* *   s   $A 	AAc                 n    | j                   r)| j                   j                          dx| _         | _        yy)zR
        Internal method to silently close the connection without waiting
        N)rw   closerv   rY   s    rR   r   zAbstractConnection._close  s.     <<LL *..DL4< rI   c                     dj                  d | j                         D              }d| j                  j                   d| j                  j                   d| dS )N,c              3   0   K   | ]  \  }}| d |   yw)=NrQ   ).0kvs      rR   	<genexpr>z.AbstractConnection.__repr__.<locals>.<genexpr>&  s     HTQ1QCjHs   <.(z)>)joinrepr_pieces	__class__rM   rL   )rY   	repr_argss     rR   __repr__zAbstractConnection.__repr__%  sQ    HHHT5E5E5GHI	4>>,,-Qt~~/F/F.GqSUVVrI   c                      y rW   rQ   r   s    rR   r   zAbstractConnection.repr_pieces)      rI   c                 >    | j                   d uxr | j                  d uS rW   )rv   rw   r   s    rR   is_connectedzAbstractConnection.is_connected-  s    ||4'DDLL,DDrI   c                     t        j                  |      }|| j                  vr| j                  j                  |       yy)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
WeakMethodry   r   )rY   callbackwms      rR   register_connect_callbackz,AbstractConnection.register_connect_callback1  s;     )T,,,##**2. -rI   c                     	 | j                   j                  t        j                  |             y# t        $ r Y y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)ry   remover   r   r   )rY   r   s     rR   deregister_connect_callbackz.AbstractConnection.deregister_connect_callback=  s8    	##**7+=+=h+GH 		s   .1 	==returnc                 4     || j                         | _        y)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
        )r   N)r|   rx   )rY   r   s     rR   r   zAbstractConnection.set_parserH  s     $T5K5KLrI   c                 j    K    j                   j                   fd fdd       d{    y7 w)z5Connects to the Redis server if not already connectedc                  *     j                  dd      S )NTF)check_healthretry_socket_connect)connect_check_healthr   s   rR   <lambda>z,AbstractConnection.connect.<locals>.<lambda>U  s    D--! .  rI   c                 *    j                  | |      S N)errorfailure_count
disconnect)r   r   rY   s     rR   r   z,AbstractConnection.connect.<locals>.<lambda>X  s    = *9 * rI   Twith_failure_countN)r   call_with_retryr   s   `rR   connectzAbstractConnection.connectP  s9      jj((  $ ) 
 	
 	
s   (313Tr   r   c                    	K    j                   ry d		 fd}	 |r* j                  j                   fd|d       d {    n j                          d {    	  j                  s j!                  |       d {    nIt	        j"                   j                        r j                          d {   n j                           j(                  D cg c]  } |       s| c} _         j(                  D ]4  } |       } |       }|st+        j,                  |      s+| d {    6 y 7 7 # t        j
                  $ r  t        j                  t        j                  f$ rU t        d      }t        t         dd       t         dd       t         dd       t         dd       |	d	
       d {  7   |t        $ rh}t         j                  |            }t        t         dd       t         dd       t         dd       t         dd       |	d	
       d {  7   |d }~wt        $ r}t        |      |d }~ww xY w7 7 # t$        $ r  j'                          d {  7    w xY wc c}w 7 Sw)Nr   c                 .    |j                  | |      S r   r   )r   r   actual_retry_attemptsrY   s     rR   failure_callbackzAAbstractConnection.connect_check_health.<locals>.failure_callbackf  s    $1!??m?LLrI   c                  $     j                         S rW   )_connectr   s   rR   r   z9AbstractConnection.connect_check_health.<locals>.<lambda>n  s    DMMO rI   Tr   zTimeout connecting to serverhostportF)server_addressserver_portnetwork_peer_addressnetwork_peer_port
error_typeretry_attemptsis_internalr   )r   r   r   r   r   CancelledErrorr   r*   r<   r/   r   OSErrorr7   _error_message	Exceptionrm   on_connect_check_healthiscoroutinefunctionr:   r   ry   inspectisawaitable)
rY   r   r   r   eexcrefr   taskr   s
   `        @rR   r   z'AbstractConnection.connect_check_health^  sw      !	M
$	0#jj00+$'+ 1    mmo%%<	**222MMM
 2243J3JK 11$777006 372I2I"S3SU3"S** 	CuHD>D++D1

		q &%% 	 4 45 	;<A$&tVT:#D&$7%,T64%@")$"=4!   G 	 3 3A 67A$&tVT:#D&$7%,T64%@")$"=4!   G 	0!#&C/	0 N 8  	//###	 #T
 s   J	&D? D;D? D=D?  !I I8I :I;I J	J+J/(J	J	.J	3J4J	;D? =D? ?BIGIAH4,H/-H44I IIJ	I I I>6I97I>>	J	c                     d| _         y )NTr   r   s    rR   mark_for_reconnectz%AbstractConnection.mark_for_reconnect  s
    !%rI   c                     | j                   S rW   r   r   s    rR   should_reconnectz#AbstractConnection.should_reconnect  s    %%%rI   c                     d| _         y )NFr   r   s    rR   reset_should_reconnectz)AbstractConnection.reset_should_reconnect  s
    !&rI   c                    K   y wrW   rQ   r   s    rR   r   zAbstractConnection._connect  s	     rb   c                      y rW   rQ   r   s    rR   _host_errorzAbstractConnection._host_error  r   rI   	exceptionc                 6    t        | j                         |      S rW   )r'   r   )rY   r   s     rR   r   z!AbstractConnection._error_message  s    #D$4$4$6	BBrI   c                     | j                   S rW   )ru   r   s    rR   get_protocolzAbstractConnection.get_protocol  s    }}rI   c                 D   K   | j                  d       d{    y7 w)z=Initialize the connection, authenticate and select a databaseTr   N)r   r   s    rR   
on_connectzAbstractConnection.on_connect  s     ***===s     c                 	  K   | j                   j                  |        | j                   }d }| j                  s| j                  s| j                  rF| j                  xs  t        | j                  | j                        }|j                          d {   }|r&| j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        t        |      dk(  rd|d   g} | j                  d| j                  dg|ddi d {    | j                          d {   }|j!                  d	      t#        | j                        k7  r6|j!                  d
      t#        | j                        k7  rt%        d      |rP | j                  dg|ddi d {    	 | j                          d {   }t)        |      dk7  rt+        d      | j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        | j                  d| j                  |       d {    | j                          d {   }| j,                  rV| j                  dd| j,                  |       d {    t)        | j                          d {         dk7  rt%        d      d}d}| j.                  rJ| j.                  j0                  r4| j                  ddd| j.                  j0                  |       d {    d}| j.                  rJ| j.                  j2                  r4| j                  ddd| j.                  j2                  |       d {    d}| j4                  r&| j                  d| j4                  |       d {    t7        t9        ||g            D ]  }		 | j                          d {     | j4                  r0t)        | j                          d {         dk7  rt%        d      y y 7 7 37 7 7 # t&        $ r= | j                  d|d   d       d {  7   | j                          d {  7  }Y w xY w7 *7 7 7 7 d7 7 7 # t:        $ r Y w xY w7 w)N)r   2r   defaultr   HELLOAUTHr   Fs   protoprotozInvalid RESP versionr   r   OKzInvalid Username or PasswordCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMETzLIB-VERSELECTzInvalid Database)rx   r  ri   re   rj   r4   get_credentials_asyncru   
isinstancerD   r   rE   EXCEPTION_CLASSESlensend_commandread_responsegetr   r7   r6   r@   r5   rf   r   formatted_namerh   rd   rangesumr;   )
rY   r   parser	auth_argscred_providerresponseauth_responselib_name_sentlib_version_sent_s
             rR   r   z*AbstractConnection.on_connect_check_health  s    %	##(( T5dmmT]]S  ,AACCI h6$,,(9: 12171I1I.''-9~"&	!5	 $$##1:IN   "//11H||H%T]]);;AT]]#A$ &&<== #$##FKYKUKKK;&*&8&8&: : M*d2)*HII ]](*$,,(9: 12171I1I.''-##GT]]#VVV!//11H ##  )	 $    $"4"4"6674?%&ABB   0 0 ? ?##  //) $    !M 0 0 < <##  ,,) $     $ 77##HdggL#QQQ sM+;<=> 	A((***	 77$"4"4"6674?%&899 @ I D 2 L !;7 ;
 ''	"E'RRR&*&8&8&: : :;$ W1 7 R
 +   7sU  BS6Q7B5S6Q:S6Q= A:S6R S6 R 3R4R 8B-S6%S&S6=S>2S60S1S6SA)S67S8AS6S3S6S!S6 S%3S#4S%8&S6S4S6:S6=S6 S6R #S)R,*SSSS6SS6S6S6S6S6S6!S6#S%%	S1.S60S11S6nowaitr   r   health_check_failedc           
        K   	 t        | j                        4 d{    | j                  j                          | j	                          | j
                  s	 ddd      d{    y	 | j                  j                          |s"| j                  j                          d{    d| _
        d| _        ddd      d{    |r|rt        j                  }nt        j                  }|b|| j                   j#                         kD  rEt%        t'        | dd      t'        | dd      t'        | dd      t'        | dd      ||       d{    t)        ||       d{    yt)        t        j*                         d{    y7 l7 (7 # t        $ r Y w xY w# d| _
        d| _        w xY w7 # 1 d{  7  sw Y   xY w# t        j                  $ r t        d| j                         dw xY w7 7 7 {w)z!Disconnects from the Redis serverNz#Timed out closing connection after r   r   )r   r   r   r   r   r   )close_reasonr   )r&  )async_timeoutrl   rx   on_disconnectr   r   rw   r   wait_closedr   rv   r   r<   r=   HEALTHCHECK_FAILEDERRORr   get_retriesr/   r   r+   APPLICATION_CLOSE)rY   r#  r   r   r$  r&  s         rR   r   zAbstractConnection.disconnect9  s    	$T%@%@A ( (**,++-((( ( (
(LL&&( ""ll66888 $(DL#'DL!( (, "*==*00(]TZZ=S=S=U-U(#*4#> 'fd ;)0vt)D&-dFD&A$#0   +)   
 +(::  W( ( 9  $(DL#'DL!( ( ( (" ## 	5d6Q6Q5RS	
s   HG F	G 8F5G $F%G )H+9F$F%F)F57G F3G BHG;H G=!"HG?H	G G F	FF FF  F00F53G 5G;F><GG -G88H=H?Hc                    K   | j                  dd       d{    t        | j                          d{         dk7  rt        d      y7 47 w)z Send PING, expect PONG in returnPINGFr   NPONGz#Bad response from PING health check)r  r@   r  r7   r   s    rR   
_send_pingzAbstractConnection._send_pingq  sR     U;;;d00223v=!"GHH > 	<2s   AAAAAAc                 H   K   | j                  ||d       d{    y7 w)z Function to call when PING failsT)r   r   r$  Nr   )rY   r   r   s      rR   _ping_failedzAbstractConnection._ping_failedw  s(     oo}$  
 	
 	
s   " "c                    K   | j                   rkt        j                         j                         | j                  kD  r;| j
                  j                  | j                  | j                  d       d{    yyy7 w)z3Check the health of the connection with a PING/PONGTr   N)	rp   r   r   timerq   r   r   r1  r3  r   s    rR   r   zAbstractConnection.check_health}  ss      &&((*//1D4J4JJ**,,!2!2t -    K 's   A1A=3A;4A=commandc                    K   | j                   j                  |       | j                   j                          d {    y 7 wrW   )rw   
writelinesdrain)rY   r6  s     rR   _send_packed_commandz'AbstractConnection._send_packed_command  s.     (ll  """s   9AAAc                   K   | j                   s| j                  d       d {    |r| j                          d {    	 t        |t              r|j                         }t        |t              r|g}| j                  r8t        j                  | j                  |      | j                         d {    y | j                  j                  |       | j                  j                          d {    y 7 7 7 G7 # t        j                  $ r( | j                  d       d {  7   t        d      d t         $ r{}| j                  d       d {  7   t#        |j$                        dk(  rd|j$                  d   }}n|j$                  d   }|j$                  d   }t'        d	| d
| d      |d }~wt(        $ r | j                  d       d {  7    w xY ww)NFr   Tr#  zTimeout writing to socketr   UNKNOWNr   zError z while writing to socket. r   )r   r   r   r  strencodebytesrk   r   wait_forr:  rw   r8  r9  r<   r   r   r  argsr7   BaseException)rY   r6  r   r   err_noerrmsgs         rR   send_packed_commandz&AbstractConnection.send_packed_command  s       +++???##%%%	'3'!..*'5)")""&&--g68K8K   ''0ll((*** @%
 +## 	F///...:;E 		///...166{a!*AFF1I! :6(!D  	
 ///...	s   "G%C9G%C;G%A1D 5C=6D :G%;8D 3C?4D 8G%;G%=D ?D (G")D,*G"F9EA F99!G"GG""G%rB  kwargsc                    K   | j                   | j                  | |j                  dd             d{    y7 w)z+Pack and send a command to the Redis serverr   Tr   N)rF  pack_commandr  )rY   rB  rG  s      rR   r  zAbstractConnection.send_command  s@     &&Dt$6::nd3S ' 
 	
 	
s   4><>c                   K   	 | j                   j                          d{   S 7 # t        $ rK}| j                  d       d{  7   | j	                         }t        d| d|j                         d}~ww xY ww)z8Poll the socket to see if there's data that can be read.NTr<  Error while reading from z: )rx   can_read_destructiver   r   r   r7   rB  )rY   r   
host_errors      rR   rL  z'AbstractConnection.can_read_destructive  su     	V::<<<< 	V///...))+J!$=j\AFF8"TUU	Vs<   A?( &( A?( 	A<A7A	0A77A<<A?)disconnect_on_errorpush_requestdisable_decodingr*   rN  rO  c                  K   ||n| j                   }| j                         }	 |X| j                  dv rJt        |      4 d{    | j                  j                  ||       d{   }ddd      d{    n|It        |      4 d{    | j                  j                  |       d{   }ddd      d{    nX| j                  dv r&| j                  j                  ||       d{   }n$| j                  j                  |       d{   }| j                  r6t        j                         j                         | j                  z   }	|	| _        t#        t$              r|d|S 7 57 7 # 1 d{  7  sw Y   rxY w7 7 7 # 1 d{  7  sw Y   xY w7 7 # t        j                  $ r0 |Y y|r| j                  d       d{  7   t        d|       t        $ r=}|r| j                  d       d{  7   t        d| d	|j                         d}~wt        $ r |r| j                  d       d{  7    w xY ww)
z0Read the response from a previously sent commandN)3r(   )rP  rO  )rP  Tr<  zTimeout reading from rK  z : )rk   r   ru   r'  rx   r  r   r<   r   r   r7   rB  rC  rp   r   r5  rq   r  r;   )
rY   rP  r*   rN  rO  read_timeoutrM  r  r   	next_times
             rR   r  z AbstractConnection.read_response  sj     #*"5w4;N;N%%'
%	'DMMX,E(6  %)\\%?%?)9 &@ &  H   )(6  %)\\%?%?)9 &@ &  H   (*!%!;!;%5L "< "  "&!;!;%5 "< " . %%002779D<V<VVI%.D"h.$W    
    
 ## 	E""ooTo222!6zlCDD 	W"ooTo222!$=j\QVVH"UVV 	 #ooTo222	s%  !I&F6 E8F6 !F(E;)F-F6 8E>9F6 FF6  F3F4F8F6 F3F6 7F28$F6 F4F6 !AI&8F6 ;F>F6 FF
FF6 FF6 F/#F&$F/+F6 4F6 6I#I&I#$G'%I# H8H H88#I#II##I&c           	         g }t        |d   t              rJ t        |d   t              r1t        |d   j	                         j                               |dd z   }n)d|d   v r"t        |d   j                               |dd z   }t        j                  t        t        t        |            j	                         t        f      }| j                  }t        | j                  j                  |      D ]  }t        |      }t        |      |kD  s||kD  st        |t              rat        j                  |t        t        |      j	                         t        f      }|j!                  |       |j!                  |       t        }t        j                  |t        t        |      j	                         t        |t        f      } |j!                  |       |S )z2Pack a series of arguments into the Redis protocolr   r   N    )r  floatr>  tupler?  split	SYM_EMPTYr   SYM_STARr  SYM_CRLFrz   maprs   
memoryview
SYM_DOLLARr   )rY   rB  outputbuffbuffer_cutoffarg
arg_lengths          rR   rI  zAbstractConnection.pack_command  s    d1gu---d1gs#a)//12T!"X=DT!W_a)DH4D~~xSY)>)>)@(KL++t||**D1 	C SJD	M)-c:. ~~:s:'='='?J d#c" ~~"J..0  	!	4 	drI   commandsc                    g }g }d}| j                   }|D ]  } | j                  | D ]  }t        |      }||kD  s||kD  st        |t              r*|r$|j                  t        j                  |             d}g }||kD  st        |t              r|j                  |       y|j                  |       ||z  }  |r$|j                  t        j                  |             |S )z.Pack multiple commands into the Redis protocolr   )rz   rI  r  r  r^  r   rZ  r   )	rY   re  r`  piecesbuffer_lengthrb  cmdchunkchunklens	            rR   pack_commandsz AbstractConnection.pack_commands+  s      ++ 	.C***C0 .u:!M1-/!%4innV&<=$%MFm+z%/LMM%(MM%(!X-M!.	.& MM)..01rI   c                 F    t        | j                  j                        dk(  S )zCheck if the socket is emptyr   )r  rv   _bufferr   s    rR   _socket_is_emptyz#AbstractConnection._socket_is_emptyI  s    4<<''(A--rI   c                    K   | j                         s,| j                  d       d {    | j                         s+y y 7 w)NT)rO  )ro  r  r   s    rR   process_invalidation_messagesz0AbstractConnection.process_invalidation_messagesM  s:     '')$$$$777 '')7s   &AA AAtokenc                     || _         y rW   )r   )rY   rr  s     rR   set_re_auth_tokenz$AbstractConnection.set_re_auth_tokenQ  s
    #rI   c                   K   | j                   l| j                  d| j                   j                  d      | j                   j                                d {    | j	                          d {    d | _         y y 7 %7 wNr
  oid)r   r  try_get	get_valuer  r   s    rR   re_authzAbstractConnection.re_authT  s     *####++E2##--/  
 $$&&&"&D +
 's$   AB A<B .A>/B >B )TTr   NT)FNNF)FN)FrL   rM   rN   __doc__	__slots__r&   r   rS   rB   r   r>  r   r   rW  boollistrK   r   rA   r"   r0   ConnectCallbackTr3   r%   r   warningsr   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   rC  r   r  r  r   r   r   r1  r3  r   r   r@  r:  rF  r  rL  r  r>   r	   rI  rl  ro  rq  r!   rt  rz  rQ   rI   rR   r]   r]   }   s9   :I:  -0H  "&*.26!&19'!&)6 %'(%)"&%),0"&!%9='.<@"#6:3i #s(Oi 3-	i
 !i !)i i dIo.i i i i :&i i  %i c]i  3-!i" c]#i$ j)%i& 3-'i( )i* %%56+i, G}-i. &&89/i0 3-1i2 #?33i
iV (0   /W   E E
/	MtJ'7 MD M
 GKK K?CKZ&&'   S  C C# C>q:$ q:$ q:j %)'+$)66 	"6  }	6
 "6 
6pI
#(5/ #d #
 QU'UC%89'IM'	'R
 
s 
t 
V "'#'8
 %)',88 %8
 "8 tn8t,* ,e ,\hx
/C&D e <.8$~ $'rI   r]   c                        e Zd ZdZddddddded	eeef   d
edee	eeee
f   f      def
 fdZd Zde	fdZd ZdefdZ xZS )
Connectionz4Manages TCP communication to and from a Redis server	localhosti  FNr   )r   r   socket_keepalivesocket_keepalive_optionssocket_typer   r   r  r  r  c                    || _         t        |      | _        || _        |xs i | _        || _        t        |   di | y NrQ   )r   r   r   r  r  r  superr   )rY   r   r   r  r  r  rG  r   s          rR   r   zConnection.__init__b  sD     	I	 0(@(FB%&"6"rI   c                     d| j                   fd| j                  fd| j                  fg}| j                  r|j	                  d| j                  f       |S )Nr   r   rd   rf   )r   r   rd   rf   r   rY   rg  s     rR   r   zConnection.repr_piecess  sM    499%		':T477OLMM=$*:*:;<rI   r   c                 4    | j                   | j                  dS )Nr   r   r  r   s    rR   _connection_argumentsz Connection._connection_argumentsy  s    		49955rI   c                   K   t        | j                        4 d{    t        j                  di | j	                          d{   \  }}ddd      d{    | _        | _        |j                  j                  d      }|r|j                  t        j                  t        j                  d       	 | j                  rs|j                  t        j                  t        j                  d       | j                   j#                         D ]&  \  }}|j                  t        j$                  ||       ( yyy7 7 7 # 1 d{  7  sw Y   xY w# t&        t(        f$ r |j+                           w xY ww)zCreate a TCP socket connectionNr   r   rQ   )r'  rl   r   open_connectionr  rv   rw   	transportget_extra_info
setsockoptr   IPPROTO_TCPTCP_NODELAYr  
SOL_SOCKETSO_KEEPALIVEr  itemsSOL_TCPr   r   r   )rY   readerwritersockr   r   s         rR   r   zConnection._connect|  sE     !<!<= 	 	#*#:#: $,,.$ NFF	 	 ..x8OOF..0B0BAF((OOF$5$5v7J7JAN $ = = C C E >11=> )	 		 	 	 	  Y'  	sp   E;D;E;'ED>EE;E AE;:A>E 8E;>E E;EE	EE;!E88E;c                 8    | j                    d| j                   S )N:r  r   s    rR   r   zConnection._host_error  s    ))Adii[))rI   )rL   rM   rN   r}  r>  r   r   r  r   r
   r@  r   r   r  r   r   __classcell__r   s   @rR   r  r  _  s    :
   $!&NR# # CHo	#
 # #+73c5j8I3I+J"K# #"6w 60*S *rI   r  c                   t    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 ddee   dee   deeej                  f   dee	d      dee	d      dee   d	ee   d
ee   de
dee   dee   dee   f fdZdef fdZed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Ze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)
    ssl_keyfilessl_certfilessl_cert_reqsssl_include_verify_flagsssl.VerifyFlagsssl_exclude_verify_flagsssl_ca_certsssl_ca_datassl_ca_pathssl_check_hostnamessl_min_versionssl_ciphersssl_passwordc                 ~    t         st        d      t        |||||||||	|
||      | _        t	        |   di | y )N$Python wasn't built with SSL support)keyfilecertfile	cert_reqsinclude_verify_flagsexclude_verify_flagsca_certsca_dataca_pathcheck_hostnamemin_versionciphersrj   rQ   )r   r:   RedisSSLContextrt   r  r   )rY   r  r  r  r  r  r  r  r  r  r  r  r  rG  r   s                 rR   r   zSSLConnection.__init__  sW      CDD,;!#!9!9!-'!-
 	"6"rI   r   c                 ^    t         |          }| j                  j                         |d<   |S )Nssl)r  r  rt   r  )rY   rG  r   s     rR   r  z#SSLConnection._connection_arguments  s-    .0((,,.urI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.keyfile      '''rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.certfile      (((rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.cert_reqs  s    )))rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  z"SSLConnection.include_verify_flags      444rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  z"SSLConnection.exclude_verify_flags  r  rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.ca_certs  r  rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.ca_data  r  rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.check_hostname  s    ...rI   c                 .    | j                   j                  S rW   )rt   r  r   s    rR   r  zSSLConnection.min_version  s    +++rI   )NNrequiredNNNNNTNNN)rL   rM   rN   r}  r   r>  r   r  
VerifyModer	   r  r   r   r
   r  r  r  r  r  r  r  r  r  r  r  r  r  s   @rR   r  r    s    &*&*4>FJFJ&*%)%)#'04%)&*!#c]!# sm!# S#..01	!#
 #+40A+B"C!# #+40A+B"C!# sm!# c]!# c]!# !!# "*-!# c]!# sm!#Fw 
 ( ( ) ) * * 5 5 5 5 ) ) ( ( / / , ,rI   r  c                       e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 ddee   dee   deeeej                  f      dee	d      dee	d      d	ee   d
ee   dee   de
dee   dee   dee   fdZdefdZy)r  )r  r  r  r  r  r  r  r  contextr  r  r  rj   Nr  r  r  r  r  r  r  r  r  r  r  r  rj   c                    t         st        d      || _        || _        |t        j
                  }nWt        |t              rGt        j
                  t        j                  t        j                  d}||vrt        d|       ||   }|| _
        || _        || _        || _        || _        || _        | j                  t        j
                  k7  r|	nd| _        |
| _        || _        || _        d | _        y )Nr  )noneoptionalr  z+Invalid SSL Certificate Requirements Flag: F)r   r:   r  r  r  	CERT_NONEr  r>  CERT_OPTIONALCERT_REQUIREDr  r  r  r  r  r  r  r  r  rj   r  )rY   r  r  r  r  r  r  r  r  r  r  r  rj   	CERT_REQSs                 rR   r   zRedisSSLContext.__init__  s     CDD I	3'----I
 	) A)M  "),I"$8!$8! "nn=N5 	 ' -1rI   r   c                 @   | j                   st        j                         }| j                  |_        | j                  |_        | j                  r&| j                  D ]  }|xj                  |z  c_         | j                  r'| j                  D ]  }|xj                  | z  c_         | j                  s| j                  r2|j                  | j                  | j                  | j                         | j                  s| j                  s| j                  r2|j!                  | j                  | j                  | j                         | j"                  | j"                  |_        | j&                  |j)                  | j&                         || _         | j                   S )N)r  r  rj   )cafilecapathcadata)r  r  create_default_contextr  r  verify_moder  verify_flagsr  r  r  load_cert_chainrj   r  r  r  load_verify_locationsr  minimum_versionr  set_ciphers)rY   r  flags      rR   r  zRedisSSLContext.get+  sJ   ||002G%)%8%8G""&..G(( 55 1D((D0(1(( 55 2D((TE1(2}}''!]] LL!]] ( 
 }}--==dll .  +*.*:*:'||'##DLL1"DL||rI   )NNNNNNNNFNNN)rL   rM   rN   r~  r   r>  r   r  r  r	   r  r   r   r   r  rQ   rI   rR   r  r    s   I$ "&"&:>BFBF"&!%!%$,0!%"&-2#-2 3--2 E#s~~"567	-2
 't,='>?-2 't,='>?-2 3--2 #-2 #-2 -2 j)-2 #-2 3--2^Z rI   r  c                   f     e Zd ZdZdddef fdZdeeeeee	f   f      fdZ
d Zdefd	Z xZS )
UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server pathr  c                2    || _         t        |   di | y r  )r  r  r   )rY   r  rG  r   s      rR   r   z#UnixDomainSocketConnection.__init__K  s    	"6"rI   r   c                     d| j                   fd| j                  fg}| j                  r|j                  d| j                  f       |S )Nr  rd   rf   )r  rd   rf   r   r  s     rR   r   z&UnixDomainSocketConnection.repr_piecesO  sB    499%dgg7MM=$*:*:;<rI   c                 D  K   t        | j                        4 d {    t        j                  | j                         d {   \  }}d d d       d {    | _        | _        | j                          d {    y 7 f7 @7 /# 1 d {  7  sw Y   ?xY w7  w)Nr  )r'  rl   r   open_unix_connectionr  rv   rw   r  )rY   r  r  s      rR   r   z#UnixDomainSocketConnection._connectU  s      !<!<= 	P 	P#*#?#?TYY#OONFF	P 	Poo		PO	P 	P 	P 	P 	 sb   B BB $B	BB	B B%B =B>B B	B 	BBBB c                     | j                   S rW   r  r   s    rR   r   z&UnixDomainSocketConnection._host_error\  s    yyrI   )rL   rM   rN   r}  r>  r   r   r   r   r   r   r   r   r  r  s   @rR   r  r  H  sI    :&( # #XeCsCx,@&AB  S rI   r  )0FFALSENNOr   c                 v    | | dk(  ry t        | t              r| j                         t        v ryt	        |       S )Nr  F)r  r>  upperFALSE_STRINGSr  )values    rR   to_boolr  c  s4    }%%++-="@;rI   c                    | j                  dd      j                  dd      }g }|j                  d      D ]O  }|j                         }t        t        |      st        d|       |j                  t        t        |             Q |S )N[r  ]r   zInvalid ssl verify flag: )replacerY  striphasattrr    r   r   r   )r  verify_flags_strr  r  s       rR   parse_ssl_verify_flagsr  k  s     }}S"-55c2>L &&s+ 8zz|{D)8?@@GK67	8
 rI   )rd   rk   rl   r  rn   max_connectionsrp   r  r  r  r*   .URL_QUERY_ARGUMENT_PARSERSc                   Z    e Zd ZU eed<   eed<   ee   ed<   eed<   eed<   eed<   eed<   y)	ConnectKwargsre   rj   connection_classr   r   rd   r  N)rL   rM   rN   r>  __annotations__r   r]   r   rQ   rI   rR   r  r    s,    MM-..
I
IG
IrI   r  F)totalurlc                    t        |       }i }t        |j                        j                         D ]N  \  }}|s	t	        |      dkD  st        |d         }t        j                  |      }|r	  ||      ||<   J|||<   P |j                  rt        |j                        |d<   |j                  rt        |j                        |d<   |j                  dk(  r/|j                  rt        |j                        |d<   t        |d<   |S |j                  d	v r|j                  rt        |j                        |d
<   |j                   rt#        |j                         |d<   |j                  r6d|vr2	 t#        t        |j                        j%                  dd            |d<   |j                  dk(  r	t(        |d<   |S d}t        d| d      # t        t        f$ r t        d| d      w xY w# t&        t        f$ r Y ^w xY w)Nr   zInvalid value for 'z' in connection URL.re   rj   unixr  r  )redisredissr   r   rd   /r  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryr  r  r   r  r  r   r   re   rj   schemer  r  hostnamer   r   r  AttributeErrorr  )r	  parsedrG  name
value_listr  r  valid_schemess           rR   	parse_urlr    s   "3-FF$V\\288: 
%j#j/A-JqM*E/33D9FW#)%=F4L  %t
% $V__5z$V__5z }};;$V[[1F6N%?!"2 M/ 
-	-??$V__5F6N;; -F6N ;;4v-"76;;#7#?#?R#HIt ==H$)6F%& M 7CM?RST
 	
G ":. W$':4&@T%UVVW6 #J/ s   /G/1G- G*-G?>G?_CPConnectionPool)boundc                   2   e Zd ZdZedee   dedefd       Ze	dfdee
   dee   fd	Z eh d
      Zd Zd Zd$dZdefdZ edgdd      d%d       Zd Zd Zd Zde
fdZde
fdZd&defdZd Zd$dZd'dZde fd Z!d!e"fd"Z#de$e%ee&f      fd#Z'y)(r  a  
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.ConnectionError` when the pool's
    limit is reached.

    By default, TCP connections are created unless ``connection_class``
    is specified. Use :py:class:`~redis.UnixDomainSocketConnection` for
    unix sockets.
    :py:class:`~redis.SSLConnection` can be used for SSL enabled connections.

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    clsr	  r   c                 J    t        |      }|j                  |        | 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.
        rQ   )r  update)r  r	  rG  url_optionss       rR   from_urlzConnectionPool.from_url  s&    V  nk"}V}rI   Nr  r  c                    |xs d}t        |t              r|dk  rt        d      || _        || _        || _        g | _        t               | _        | j                  j                  dt              | _        t        j                         | _        | j                  j                  dd       | _        | j                  t!               | _        y y )Nl        r   z,"max_connections" must be a positive integerr   r   )r  r   r   r  connection_kwargsr  _available_connectionsset_in_use_connectionsr  rB   r   r   Lockr{   r   r%   )rY   r  r  r#  s       rR   r   zConnectionPool.__init__
  s     *2U/3/?Q3FKLL 0!2.@B#<?E !3377Q\\^
!%!7!7!;!;<NPT!U!!)%4%6D" *rI   >   rj   re   r  ri   c                 t   dj                  | j                  j                         D cg c]  \  }}| d|| j                  v rdn|  c}}      }d| j                  j
                   d| j                  j                   d| j                  j
                   d| j                  j                   d| dS c c}}w )	Nr   r   z
<REDACTED>r   r   z(<r   z)>)>)r   r#  r  SENSITIVE_REPR_KEYSr   rM   rL   r  )rY   r   r   conn_kwargss       rR   r   zConnectionPool.__repr__*  s    hh !2288:Aq #QqD,D,D'D|!LM
 ))*!DNN,C,C+D&&112!D4I4I4R4R3S}D"	
s   !B4
c                 z   t        | d      rt        | d      rt        | j                        }t        | j                        }|dkD  s|dkD  rOt	        |       }ddlm} |dkD  r ||t        j                  |        |dkD  r ||t        j                  |        g | _        t        j                         | _        y )Nr$  r&  r   r,   	pool_nameconnection_statecounter)r  r  r$  r&  r   redis.observability.recorderr,   r   IDLEUSEDr   WeakSetrY   
idle_countin_use_countr.  sync_record_connection_counts        rR   resetzConnectionPool.reset7  s     412w'8
 T889Jt778LA~!1)$/	 >0"+)8)=)=!+
  !#0"+)8)=)=!- ')##*??#4 rI   c                 `   	 t        | d      rt        | d      syt        | j                        }t        | j                        }|dkD  s|dkD  rQt	        |       }ddlm} |dkD  r ||t        j                  |        |dkD  r ||t        j                  |        yyy# t        $ r Y yw xY w)zCClean up connection pool and record metrics when garbage collected.r$  r&  Nr   r,  r-  )r  r  r$  r&  r   r1  r,   r   r2  r3  r   r5  s        rR   r   zConnectionPool.__del__V  s    	4!9:'+C T889Jt778LA~!1)$/	 >0"+)8)=)=!+
  !#0"+)8)=)=!- $ "2&  		s   B! BB! !	B-,B-c                 b    | j                   xs" t        | j                        | j                  k  S )z;Return True if a connection can be retrieved from the pool.)r$  r  r&  r  r   s    rR   can_get_connectionz!ConnectionPool.can_get_connectionu  s1     '' D4++,t/C/CC	
rI   *)Use get_connection() without args instead5.3.0r~   r   versionc                 n  K   | j                   4 d{    t        | j                        t        | j                        z   }t	        j
                         }| j                         }t        | j                        t        | j                        z   }||kD  }ddd      d{    t        |       }	r%t        |	t        j                  d       d{    nHt        |	t        j                  d       d{    t        |	t        j                  d       d{    	 | j                         d{    |r*t        | t	        j
                         z
         d{    |S 7 V7 # 1 d{  7  sw Y   xY w7 7 7 j7 R7 (# t        $ r | j                         d{  7    w xY ww)z(Get a connected connection from the poolNr   r-  r   connection_poolduration_seconds)r{   r  r$  r&  r5  	monotonicget_available_connectionr   r,   r   r3  r2  ensure_connectionr-   rC  release)
rY   command_namekeysoptionsconnections_beforestart_time_createdrZ   connections_after
is_createdr.  s
             rR   get_connectionzConnectionPool.get_connection|  s     :: 		@ 		@!$T%@%@!AC((E " "&!1668J #D$?$? @3((D ! +-??J		@ 		@ "$'	)#!0!5!5   *#!0!5!5  
 *#!0!5!5  	((4443$(%)^^%58J%J  
 Y		@ 		@ 		@ 		@ 		@ 
 5  	,,z***	s   F5E)F5B E.F5"E,#0F5F$F58F9#F5FF5"F 6F	7+F "F#F (F5,F5.F 4E75F <F5F5F5	F F F2*F-+F22F5c                    	 | j                   j                         }| j                  j                  |       |S # t        $ rA t        | j                        | j
                  k\  rt        d      d| j                         }Y fw xY w)zCGet a connection from the pool, without making sure it is connectedzToo many connectionsN)	r$  pop
IndexErrorr  r&  r  r9   make_connectionaddrX   s     rR   rG  z'ConnectionPool.get_available_connection  s}    	04488:J
 	  $$Z0  	04++,0D0DD)*@AtK--/J	0s   9 ABBc                     | j                   }| j                  |j                  dd      |j                  dd      |j                  dd            S )z,Return an encoder based on encoding settingsr   r   r   r   r   F)r   r   r   )r#  r   r  )rY   rG  s     rR   get_encoderzConnectionPool.get_encoder  sQ    ''!!ZZ
G4"JJ'8(C#ZZ(:EB " 
 	
rI   c                 :     | j                   di | j                  S )z=Create a new connection.  Can be overridden by child classes.rQ   )r  r#  r   s    rR   rU  zConnectionPool.make_connection  s      %t$$>t'='=>>rI   rZ   c                 p  K   |j                          d{    	 |j                          d{   rt        d      dy7 *7 # t        t        t        f$ rZ |j                          d{  7   |j                          d{  7   |j                          d{  7  rt        d      dY yw xY ww)z8Ensure that the connection object is connected and validNzConnection has datazConnection not ready)r   rL  r7   r<   r   r   rX   s     rR   rH  z ConnectionPool.ensure_connection  s       """
	H44666%&;<$F 7 	# 7w7 	H'')))$$&&&44666%&<=4G 7	Hsf   B6AB6A AA  B6A 'B3,A/-B3BB3B!B30B62B33B6c                   K   | j                   j                  |       |j                         r|j                          d{    | j                  j                  |       | j                  j                  t        |             d{    t        |       }t        |t        j                  d       d{    t        |t        j                  d       d{    y7 7 Z7 -7 w)z(Releases the connection back to the poolNr   r-  r   )r&  r   r   r   r$  r   r   dispatch_asyncr$   r   r,   r   r3  r2  )rY   rZ   r.  s      rR   rI  zConnectionPool.release  s      	  ''
3&&('')))##**:6$$33-j9
 	
 	

 "$'	%,11
 	
 	

 &,11
 	
 	
 *	
	

	
sH   ?C)C!AC)C#	.C)7C%8#C)C'C)#C)%C)'C)inuse_connectionsc                    K   |r!t        | j                  | j                        }n| j                  }t        j                  d |D        ddi d{   }t        d |D        d      }|r|y7 w)z
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other tasks. Otherwise only disconnect
        connections that are idle in the pool.
        c              3   <   K   | ]  }|j                           y wrW   r   )r   rZ   s     rR   r   z,ConnectionPool.disconnect.<locals>.<genexpr>	  s     D*j##%Ds   return_exceptionsTNc              3   B   K   | ]  }t        |t              s|  y wrW   )r  rC  )r   rs     rR   r   z,ConnectionPool.disconnect.<locals>.<genexpr>  s     D!z!]'CADs   )r   r$  r&  r   gathernext)rY   r]  connectionsrespr   s        rR   r   zConnectionPool.disconnect  s|      8=++T-E-E9K 55K^^DD
"
 

 DtDdKI 
s   AA0A.A0c                    K   | j                   4 d{    | j                  D ]  }|j                           ddd      d{    y7 67 # 1 d{  7  sw Y   yxY ww)z<
        Mark all active connections for reconnect.
        N)r{   r&  r   )rY   conns     rR   'update_active_connections_for_reconnectz6ConnectionPool.update_active_connections_for_reconnect  s_      :: 	* 	*00 *'')*	* 	* 	* 	* 	* 	* 	*sC   A#A
A#"AA#AA#A#A AA A#c                 @   K   | j                          d{    y7 w)z-Close the pool, disconnecting all connectionsNr   r   s    rR   aclosezConnectionPool.aclose  s     oos   c                 d    | j                   D ]	  }||_         | j                  D ]	  }||_         y rW   )r$  r   r&  )rY   r   rh  s      rR   	set_retryzConnectionPool.set_retry  s:    // 	DDJ	,, 	DDJ	rI   rr  c                    K    j                   4 d {     j                  D ]W  j                  j                  fd fd       d {    j                  j                  fd fd       d {    Y  j                  D ]  j                          d d d       d {    y 7 7 e7 =7 # 1 d {  7  sw Y   y xY ww)Nc                  d     j                  dj                  d      j                               S rv  )r  rx  ry  )rh  rr  s   rR   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>'  s)    D--e 4eoo6G rI   c                 &    j                  |       S rW   _mockr   rY   s    rR   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>*  s    $**U"3 rI   c                  $     j                         S rW   )r  )rh  s   rR   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>-  s    D..0 rI   c                 &    j                  |       S rW   rq  rs  s    rR   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>-  s    

5@Q rI   )r{   r$  r   r   r&  rt  )rY   rr  rh  s   ``@rR   re_auth_callbackzConnectionPool.re_auth_callback#  s     :: 	. 	.33 	jj00 4	   jj0002Q  	 00 .&&u-.	. 	. 	.	. 	. 	. 	.sh   CB4C6B<B6)B<:B8;(B<#C.B:/C6B<8B<:C<CCC
Cr   c                    K   yw)z
        Dummy functions, needs to be passed as error callback to retry object.
        :param error:
        :return:
        NrQ   )rY   r   s     rR   rr  zConnectionPool._mock2  s      	rb   c                 n   t        j                         }t        |       |t        <   |j	                         }|j	                         }t
        j                  j                  |t        <   t
        j                  j                  |t        <   t        | j                        |ft        | j                        |fgS )zD
        Returns a connection count (both idle and in use).
        )r   build_base_attributesr   r   r   r   r2  r  r   r3  r  r$  r&  )rY   
attributesfree_connections_attributesin_use_connections_attributess       rR   get_connection_countz#ConnectionPool.get_connection_count:  s     &;;=
5B45H
12&0oo&7#(2(9%   && 	$$>?   && 	&&@A
 ,,-/JK))*,IJ
 	
rI   r{  rW   r|  )r   r0   r   N)(rL   rM   rN   r}  classmethodr   r  r>  r!  r  r]   r   r   r   	frozensetr)  r   r9  r   r  r<  r&   rQ  rG  rX  rU  rH  rI  r   ri  rk  rm  r!   rv  r:   rr  r	   rX  dictr}  rQ   rI   rR   r  r    s)    ,d3i ,c , , ,` 6@)-7127 "#7. $	

5>>
D 
 U:
2
2h	
?H2D H 
(: 
6$ .* .N . 
d5d+;&< 
rI   c            
            e Zd ZdZddeej                  fdedee	   de
e   de
ej                     f fdZ ed	gd
d      d fd	       Zdef fdZ xZS )BlockingConnectionPoola  
    A blocking connection pool::

        >>> from redis.asyncio import Redis, BlockingConnectionPool
        >>> client = Redis.from_pool(BlockingConnectionPool())

    It performs the same function as the default
    :py:class:`~redis.asyncio.ConnectionPool` implementation, in that,
    it maintains a pool of reusable connections that can be shared by
    multiple async redis clients.

    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.asyncio.ConnectionPool` implementation does), it
    blocks the current `Task` 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      r  r*   r  queue_classc                 j    t        |   d||d| t        j                         | _        || _        y )N)r  r  rQ   )r  r   r   	Condition
_conditionr*   )rY   r  r*   r  r  r#  r   s         rR   r   zBlockingConnectionPool.__init__r  s@     	 	
-+	
  	

 "++-rI   r=  r>  r?  r@  c                 >  K   t        j                         }	 | j                  4 d{    t        | j                        4 d{    | j                  j                  | j                         d{    t        | j                        t        | j                        z   }t        j                         }t        | -         }t        | j                        t        | j                        z   }||kD  }	ddd      d{    ddd      d{    	 | j                         d{    	r*t!        | t        j                         z
         d{    t#        t%        |       t        j                         |z
         d{    |S 7 h7 M7 #7 # 1 d{  7  sw Y   xY w7 # 1 d{  7  sw Y   xY w# t        j                  $ r}
t        d      |
d}
~
ww xY w7 7 7 h# t&        $ r | j)                         d{  7    w xY ww)z@Gets a connection from the pool, blocking until one is availableNzNo connection available.rC  )r.  rE  )r5  rF  r  r'  r*   rA  r<  r  r$  r&  r  rG  r   r<   r7   rH  r-   r.   r   rC  rI  )rY   rJ  rK  rL  start_time_acquiredrM  rN  rZ   rO  rP  errr   s              rR   rQ  z%BlockingConnectionPool.get_connection  s     #nn.	G H H(6 H H//2243J3JKKK),T-H-H)IC00M *& *.)9&!&!A!CJ(+D,G,G(H300L )% "35G!GJH HH H"	((4443$(%)^^%58J%J  
 .'-!%!14G!G  
 ?HHKH H H HH H H H ## 	G!"<=3F	G
 5
  	,,z***	s  HG FG F3FF3)F4F5BF6F3FF3G F1G G5 +G/,+G5 G12G5 
G3G5 HG F3FF3F.	"F%#F.	*F31G 3G9F<:GG G,G''G,,H/G5 1G5 3G5 5HHHHrZ   c                    K   | j                   4 d{    t        | 	  |       d{    | j                   j                          ddd      d{    y7 F7 17 	# 1 d{  7  sw Y   yxY ww)z)Releases the connection back to the pool.N)r  r  rI  notify)rY   rZ   r   s     rR   rI  zBlockingConnectionPool.release  sc     ?? 	% 	%'/*---OO""$	% 	% 	%-	% 	% 	% 	%sT   A6AA6A!AA!
A6AA6A!A6!A3'A*(A3/A6rW   )rL   rM   rN   r}  r  r   	LifoQueuer   r   rW  r   r]   Queuer   r&   rQ  rI  r  r  s   @rR   r  r  P  s    F  "#%5?+2+<+< % 12	
 '--(  U:
(
(T%(: % %rI   r  )r   r   enumr   r   sysr5  r  r   abcr   	itertoolsr   typesr   typingr   r   r   r	   r
   r   r   r   r   r   r   r   r   urllib.parser   r   r   r   observability.attributesr   r   r   r   r   utilsr   r  r   r   r    
auth.tokenr!   r   r"   r#   eventr$   r%   r&   r'   version_infor*   r'  $redis.asyncio.observability.recorderr+   r,   r-   r.   r/   redis.asyncio.retryr0   redis.backoffr1   redis.connectionr2   redis.credentialsr3   r4   redis.exceptionsr5   r6   r7   r8   r9   r:   r;   r<   redis.observability.metricsr=   redis.typingr>   redis.utilsr?   r@   _parsersrA   rB   rC   rD   rE   r[  r_  r\  SYM_LFrZ  EnumrK   rP   r   r  rS   rU   r`   r  r]   r  r  r  r  r  r  r  r  r   rW  r  r>  rO   r  r  r  r  r  rQ   rI   rR   <module>r     s^        
      "    B A  "77
CJJK ' 9 F 9 z!06  & # 1 T	 	 	 4 # 7  
				   E+->@SSTU U'M%M>h >D8 D 02NNO _' _'D6*# 6*rP,J P,fZ Zz!3 0 /htn  CS"'##!$%$:$:C GC#v+)>$>? "IU 23 2= 2j e+,A
 A
He%^ e%rI   