
    h                       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mZ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 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+ ddl,m-Z-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; ddl<m=Z= ddl>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZG eArd dlHZHndZHe@rd dlIZIdZJdZKdZLdZMdZN eO       ZPeee&e'e%f      eQd<   e@re%ZRne&ZR G d d      ZS G d d      ZT G d d      ZU G d deU      ZV G d d eV      ZW G d! d"eU      ZX G d# d$eW      ZY G d% d&eV      ZZd'Z[d( Z\e]e^e^e\e\e_e]e]e\e^d)
Z`d* Za ed+d,-      Zb G d. d,      Zc G d/ d0ec      Zdy)1    N)abstractmethod)chain)EmptyFull	LifoQueue)AnyCallableDictListOptionalTypeTypeVarUnion)parse_qsunquoteurlparse)
CacheEntryCacheEntryStatusCacheFactoryCacheFactoryInterfaceCacheInterfaceCacheKey   )Encoder_HiredisParser_RESP2Parser_RESP3Parser)TokenInterface)	NoBackoff)CredentialProvider"UsernamePasswordCredentialProvider)AfterConnectionReleasedEventEventDispatcher)	AuthenticationError$AuthenticationWrongNumberOfArgsErrorChildDeadlockedErrorConnectionError	DataErrorMaxConnectionsError
RedisErrorResponseErrorTimeoutError)Retry)	CRYPTOGRAPHY_AVAILABLEHIREDIS_AVAILABLESSL_AVAILABLEcompare_versionsdeprecated_argsensure_stringformat_error_messageget_lib_versionstr_if_bytes   *   $s   
       DefaultParserc                       e Zd ZdefdZy)HiredisRespSerializerargsc                    g }t        |d   t              r1t        |d   j                         j	                               |dd z   }n)d|d   v r"t        |d   j	                               |dd z   }	 |j                  t        j                  |             |S # t        $ r3 t        j                         \  }}}t        |      j                  |      w xY w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)selfr>   output_value	tracebacks         r/var/www/fastuser/data/www/generator.snapmosaic.io/flask_app/venv/lib/python3.12/site-packages/redis/connection.pypackzHiredisRespSerializer.packM   s    d1gs#a)//12T!"X=DT!W_a)DH4D	=MM'..t45
 	  	="%,,.AuiE"11)<<	=s   1$B <CN)__name__
__module____qualname__r   rU    r9   rT   r=   r=   L   s    $ r9   r=   c                       e Zd ZddZd Zy)PythonRespSerializerNc                      || _         || _        y N)_buffer_cutoffrF   )rO   buffer_cutoffrF   s      rT   __init__zPythonRespSerializer.__init___   s    +r9   c           	      n   g }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                  |      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 r@   )rC   rD   rE   rF   rG   	SYM_EMPTYjoinSYM_STARlenSYM_CRLFr^   map
memoryview
SYM_DOLLARrH   )rO   r>   rP   buffr_   arg
arg_lengths          rT   rU   zPythonRespSerializer.packc   si    d1gs#a)//12T!"X=DT!W_a)DH4D~~xSY)>)>)@(KL++t{{D) 	C SJD	M)-c:. ~~:s:'='='?J d#c" ~~"J..0  	!	4 	dr9   returnN)rV   rW   rX   r`   rU   rY   r9   rT   r[   r[   ^   s    +r9   r[   c                   p   e Z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edd       Zed        Zedd       Ze	 dd
ddd       Zed        Zed        Zeedeeeef   eeef   f   fd              Zedefd       Zed        Zy)ConnectionInterfacec                      y r]   rY   rO   s    rT   repr_pieceszConnectionInterface.repr_pieces       r9   c                      y r]   rY   rO   callbacks     rT   register_connect_callbackz-ConnectionInterface.register_connect_callback   rt   r9   c                      y r]   rY   rv   s     rT   deregister_connect_callbackz/ConnectionInterface.deregister_connect_callback   rt   r9   c                      y r]   rY   rO   parser_classs     rT   
set_parserzConnectionInterface.set_parser   rt   r9   c                      y r]   rY   rr   s    rT   get_protocolz ConnectionInterface.get_protocol   rt   r9   c                      y r]   rY   rr   s    rT   connectzConnectionInterface.connect   rt   r9   c                      y r]   rY   rr   s    rT   
on_connectzConnectionInterface.on_connect   rt   r9   c                      y r]   rY   rO   r>   s     rT   
disconnectzConnectionInterface.disconnect   rt   r9   c                      y r]   rY   rr   s    rT   check_healthz ConnectionInterface.check_health   rt   r9   Tc                      y r]   rY   rO   commandr   s      rT   send_packed_commandz'ConnectionInterface.send_packed_command   rt   r9   c                      y r]   rY   rO   r>   kwargss      rT   send_commandz ConnectionInterface.send_command   rt   r9   c                      y r]   rY   rO   timeouts     rT   can_readzConnectionInterface.can_read   rt   r9   Fdisconnect_on_errorpush_requestc                     y r]   rY   )rO   disable_decodingr   r   s       rT   read_responsez!ConnectionInterface.read_response   s     	r9   c                      y r]   rY   r   s     rT   rJ   z ConnectionInterface.pack_command   rt   r9   c                      y r]   rY   rO   commandss     rT   pack_commandsz!ConnectionInterface.pack_commands   rt   r9   rn   c                      y r]   rY   rr   s    rT   handshake_metadataz&ConnectionInterface.handshake_metadata   s     	r9   tokenc                      y r]   rY   rO   r   s     rT   set_re_auth_tokenz%ConnectionInterface.set_re_auth_token   rt   r9   c                      y r]   rY   rr   s    rT   re_authzConnectionInterface.re_auth   rt   r9   NTr   F)rV   rW   rX   r   rs   rx   rz   r~   r   r   r   r   r   r   r   r   r   rJ   r   propertyr   r
   bytesrD   r   r   r   r   rY   r9   rT   rp   rp      s                             !      E$ue|*<d38n*L$M    ~    r9   rp   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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      dee   f(dZd Zed         Zd! Zd" Zd# Zd$ Zd% Zd& Z	 dCd(ed)efd*Zed+        Zed,        Zd- Zd. ZdDd(efd/Z d0 Z!d1 Z"d2 Z#d3 Z$dDd4Z%d5 Z&dEd6Z'	 dFd'dd7d8Z(d9 Z)d: Z*d;eee	f   fd<Z+e,d;ee-e.e.f   e-e	e	f   f   fd=       Z/e/j`                  d>ee-e.e.f   e-e	e	f   f   fd?       Z/d@e1fdAZ2dB Z3y)G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_packerevent_dispatcherc                    |s|r|t        d      |t               | _        n|| _        t        j                         | _        || _        || _        || _        || _	        || _
        || _        || _        || _        ||}|| _        || _        |t         u rg }|r|j#                  t$               || _        |s|rR|t)        t+               d      | _        nt/        j0                  |      | _        | j,                  j3                  |       nt)        t+               d      | _        || _        d| _        || _        t;        |||	      | _        d| _        d| _         || _!        | jE                  |
       g | _#        d| _$        d| _%        	 tM        |      }|dk  s|dkD  rtU        d	      || _+        | jY                  |      | _-        y# tN        $ r	 tP        }Y DtR        $ r tU        d      w xY w# dk  s|dkD  rtU        d	      || _+        w xY w)
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(   r#   _event_dispatcherosgetpidpidr   r   r   r   r   r   r   r   r   r   SENTINELrH   r,   retry_on_errorr-   r   r   copydeepcopyupdate_supported_errorsr   next_health_checkr   r   encoderr   _sock_socket_read_sizer~   _connect_callbacksr^   _re_auth_tokenintrK   DEFAULT_RESP_VERSION
ValueErrorr'   r   _construct_command_packer_command_packer)rO   r   r   r   r   r   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   ps                           rT   r`   zAbstractConnection.__init__   s   @ &9&E+  #%4%6D"%5D"99;& &#6   ,!)%3"&<# 0X%N!!,/,N}"9;2
 "]]51
JJ..~>y{A.DJ%:"!""4x:JK"&
!1%"$"8<
	HA 1uA%&FGGDM#==nM  	%$A 	A!"?@@	A 1uA%&FGGDMs$   G G+G. G++G. .Hc           	          dj                  | j                         D cg c]  \  }}| d|  c}}      }d| j                  j                   d| j                  j                   d| dS c c}}w )N,=<.(z)>)rc   rs   	__class__rW   rV   )rO   kv	repr_argss       rT   __repr__zAbstractConnection.__repr__E  sj    HHT5E5E5GHTQ1QCjHI	4>>,,-Qt~~/F/F.GqSUVV Is   A,
c                      y r]   rY   rr   s    rT   rs   zAbstractConnection.repr_piecesI  rt   r9   c                 D    	 | j                          y # t        $ r Y y w xY wr]   )r   	Exceptionrr   s    rT   __del__zAbstractConnection.__del__M  s#    	OO 		s    	c                 ~    ||S t         r
t               S t        | j                  | j                  j
                        S r]   )r/   r=   r[   r^   r   rF   )rO   packers     rT   r   z,AbstractConnection._construct_command_packerS  s6    M(**'(;(;T\\=P=PQQr9   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
WeakMethodr   rH   )rO   rw   wms      rT   rx   z,AbstractConnection.register_connect_callback[  s;     )T,,,##**2. -r9   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)r   remover   r   r   rv   s     rT   rz   z.AbstractConnection.deregister_connect_callbackg  s8    	##**7+=+=h+GH 		s   .1 	==c                 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   _parserr|   s     rT   r~   zAbstractConnection.set_parserr  s     $T5K5KLr9   c                 (    | j                  d       y)z5Connects to the Redis server if not already connectedTr   N)connect_check_healthrr   s    rT   r   zAbstractConnection.connectz  s    !!t!4r9   Tr   retry_socket_connectc                 f     j                   ry 	 |r# j                  j                   fd fd      }n j                         }| _         	  j                   j                  |       n j                           j                  D cg c]  } |       s| c} _         j                  D ]  } |       }|s |         y # t        j
                  $ r t        d      t        $ r}t         j                  |            d }~ww xY w# t        $ r  j                           w xY wc c}w )Nc                  $     j                         S r]   )_connectrr   s   rT   <lambda>z9AbstractConnection.connect_check_health.<locals>.<lambda>  s    DMMO r9   c                 &    j                  |       S r]   r   errorrO   s    rT   r   z9AbstractConnection.connect_check_health.<locals>.<lambda>  s    4??5;Q r9   zTimeout connecting to serverr   )r   r   call_with_retryr   socketr   r,   OSErrorr'   _error_messager   on_connect_check_healthr*   r   r   )rO   r   r   sockerefrw   s   `      rT   r   z'AbstractConnection.connect_check_health~  s     ::
	:#zz11+-Q }} 

	&&.,,,,G ''- 372I2I"S3SU3"S** 	CuH	- ~~ 	?=>> 	:!$"5"5a"899	:  	OO	 #Ts/   5C 0D D.D.&D.DDD+c                      y r]   rY   rr   s    rT   r   zAbstractConnection._connect  rt   r9   c                      y r]   rY   rr   s    rT   _host_errorzAbstractConnection._host_error  rt   r9   c                 6    t        | j                         |      S r]   )r4   r  )rO   	exceptions     rT   r  z!AbstractConnection._error_message  s    #D$4$4$6	BBr9   c                 (    | j                  d       y )NTr   )r  rr   s    rT   r   zAbstractConnection.on_connect  s    $$$$7r9   c                    | j                   j                  |        | j                   }d}| j                  s| j                  s| j                  r>| j                  xs  t        | j                  | j                        }|j                         }|r| j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        t        |      dk(  rd|d   g} | j                  d| j                  dg|dd	i | j                         | _        nD|rA | j                  dg|dd	i 	 | j                         }t%        |      dk7  rt'        d      | j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        | j                  d| j                  |       | j                         | _        | j                   j)                  d      | j                  k7  r3| j                   j)                  d      | j                  k7  rt+        d      | j,                  rF| j                  dd| j,                  |       t%        | j                               dk7  rt+        d      	 | j.                  r0| j                  ddd| j.                  |       | j                          	 | j2                  r0| j                  ddd| j2                  |       | j                          | j4                  rF| j                  d| j4                  |       t%        | j                               dk7  rt+        d      yy# t"        $ r+ | j                  d|d
   d	       | j                         }Y mw xY w# t0        $ r Y w xY w# t0        $ r Y w xY w)z=Initialize the connection, authenticate and select a databaseN)r:   2r   defaultr   HELLOAUTHr   Fr   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   r   r   r   r!   get_credentialsr   rC   r   r~   r   EXCEPTION_CLASSESre   r   r   r   r%   r6   r$   getr'   r   r   r+   r   r   )rO   r   parser	auth_argscred_providerauth_responses         rT   r  z*AbstractConnection.on_connect_check_health  s   %	##(( T5dmmT]]S  &557I h6$,,5-171I1I.''-9~"&	!5	 D1:IN '+&8&8&:D#
  DfEyEuE5 $ 2 2 4 M*d2)*HII ]](*$,,5-171I1I.''-gt}}<P&*&8&8&:D#''++H5F++//8DMMI%&<==   )	   D..01T9%&ABB	}}!!MM!- "  ""$	!!$$!- "  ""$
 77hlKD..01T9%&899 : C 8 5
 !!&)B-e!L $ 2 2 45`  		  		s6   (N2 &<O) #<O8 20O&%O&)	O54O58	PPc                 P   | j                   j                          | j                  }d| _        |yt        j                         | j
                  k(  r 	 |j                  t        j                         	 |j                          y# t        t        f$ r Y #w xY w# t        $ r Y yw xY w)z!Disconnects from the Redis serverN)r   on_disconnectr   r   r   r   shutdownr  	SHUT_RDWRr  rK   close)rO   r>   	conn_socks      rT   r   zAbstractConnection.disconnect"  s    ""$JJ	
99;$(("""6#3#34	OO	 Y' 
  		s$   B 3B BB	B%$B%c                 x    | j                  dd       t        | j                               dk7  rt        d      y)z Send PING, expect PONG in returnPINGFr   PONGz#Bad response from PING health checkN)r   r6   r   r'   rr   s    rT   
_send_pingzAbstractConnection._send_ping6  s<    &u5**,-7!"GHH 8r9   c                 $    | j                          y)z Function to call when PING failsNr   rO   r  s     rT   _ping_failedzAbstractConnection._ping_failed<      r9   c                     | j                   rSt        j                         | j                  kD  r1| j                  j                  | j                  | j                         yyy)z3Check the health of the connection with a PING/PONGN)r   time	monotonicr   r   r  r,  r/  rr   s    rT   r   zAbstractConnection.check_health@  sF    %%$..*:T=S=S*SJJ&&t8I8IJ +T%r9   c                 R   | j                   s| j                  d       |r| j                          	 t        |t              r|g}|D ]  }| j                   j                  |        y
# t        j                  $ r | j                          t        d      t        $ ro}| j                          t        |j                        dk(  rd|j                  d   }}n|j                  d   }|j                  d   }t        d| d| d	      d
}~wt        $ r | j                           w xY w)z2Send an already packed command to the Redis serverFr   zTimeout writing to socketr   UNKNOWNr   zError z while writing to socket. r   N)r   r   r   rC   rD   sendallr  r   r   r,   r  re   r>   r'   BaseException)rO   r   r   itemr  errnoerrmsgs          rT   r   z&AbstractConnection.send_packed_commandE  s   zz%%5%9	'3'") )

""4()~~ 	<OO:;; 	WOO166{a )166!9vq	!F5'1KF8ST"UVV 	
 OO	s   5A( (6D&A*DD&c                 x    | j                   | j                  j                  | |j                  dd             y)z+Pack and send a command to the Redis serverr   Tr   N)r   r   rU   r  r   s      rT   r   zAbstractConnection.send_commandd  s9      %D  %%t,ND9 	! 	
r9   c                    | j                   }|s| j                          | j                         }	 | j                  j	                  |      S # t
        $ r0}| j                          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   r   r  r   r'   r>   )rO   r   r  
host_errorr  s        rT   r   zAbstractConnection.can_readk  sy    zzLLN%%'
	V<<((11 	VOO!$=j\AFF8"TUU	Vs   A 	B+A??Br   c                d   | j                         }	 | j                  dv r| j                  j                  ||      }n| j                  j                  |      }| j                  r&t        j                         | j                  z   | _        t!        |t"              r	 ||S # t        j
                  $ r! |r| j                          t        d|       t        $ r2}|r| j                          t        d| d|j                         d}~wt        $ r |r| j                           w xY w# ~w xY w)z0Read the response from a previously sent command)3r   )r   r   )r   zTimeout reading from r=  z : N)r  r   r   r   r  r   r   r,   r  r'   r>   r7  r   r2  r3  r   rC   r+   )rO   r   r   r   r>  responser  s          rT   r   z AbstractConnection.read_responsey  s%    %%'
	}}(<<55%5L 6   <<55GW5X" %%%)^^%58R8R%RD"h. 1 ~~ 	E"!!6zlCDD 	W"!!$=j\QVVH"UVV 	 #!	 s$   AB! D, !;D)-D		 D),D/c                 4     | j                   j                  | S )rA   )r   rU   r   s     rT   rJ   zAbstractConnection.pack_command  s    (t##(($//r9   c                    g }g }d}| j                   }|D ]  } | j                  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   )	r^   r   rU   re   rC   rh   rH   rb   rc   )	rO   r   rP   piecesbuffer_lengthr_   cmdchunkchunklens	            rT   r   z AbstractConnection.pack_commands  s    ++ 	.C2--22C8 .u:!M1-/!%4innV&<=$%MFm+z%/LMM%(MM%(!X-M!.	.& MM)..01r9   rn   c                     | j                   S r]   )r   rr   s    rT   r   zAbstractConnection.get_protocol  s    }}r9   c                     | j                   S r]   _handshake_metadatarr   s    rT   r   z%AbstractConnection.handshake_metadata  s    '''r9   rR   c                     || _         y r]   rK  )rO   rR   s     rT   r   z%AbstractConnection.handshake_metadata  s
    #( r9   r   c                     || _         y r]   )r   r   s     rT   r   z$AbstractConnection.set_re_auth_token  s
    #r9   c                     | j                   \| j                  d| j                   j                  d      | j                   j                                | j	                          d | _         y y Nr  oid)r   r   try_get	get_valuer   rr   s    rT   r   zAbstractConnection.re_auth  s`    *##++E2##--/
  "&D +r9   )TTr   r   r   )4rV   rW   rX   __doc__r   r;   r5   r   r   rD   floatboolr   r   r	   r    r#   r`   r   r   rs   r   r   rx   rz   r~   r   r   r   r  r  r   r  r   r,  r/  r   r   r   r   r   rJ   r   r   r   r
   r   r   setterr   r   r   rY   r9   rT   r   r      s
   6 "&*.26!&'!&" %%&%)",%4%6"&"&;?<@"#7;6:/^N^N 3-^N !	^N
 !)^N ^N ^N ^N ^N ^N  #^N c]^N 3-^N  c]!^N" 3-#^N$ S$Y%^N& %Xb$h%78'^N( &&89)^N* 3-+^N, !"d(!34-^N. #?3/^N@W  R
/	M5
 GK% %?C%N    C8m:D m:^(IK
>
V  * !*X0<eCHo  (E$ue|*<d38n*L$M ( ( )d5%<.@$sCx..P(Q ) )$~ $'r9   r   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 serverc                     || _         t        |      | _        || _        |xs i | _        || _        t        |   di | y NrY   )hostr   portsocket_keepalivesocket_keepalive_optionssocket_typesuperr`   )rO   r\  r]  r^  r_  r`  r   r   s          rT   r`   zConnection.__init__  sD     	I	 0(@(FB%&"6"r9   c                     d| j                   fd| j                  fd| j                  fg}| j                  r|j	                  d| j                  f       |S )Nr\  r]  r   r   )r\  r]  r   r   rH   rO   rD  s     rT   rs   zConnection.repr_pieces  sM    499%		':T477OLMM=$*:*:;<r9   c                    d}t        j                  | j                  | j                  | j                  t         j
                        D ]  }|\  }}}}}d}	 t        j                   |||      }|j                  t         j                  t         j                  d       | j                  rr|j                  t         j                  t         j                  d       | j                  j                         D ]&  \  }	}
|j                  t         j                  |	|
       ( |j                  | j                         |j!                  |       |j                  | j"                         |c S  ||t%        d      # t$        $ rO}|}|@	 |j'                  t         j(                         n# t$        $ r Y nw xY w|j+                          Y d}~d}~ww xY w)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
settimeoutr   r   r   r  r%  r&  r'  )rO   errresfamilysocktyper  	canonnamesocket_addressr  r   r   rQ   s               rT   r   zConnection._connect  s   
 %%IItyy$"2"2F4F4F
 !	!C BE>FHeYD!}}VXu= 2 2F4F4FJ ((OOF$5$5v7J7JAN $ = = C C E B1(:(:AqAB  ; ;< ^,  3 341!	!F ?IABB  !#f&6&67" JJL!s=   DE55	G>GF#"G#	F/,G.F//GGc                 8    | j                    d| j                   S )N:)r\  r]  rr   s    rT   r  zConnection._host_error&  s    ))Adii[))r9   )	localhosti  FNr   	rV   rW   rX   rT  r`   rs   r   r  __classcell__r   s   @rT   rY  rY    s-    : !%# +CZ*r9   rY  c                   :   e Zd ZdZdZdZdededej                  fdZ
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd&dZd Zd'dZ	 d(ddddZd Zd Zedeeeef   eeef   f   fd       Zd Zd Z deddfdZ!d Z"d e#eee$e#e      f      fd!Z%d" Z&d#e'fd$Z(d% Z)y))CacheProxyConnections   fooz7.4.0redisconncache	pool_lockc                    t        j                         | _        || _        | j                  j                  | _        | j                  j
                  | _        | j                  j                  | _        |j                  | _        || _        || _	        t        j                         | _        d | _        d | _        | j                  | j                          y r]   )r   r   r   _connr   r\  r]  r   
_pool_lock_cache	threadingRLock_cache_lock_current_command_cache_key_current_optionsrx   _enable_tracking_callback)rO   r}  r~  r  s       rT   r`   zCacheProxyConnection.__init__/  s     99;
ZZ%%
JJOO	JJOO	#'#;#; #$??,*.' $&&t'E'EFr9   c                 6    | j                   j                         S r]   )r  rs   rr   s    rT   rs   z CacheProxyConnection.repr_piecesB  s    zz%%''r9   c                 :    | j                   j                  |       y r]   )r  rx   rv   s     rT   rx   z.CacheProxyConnection.register_connect_callbackE  s    

,,X6r9   c                 :    | j                   j                  |       y r]   )r  rz   rv   s     rT   rz   z0CacheProxyConnection.deregister_connect_callbackH  s    

..x8r9   c                 :    | j                   j                  |       y r]   )r  r~   r|   s     rT   r~   zCacheProxyConnection.set_parserK  s    

l+r9   c                     | j                   j                          | j                   j                  j                  dd       }|&| j                   j                  j                  dd       }| j                   j                  j                  dd       }|&| j                   j                  j                  dd       }||t	        d      t        |      }t        |      }|| j                  k7  st        || j                        dk(  rt	        d      y )Ns   serverservers   versionversionz0Cannot retrieve information about server versionr   ziTo maximize compatibility with all Redis products, client-side caching is supported by Redis 7.4 or later)	r  r   r   r  r'   r3   DEFAULT_SERVER_NAMEr1   MIN_ALLOWED_VERSION)rO   server_name
server_vers      rT   r   zCacheProxyConnection.connectN  s    

jj3377	4H**77;;HdKKZZ2266z4H
66::9dKJ!3!"TUU":.
#K0 4333
D,D,DEJ!{  Kr9   c                 8    | j                   j                          y r]   )r  r   rr   s    rT   r   zCacheProxyConnection.on_connecte  s    

r9   c                     | j                   5  | j                  j                          d d d         | j                  j                  |  y # 1 sw Y   #xY wr]   )r  r  flushr  r   r   s     rT   r   zCacheProxyConnection.disconnecth  sD     	 KK	 

t$	  	 s   A

Ac                 8    | j                   j                          y r]   )r  r   rr   s    rT   r   z!CacheProxyConnection.check_healthm  s    

!r9   Tc                 :    | j                   j                  |       y r]   )r  r   r   s      rT   r   z(CacheProxyConnection.send_packed_commandp  s     	

&&w/r9   c           	         | j                          | j                  5  | j                  j                  t	        |d   d            s-d | _         | j                  j                  |i | 	 d d d        y 	 d d d        |j                  d      t        d      t	        |d   t        |j                  d                  | _        | j                  5  | j                  j                  | j
                        r| j                  j                  | j
                        }|j                  | j                  k7  rf| j                  5  |j                  j                         r7|j                  j                  d       |j                  j                         r7d d d        	 d d d        y | j                  j                  t!        | j
                  | j"                  t$        j&                  | j                               d d d         | j                  j                  |i | y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   ?xY w)	Nr   rY   )r   
redis_keyskeyszCannot create cache key.Tr   )	cache_keycache_valuestatusconnection_ref)_process_pending_invalidationsr  r  is_cachabler   r  r  r   r  r   rE   r  r  r   r   setr   DUMMY_CACHE_VALUEr   IN_PROGRESS)rO   r>   r   entrys       rT   r   z!CacheProxyConnection.send_commandu  s   ++- 	 ;;**8DGPR+ST26/'

''88	 	 U	 ::f%788 +3Gfjj.@(A+
'  	 {{t>>?(G(GH''4::5 R#22;;=!00>>D>Q $22;;=R 	 	  KKOO"== $ 6 6+77#'::	!	6 	 

00W	 	0R R	 	s9   AHA0H8AH,	H8&AH8H),H5	1H88Ic                 8    | j                   j                  |      S r]   )r  r   r   s     rT   r   zCacheProxyConnection.can_read  s    zz""7++r9   Fr   c                   | j                   5  | j                  | j                  j                  | j                        | j                  j                  | j                        j                  t
        j                  k7  rTt        j                  | j                  j                  | j                        j                        }d | _        |cd d d        S d d d        | j                  j                  |||      }| j                   5  | j                  |cd d d        S |1| j                  j                  | j                  g       |cd d d        S | j                  j                  | j                        }|7t
        j                  |_        ||_	        | j                  j                  |       d | _        d d d        |S # 1 sw Y   xY w# 1 sw Y   |S xY w)N)r   r   r   )r  r  r  r  r  r   r  r   r   r  r  r   delete_by_cache_keysVALIDr  )rO   r   r   r   ro  rA  cache_entrys          rT   r   z"CacheProxyConnection.read_response  s     	 //;KKOOD$C$CDPKKOOD$C$CDKK#//0 mmKKOOD$C$CDPP 37/	 	 	 ::++- 3% , 
  	3..6	3 	3
 00$2Q2Q1RS	3 	3 ++//$*I*IJK &%5%;%;"*2',.2D+%	3( Q	 	(	3( s%   B<F?G)GA%G?GGc                 4     | j                   j                  | S r]   )r  rJ   r   s     rT   rJ   z!CacheProxyConnection.pack_command  s    &tzz&&--r9   c                 8    | j                   j                  |      S r]   )r  r   r   s     rT   r   z"CacheProxyConnection.pack_commands  s    zz''11r9   rn   c                 .    | j                   j                  S r]   )r  r   rr   s    rT   r   z'CacheProxyConnection.handshake_metadata  s    zz,,,r9   c                 8    | j                   j                          y r]   )r  r   rr   s    rT   r   zCacheProxyConnection._connect  s    

r9   c                 8    | j                   j                          y r]   )r  r  rr   s    rT   r  z CacheProxyConnection._host_error  s    

 r9   Nc                     |j                  ddd       |j                          |j                  j                  | j                         y )Nr  TRACKINGON)r   r   r   set_invalidation_push_handler_on_invalidation_callback)rO   r}  s     rT   r  z.CacheProxyConnection._enable_tracking_callback  s8    (J52243Q3QRr9   c                     | j                         r.| j                  j                  d       | j                         r-y y )NTr  )r   r  r   rr   s    rT   r  z3CacheProxyConnection._process_pending_invalidations  s+    mmoJJ$$$$7 mmor9   datac                     | j                   5  |d   | j                  j                          n| j                  j                  |d          d d d        y # 1 sw Y   y xY w)Nr   )r  r  r  delete_by_redis_keys)rO   r  s     rT   r  z.CacheProxyConnection._on_invalidation_callback  sO     	:Aw!!#00a9	: 	: 	:s   ?AAc                 6    | j                   j                         S r]   )r  r   rr   s    rT   r   z!CacheProxyConnection.get_protocol  s    zz&&((r9   r   c                 :    | j                   j                  |       y r]   )r  r   r   s     rT   r   z&CacheProxyConnection.set_re_auth_token  s    

$$U+r9   c                 8    | j                   j                          y r]   )r  r   rr   s    rT   r   zCacheProxyConnection.re_auth  s    

r9   r   r   r   )*rV   rW   rX   r  r  r  rp   r   r  r  r`   rs   rx   rz   r~   r   r   r   r   r   r   r   r   rJ   r   r   r   r
   r   rD   r   r   r  r  r  r   r   r  r   r   r   r   rY   r9   rT   r{  r{  *  s+   !!G!G G ??	G&(79,. %
"0
.1`,  %+=APU+Z.2 -E$ue|*<d38n*L$M - -!S.A Sd S
8:d5htE{>S9S3T.U :),~ ,r9   r{  c                   P     e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd	Z fdZ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)
    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| _        || _        |	| _        |
| _        || _        || _        || _        || _        t-        | \  di | y)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), or an ssl.VerifyMode. 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optionalrequiredz+Invalid SSL Certificate Requirements Flag: FrY   )r0   r*   keyfilecertfilessl	CERT_NONErC   rD   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_ciphersra  r`   )rO   ssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_ca_datassl_check_hostnamessl_ca_pathssl_passwordr  r  r  r  r  r  r   	CERT_REQSr   s                    rT   r`   zSSLConnection.__init__  s   P CDD"$ MMMs+----I
 I- A-Q  &m4M&$"""&..CMM"Au 	 %1!!2)B& 0&<#.&"6"r9   c                     t         |          }	 | j                  |      S # t        t        f$ r |j                           w xY w)zN
        Wrap the socket with SSL support, handling potential errors.
        )ra  r   _wrap_socket_with_sslr  r*   r'  )rO   r  r   s     rT   r   zSSLConnection._connectP  sH     w!	--d33$ 	JJL	s	   " !Ac                 ,   t        j                         }| j                  |_        | j                  |_        | j
                  s| j                  r2|j                  | j
                  | j                  | j                         | j                  | j                  | j                  2|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+                  || j,                        }| j(                  r+d	dl}d
dlm} | j4                  f|j6                  j9                  |j6                  j:                        }|j=                  | j
                         |j?                  | j                         n| j4                  }|jA                  || jB                         |j6                  jE                  |tG        jF                               }|jI                          |jK                  | j,                  | jL                  f       |jO                          |jQ                          |S | j"                  du rRt$        rLd
dlm)}  ||| j,                  | jL                  | j                        }	|	jU                         r|S tW        d      |S )z
        Wraps the socket with SSL support.

        Args:
            sock: The plain socket to wrap with SSL.

        Returns:
            An SSL wrapped socket.
        )r  r  r   N)cafilecapathcadataTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.)server_hostnamer   r   )ocsp_staple_verifier)OCSPVerifierzocsp validation error),r  create_default_contextr  r  verify_moder  r  load_cert_chainr  r  r  r  load_verify_locationsr  minimum_versionr  set_ciphersr  r.   r*   r  wrap_socketr\  OpenSSLocspr  r  SSLContextSSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackr  rY  r  request_ocspr   r]  do_handshaker%  r  is_validr'   )
rO   r  contextsslsockr  r  
staple_ctxconr  os
             rT   r  z#SSLConnection._wrap_socket_with_ssl[  su    ,,.!%!4!4"nn==DLL##22 $  MM%||'||'))}}T\\$,, *  +&*&:&:G# 0 01!!T).D.M=>>))d.D.D 
 %%dDII%F ))2 $$,$[[001J1JK
//>..t||<!22
//$d&A&A
 ++((V]]_ECKKDII./LLNN !!T).D*WdiiDMMJAzz|%&=>>r9   )NNr  NNTNNFFNNNN)rV   rW   rX   rT  r`   r   r  rx  ry  s   @rT   r  r     sF      "'#H#T	Mr9   r  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 serverc                 @    t        |   di | || _        || _        y r[  )ra  r`   pathr   )rO   r  r   r   r   s       rT   r`   z#UnixDomainSocketConnection.__init__  s"    "6"	,r9   c                     d| j                   fd| j                  fg}| j                  r|j                  d| j                  f       |S )Nr  r   r   )r  r   r   rH   rc  s     rT   rs   z&UnixDomainSocketConnection.repr_pieces  sB    499%dgg7MM=$*:*:;<r9   c                    t        j                   t         j                  t         j                        }|j                  | j                         	 |j                  | j                         |j                  | j                         |S # t        $ rB 	 |j                  t         j                         n# t        $ r Y nw xY w|j                           w xY w)z&Create a Unix domain socket connection)r  AF_UNIXrf  rm  r   r   r  r  r%  r&  r'  r   )rO   r  s     rT   r   z#UnixDomainSocketConnection._connect  s    }}V^^V-?-?@334		LL# 	++,  	f../ JJL	s0   B 	CB10C1	B=:C<B==Cc                     | j                   S r]   )r  rr   s    rT   r  z&UnixDomainSocketConnection._host_error  s    yyr9   ) Nrw  ry  s   @rT   r   r     s    :-
"r9   r   )0FFALSENNOc                 v    | | dk(  ry t        | t              r| j                         t        v ryt	        |       S )Nr  F)rC   rD   upperFALSE_STRINGSrV  )rR   s    rT   to_boolr    s4    }%%++-="@;r9   )
r   r   r   r^  r   r   max_connectionsr   r  r   c                 B   | j                  d      s-| j                  d      s| j                  d      st        d      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                   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 # t        t        f$ r t        d| d      w xY w# t(        t        f$ r Y Mw xY w)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.r   r   unixr  connection_classr\  r]  r   /r  rediss)
startswithr   r   r   queryrl  re   r   URL_QUERY_ARGUMENT_PARSERSr  rK   r   r   schemer  r   hostnamer]  r   replaceAttributeErrorr  )urlr   namerR   r  s        rT   	parse_urlr     s   z">>+&>>)$5
 	

 3-CF		*002 
%eSZ!^E!H%E/33D9FW#)%=F4L  %t
% ||$S\\2z
||$S\\2z zzV88$SXX.F6N%?!"& M! <<$S\\2F6N88 ]F6N 88F*"7388#4#<#<S"#EFt ::!)6F%&MC ":. W$':4&@T%UVVW6 #J/ s   -G*1H *H	HH_CPConnectionPool)boundc                      e Zd ZdZedee   dedefd       Ze	ddfde
e   de
e   fd	Zdefd
Zd Zd"dZd"dZ edgdd      d#d$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eddfdZdefdZd e fd!Z!y)(r"  a  
    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.
    :py:class:`~redis.SSLConnection` can be used for SSL enabled connections.

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    clsr  rn   c                 b    t        |      }d|v r|d   |d<   |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.
        r  rY   )r   update)r%  r  r   url_optionss       rT   from_urlzConnectionPool.from_url2  s?    R  n'.45G.HK*+k"}V}r9   Nr  cache_factoryc                    |xs d}t        |t              r|dk  rt        d      || _        || _        || _        d | _        || _        |j                  d      s|j                  d      r|j                  d      dvrt        d      | j                  j                  d      }|#t        |t              st        d	      || _        nc| j                   | j                  j                         | _        n7t        | j                  j                  d            j                         | _        |j                  dd        |j                  dd        | j                  j                  d
d       | _        | j                  t               | _        t!        j"                         | _        t!        j"                         | _        | j)                          y )Nl        r   z,"max_connections" must be a positive integercache_configr~  r   )r   r@  z4Client caching is only supported with RESP version 3z#Cache must implement CacheInterfacer   )rC   r   r   r  connection_kwargsr  r~  _cache_factoryr  r*   r   	get_cacher   popr   r#   r  r  
_fork_lock_lockreset)rO   r  r  r*  r-  r~  s         rT   r`   zConnectionPool.__init__c  s    *2U/3/?Q3FKLL 0!2.
+  04E4I4I'4R $$Z0@ !WXX**..w7E !%8$%JKK"
&&2!%!4!4!>!>!@DJ!-..22>B"ik J 	gt,nd3!%!7!7!;!;<NPT!U!!)%4%6D" $//+__&


r9   c                 T   dj                  | j                  j                         D cg c]  \  }}| d|  c}}      }d| j                  j                   d| j                  j
                   d| j                  j                   d| j                  j
                   d| dS c c}}w )Nr   r   r   r   z(<r   z)>)>)rc   r-  rl  r   rW   rV   r  )rO   r   r   conn_kwargss       rT   r   zConnectionPool.__repr__  s    hht7M7M7S7S7UVtq!1#Qqc
VW))*!DNN,C,C+D&&112!D4I4I4R4R3S}D"	
  Ws   B$
c                 :    | j                   j                  dd      S )z
        Returns:
            The RESP protocol version, or ``None`` if the protocol is not specified,
            in which case the server default will be used.
        r   N)r-  r  rr   s    rT   r   zConnectionPool.get_protocol  s     %%))*d;;r9   c                 p    d| _         g | _        t               | _        t	        j
                         | _        y )Nr   )_created_connections_available_connectionsr  _in_use_connectionsr   r   r   rr   s    rT   r3  zConnectionPool.reset  s+    $%!&(##&5  99;r9   c                 f   | j                   t        j                         k7  rq| j                  j	                  d      }|st
        	 | j                   t        j                         k7  r| j                          | j                  j                          y y # | j                  j                          w xY w)N   )r   )r   r   r   r1  acquirer&   r3  release)rO   acquireds     rT   	_checkpidzConnectionPool._checkpid  s    F 88ryy{"..q.9H***88ryy{*JJL'') # '')s   1B B0*)Use get_connection() without args instead5.3.0args_to_warnreasonr  rY  c                 n   | j                          | j                  5  	 | j                  j                         }| j                  j                  |       ddd       	 j                          	 |j                         r| j                  t        d      |S # t        $ r | j                         }Y yw xY w# 1 sw Y   cxY w# t        t        t        f$ r? |j                          |j                          |j                         rt        d      Y |S w xY w# t        $ r | j!                          w xY w)zGet a connection from the poolNConnection has dataConnection not ready)r@  r2  r9  r0  
IndexErrormake_connectionr:  addr   r   r~  r'   r,   r  r   r7  r>  rO   command_namer  options
connections        rT   get_connectionzConnectionPool.get_connection  s/    	ZZ 	54!88<<>
 $$((4	5	 
B&&(TZZ-?)*?@@ 3  4!113
4	5 	5" $\7; B%%'""$&&()*@AA ) B
  	 LL$		sX   B6BB6D .'C B30B62B33B66B?ADD DD D4c                     | j                   }t        |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  )rO   r   s     rT   get_encoderzConnectionPool.get_encoder  sF    ''ZZ
G4"JJ'8(C#ZZ(:EB
 	
r9   c                 :   | j                   | j                  k\  rt        d      | xj                   dz  c_         | j                  ;t	         | j
                  di | j                  | j                  | j                        S  | j
                  di | j                  S )zCreate a new connectionzToo many connectionsr   rY   )r8  r  r)   r~  r{  r  r-  r2  rr   s    rT   rK  zConnectionPool.make_connection  s    $$(<(<<%&<==!!Q&!::!'%%%?(>(>?TZZ  %t$$>t'='=>>r9   rP  c                    | j                          | j                  5  	 | j                  j                  |       | j                  |      r@| j                  j                  |       | j                  j                  t        |             n|j                          	 ddd       y	 ddd       y# t        $ r Y ddd       yw xY w# 1 sw Y   yxY w)z(Releases the connection back to the poolN)r@  r2  r:  r   KeyErrorowns_connectionr9  rH   r   dispatchr"   r   rO   rP  s     rT   r>  zConnectionPool.release(  s    ZZ 	((//
; ##J/++22:>&&//0< %%''	 		 	   	 		 	s.   CB/A"C/	C8CCCCc                 4    |j                   | j                   k(  S r]   )r   rY  s     rT   rW  zConnectionPool.owns_connection@  s    ~~))r9   inuse_connectionsc                     | j                          | j                  5  |r!t        | j                  | j                        }n| j                  }|D ]  }|j                           	 ddd       y# 1 sw Y   yxY w)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@  r2  r   r9  r:  r   )rO   r[  connectionsrP  s       rT   r   zConnectionPool.disconnectC  sp     	ZZ 		( #//1I1I #99) (
%%'(		( 		( 		(s   AA..A7c                 $    | j                          y)z-Close the pool, disconnecting all connectionsNr   rr   s    rT   r'  zConnectionPool.closeW  r0  r9   r   c                     | j                   j                  d|i       | j                  D ]	  }||_         | j                  D ]	  }||_         y )Nr   )r-  r'  r9  r   r:  )rO   r   r}  s      rT   	set_retryzConnectionPool.set_retry[  sS    %%w&67// 	DDJ	,, 	DDJ	r9   r   c                 >     j                   5   j                  D ]G  j                  j                  fd fd       j                  j                  fd fd       I  j                  D ]  j                          	 d d d        y # 1 sw Y   y xY w)Nc                  d     j                  dj                  d      j                               S rP  )r   rR  rS  )r}  r   s   rT   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>f  s)    D--e 4eoo6G r9   c                 &    j                  |       S r]   _mockr   s    rT   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>i  s    $**U"3 r9   c                  $     j                         S r]   )r   )r}  s   rT   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>l  s    D..0 r9   c                 &    j                  |       S r]   rd  r   s    rT   r   z1ConnectionPool.re_auth_callback.<locals>.<lambda>l  s    

5@Q r9   )r2  r9  r   r  r:  r   )rO   r   r}  s   ``@rT   re_auth_callbackzConnectionPool.re_auth_callbackb  s    ZZ 	.33 	

** 4	 

**02Q	 00 .&&u-.	. 	. 	.s   A9BBr  c                    K   yw)z
        Dummy functions, needs to be passed as error callback to retry object.
        :param error:
        :return:
        NrY   r.  s     rT   re  zConnectionPool._mockq  s      	s   rm   r]   )rn   rY  )rn   rp   )rP  rY  rn   Nr   )"rV   rW   rX   rT  classmethodr   r!  rD   r)  rY  r   r   r   r`   r   r   r3  r@  r2   rQ  r   rS  rK  r>  rW  rV  r   r'  r-   r`  r   rh  r*   re  rY   r9   rT   r"  r"  #  s    .d3i .c . . .d $)-9=	7 "#7   56	7r
# 
< -*^ U:
 
 D
W 
?0*, *3 *(D (D ((u  .n . r9   c                   j     e Zd ZdZddeef fd	Zd Zd Z e	dgdd	
      d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                 F    || _         || _        t        |   d||d| y )N)r  r  rY   )queue_classr   ra  r`   )rO   r  r   r  rp  r-  r   s         rT   r`   zBlockingConnectionPool.__init__  s6     ' 	
-+	
  	
r9   c                     | j                  | j                        | _        	 	 | j                  j                  d        # t        $ r Y nw xY wg | _        t        j                         | _        y r]   )	rp  r  pool
put_nowaitr   _connectionsr   r   r   rr   s    rT   r3  zBlockingConnectionPool.reset  sf    $$T%9%9:			$$T*   
  99;s   ? 	A
Ac                    | j                   <t         | j                  di | j                  | j                   | j                        }n | j                  di | j                  }| j
                  j                  |       |S )zMake a fresh connection.rY   )r~  r{  r  r-  r2  rt  rH   rY  s     rT   rK  z&BlockingConnectionPool.make_connection  sr    ::!-%%%?(>(>?TZZJ /..H1G1GHJ  ,r9   rA  rB  rC  rD  c                    | j                          d}	 | j                  j                  d| j                        }|| j                         }	 |j                          	 |j                         rt        d      	 |S # t        $ r t        d      w xY w# t
        t        t        f$ r? |j                          |j                          |j                         rt        d      Y |S w xY w# t        $ r | j                  |        w xY w)a7  
        Get a connection, blocking for ``self.timeout`` until a connection
        is available from the pool.

        If the connection returned is ``None`` then creates a new connection.
        Because we use a last-in first-out queue, the existing connections
        (having been returned to the pool after the initial ``None`` values
        were added) will be returned before ``None`` values. This means we only
        create new connections when we need to, i.e.: the actual number of
        connections will only increase in response to demand.
        NT)blockr   zNo connection available.rH  rI  )r@  rr  r  r   r   r'   rK  r   r   r,   r  r   r7  r>  rM  s        rT   rQ  z%BlockingConnectionPool.get_connection  s   $ 	 
	>T4<<HJ --/J	 
B&&()*?@@ ) =  	> ""<==	>( $\7; B%%'""$&&()*@AA ) B
  	LL$	s6   'A= C+ B =BAC($C+ 'C((C+ +Dc                     | j                          | j                  |      s,|j                          | j                  j	                  d       y	 | j                  j	                  |       y# t
        $ r Y yw xY w)z)Releases the connection back to the pool.N)r@  rW  r   rr  rs  r   rY  s     rT   r>  zBlockingConnectionPool.release  sj     	##J/
 !!#II  &	II  , 	 	s   A+ +	A76A7c                 f    | j                          | j                  D ]  }|j                           y)z(Disconnects all connections in the pool.N)r@  rt  r   rY  s     rT   r   z!BlockingConnectionPool.disconnect  s-    ++ 	$J!!#	$r9   r]   )rV   rW   rX   rT  rY  r   r`   r3  rK  r2   rQ  r>  r   rx  ry  s   @rT   rl  rl  z  sU    F #
 0	 U:
2
2h*$r9   rl  )er   r   r  rL   r  r2  r   abcr   	itertoolsr   queuer   r   r   typingr   r	   r
   r   r   r   r   r   urllib.parser   r   r   redis.cacher   r   r   r   r   r   _parsersr   r   r   r   
auth.tokenr   backoffr   credentialsr    r!   eventr"   r#   
exceptionsr$   r%   r&   r'   r(   r)   r*   r+   r,   r   r-   utilsr.   r/   r0   r1   r2   r3   r4   r5   r6   r  rI   rd   ri   rf   rb   r   objectr   __annotations__r;   r=   r[   rp   r   rY  r{  r  r   r  r  r   rU  listr  r   r!  r"  rl  rY   r9   rT   <module>r     s    	  
      ( ( L L L 4 4  J I &  O @
 
 
 
 
 
 
C
	 8E,nDEF F"M M $0 0fN Nb{', {'|G*# G*TS. SlhJ hV !3  F / # ! 6r e+,T Tn
g$^ g$r9   