
    Iis                        % S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKJr  S SK	J
r
  S SKJrJrJr  S SKJr  S SKJrJrJrJrJrJrJr  S SKJrJrJr  S SKJrJrJrJ r J!r!J"r"  S	S
K#J$r$J%r%J&r&J'r'  S	SK(J)r)  S	SK*J+r+J,r,  S	SK-J.r.J/r/J0r0J1r1J2r2J3r3J4r4J5r5  S	SK6J7r7  S	SK8J9r9J:r:J;r;J<r<J=r=J>r>J?r?J@r@  \:(       a  S SKArASrBSrCSrDSrESrF\G" 5       rH\\\&\'\%4      \IS'   \:(       a  \%rJO\&rJ " S S5      rK " S S5      rL " S S5      rM " S S\M5      rN " S S\N5      rO " S  S!\M5      rP " S" S#\O5      rQ " S$ S%\N5      rRS&rSS' rT\U\V\V\T\T\W\U\U\T\VS(.
rXS) rY " S* S+5      rZ " S, S-\Z5      r[g).    N)abstractmethod)chain)EmptyFull	LifoQueue)time)AnyCallableDictListOptionalTypeUnion)parse_qsunquoteurlparse)
CacheEntryCacheEntryStatusCacheFactoryCacheFactoryInterfaceCacheInterfaceCacheKey   )Encoder_HiredisParser_RESP2Parser_RESP3Parser)	NoBackoff)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorChildDeadlockedErrorConnectionError	DataError
RedisErrorResponseErrorTimeoutError)Retry)CRYPTOGRAPHY_AVAILABLEHIREDIS_AVAILABLESSL_AVAILABLEcompare_versionsensure_stringformat_error_messageget_lib_versionstr_if_bytes   *   $s   
       DefaultParserc                   "    \ rS rSrS\4S jrSrg)HiredisRespSerializerD   argsc                    / n[        US   [        5      (       a1  [        US   R                  5       R	                  5       5      USS -   nO+SUS   ;   a"  [        US   R	                  5       5      USS -   n UR                  [        R                  " U5      5        U$ ! [         a3    [        R                  " 5       u  p4n[        U5      R                  U5      ef = f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         6/venv/lib/python3.13/site-packages/redis/connection.pypackHiredisRespSerializer.packE   s    d1gs##a)//12T!"X=DT!W_a)DH4D	=MM'..t45
 	  	="%,,.AiE"11)<<	=s   8%B =C N)__name__
__module____qualname____firstlineno__r   rQ   __static_attributes__rS   r4   rP   r8   r8   D   s    $ r4   r8   c                   $    \ rS rSrSS jrS rSrg)PythonRespSerializerV   Nc                     Xl         X l        g N_buffer_cutoffrB   )rK   buffer_cutoffrB   s      rP   __init__PythonRespSerializer.__init__W   s    +r4   c           	         / n[        US   [        5      (       a1  [        US   R                  5       R	                  5       5      USS -   nO+SUS   ;   a"  [        US   R	                  5       5      USS -   n[
        R                  [        [        [        U5      5      R                  5       [        45      nU R                  n[        U R                  U5       H  n[        U5      n[        U5      U:  d  Xd:  d  [        U[        5      (       ab  [
        R                  U[        [        U5      R                  5       [        45      nUR                  U5        UR                  U5        [        nM  [
        R                  U[        [        U5      R                  5       [        U[        45      nM     UR                  U5        U$ r<   )r?   r@   rA   rB   rC   	SYM_EMPTYjoinSYM_STARlenSYM_CRLFr_   map
memoryview
SYM_DOLLARrD   )rK   r:   rL   buffr`   arg
arg_lengths          rP   rQ   PythonRespSerializer.pack[   sh    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r4   r^   returnN)rT   rU   rV   rW   ra   rQ   rX   rS   r4   rP   rZ   rZ   V   s    +r4   rZ   c                   L   \ rS rSr\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       r\S	 5       r\SS j5       r\S 5       r\SS j5       r\ SS
SS.S jj5       r\S 5       r\S 5       r\\S\\\\4   \\\4   4   4S j5       5       rSrg)ConnectionInterface   c                     g r]   rS   rK   s    rP   repr_piecesConnectionInterface.repr_pieces       r4   c                     g r]   rS   rK   callbacks     rP   register_connect_callback-ConnectionInterface.register_connect_callback   ry   r4   c                     g r]   rS   r{   s     rP   deregister_connect_callback/ConnectionInterface.deregister_connect_callback   ry   r4   c                     g r]   rS   rK   parser_classs     rP   
set_parserConnectionInterface.set_parser   ry   r4   c                     g r]   rS   rv   s    rP   connectConnectionInterface.connect   ry   r4   c                     g r]   rS   rv   s    rP   
on_connectConnectionInterface.on_connect   ry   r4   c                     g r]   rS   rK   r:   s     rP   
disconnectConnectionInterface.disconnect   ry   r4   c                     g r]   rS   rv   s    rP   check_health ConnectionInterface.check_health   ry   r4   Tc                     g r]   rS   rK   commandr   s      rP   send_packed_command'ConnectionInterface.send_packed_command   ry   r4   c                     g r]   rS   rK   r:   kwargss      rP   send_command ConnectionInterface.send_command   ry   r4   c                     g r]   rS   rK   timeouts     rP   can_readConnectionInterface.can_read   ry   r4   Fdisconnect_on_errorpush_requestc                    g r]   rS   )rK   disable_decodingr   r   s       rP   read_response!ConnectionInterface.read_response   s     	r4   c                     g r]   rS   r   s     rP   rF    ConnectionInterface.pack_command   ry   r4   c                     g r]   rS   rK   commandss     rP   pack_commands!ConnectionInterface.pack_commands   ry   r4   rq   c                     g r]   rS   rv   s    rP   handshake_metadata&ConnectionInterface.handshake_metadata   s     	r4   rS   NTr   F)rT   rU   rV   rW   r   rw   r}   r   r   r   r   r   r   r   r   r   r   rF   r   propertyr   r   bytesr@   r   rX   rS   r4   rP   rs   rs      sh                           !      E$ue|*<d38n*L$M   r4   rs   c            *       `   \ rS rSrSrSSSSS\SSS\SSSS	\" 5       SSSSS
S4S\S\	\
   S\	\   S\	\   S\S\
S\
S\S\S\S\	\
   S\	\
   S\	\
   S\	\
   S\\S4   S\	\/ S4      S\	\   S\	\   S\	\/ S4      4&S jjrS r\S  5       rS! rS" rS# rS$ rS% rS& r\S' 5       r\S( 5       rS) rS* rS+ rS, r S- r!S. r"S=S0 jr#S1 r$S>S2 jr% S?S/SS3.S4 jjr&S5 r'S6 r(S7\=(       d    \
4S8 jr)\*S7\\+\,\,4   \+\
\
4   4   4S9 j5       r-\-R\                  S:\\+\,\,4   \+\
\
4   4   4S; j5       r-S<r/g)@AbstractConnection   z0Manages communication to and from a Redis serverr   NFutf-8stricti   zredis-pyr5   dbpasswordsocket_timeoutsocket_connect_timeoutretry_on_timeoutencodingencoding_errorsdecode_responsessocket_read_sizehealth_check_intervalclient_namelib_namelib_versionusernameretryredis_connect_funccredential_providerprotocolcommand_packerc                    U(       d  U(       a  Ub  [        S5      e[        R                  " 5       U l        Xl        Xl        Xl        Xl        UU l        X l	        UU l
        X0l        Uc  UnX@l        XPl        U[        L a  / nU(       a  UR                  [         5        X`l        U(       d  U(       aT  Uc  [%        ['        5       S5      U l        O[*        R,                  " U5      U l        U R(                  R/                  U5        O[%        ['        5       S5      U l        Xl        SU l        UU l        [7        XxU	5      U l        SU l        SU l        Xl        U RA                  U
5        / U l!        SU l"         [G        U5      nUS:  d  US:  a  [O        S	5      eUU l(        U RS                  U5      U l*        g! [H         a	    [J        n NG[L         a    [O        S5      ef = f! WS:  d  US:  a  [O        S	5      eUU l(        f = f)
a  
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 integerr5      zprotocol must be either 2 or 3)+r%   osgetpidpidr   r   r   r   r   r   r   r   r   r   SENTINELrD   r(   retry_on_errorr)   r   r   copydeepcopyupdate_supported_errorsr   next_health_checkr   r   encoderr   _sock_socket_read_sizer   _connect_callbacksr_   intrG   DEFAULT_RESP_VERSION
ValueErrorr$   r   _construct_command_packer_command_packer)rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ps                          rP   ra   AbstractConnection.__init__   s   > &9&E+  99;& &#6   ,!)%3"&<# 0X%N!!,/,N}"9;2
 "]]51
JJ..~>y{A.DJ%:"!""4x:JK"&
!1%"$"
	HA 1uA%&FGGDM#==nM  	%$A 	A!"?@@	A 1uA%&FGGDMs$   ;F; ;G"G% G""G% % Hc           	          SR                  U R                  5        VVs/ s H  u  pU SU 3PM     snn5      nSU R                  R                   SU R                  R                   SU S3$ s  snnf )N,=<.()>)re   rw   	__class__rU   rT   )rK   kv	repr_argss       rP   __repr__AbstractConnection.__repr__+  sn    HHT5E5E5GH5GTQ1QCj5GHI	4>>,,-Qt~~/F/F.GqSUVV Is   A.
c                     g r]   rS   rv   s    rP   rw   AbstractConnection.repr_pieces/  ry   r4   c                 F     U R                  5         g ! [         a     g f = fr]   )r   	Exceptionrv   s    rP   __del__AbstractConnection.__del__3  s#    	OO 		s    
  c                     Ub  U$ [         (       a
  [        5       $ [        U R                  U R                  R
                  5      $ r]   )r+   r8   rZ   r_   r   rB   )rK   packers     rP   r   ,AbstractConnection._construct_command_packer9  s9    M(**'(;(;T\\=P=PQQr4   c                     [         R                  " U5      nX R                  ;  a  U R                  R                  U5        gg)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   rD   )rK   r|   wms      rP   r}   ,AbstractConnection.register_connect_callbackA  s9     ),,,##**2. -r4   c                      U R                   R                  [        R                  " U5      5        g! [         a     gf = f)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   r{   s     rP   r   .AbstractConnection.deregister_connect_callbackM  s8    	##**7+=+=h+GH 		s   /2 
??c                 .    U" U R                   S9U l        g)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     rP   r   AbstractConnection.set_parserX  s     $T5K5KLr4   c                 t  ^  T R                   (       a  g T R                  R                  U 4S jU 4S j5      nUT l          T R                  c  T R                  5         OT R                  T 5         T R                   Vs/ s H  o3" 5       (       d  M  UPM     snT l        T R                   H  nU" 5       nU(       d  M  U" T 5        M     g! [        R                   a    [        S5      e[         a  n[        T R                  U5      5      eSnAff = f! [         a    T R                  5         e f = fs  snf )z5Connects to the Redis server if not already connectedNc                  $   > T R                  5       $ r]   )_connectrv   s   rP   <lambda>,AbstractConnection.connect.<locals>.<lambda>f  s    r4   c                 &   > TR                  U 5      $ r]   r   )errorrK   s    rP   r  r  f  s    tu7Mr4   zTimeout connecting to server)r   r   call_with_retrysocketr   r(   OSErrorr$   _error_messager   r   r&   r   r   )rK   sockerefr|   s   `    rP   r   AbstractConnection.connect`  s
   ::	:::--')MD 

	&&.! ''- 372I2I"S2I3SU32I"S**CuHx +- ~~ 	?=>> 	:!$"5"5a"899	:  	OO	 #Ts5   $C D D ?D5D5(D4DDD2c                     g r]   rS   rv   s    rP   r
  AbstractConnection._connect  ry   r4   c                     g r]   rS   rv   s    rP   _host_errorAbstractConnection._host_error  ry   r4   c                 6    [        U R                  5       U5      $ r]   )r/   r  )rK   	exceptions     rP   r  !AbstractConnection._error_message  s    #D$4$4$6	BBr4   c                    U R                   R                  U 5        U R                   nSnU R                  (       d"  U R                  (       d  U R                  (       aC  U R                  =(       d     [        U R                  U R                  5      nUR                  5       nU(       a  U R                  S;  a  [        U R                   [        5      (       aK  U R                  [        5        UR                  U R                   l        U R                   R                  U 5        [        U5      S:X  a  SUS   /nU R                  " SU R                  S/UQ76   U R                  5       U l        GORU(       aC  U R                  " S/UQ7SS	06   U R                  5       n[%        U5      S:w  a  ['        S5      eGOU R                  S;  a  [        U R                   [        5      (       aK  U R                  [        5        UR                  U R                   l        U R                   R                  U 5        U R                  SU R                  5        U R                  5       U l        U R                   R)                  S5      U R                  :w  a4  U R                   R)                  S5      U R                  :w  a  [+        S5      eU R,                  (       aE  U R                  SSU R,                  5        [%        U R                  5       5      S:w  a  [+        S5      e U R.                  (       a.  U R                  SSSU R.                  5        U R                  5          U R2                  (       a.  U R                  SSSU R2                  5        U R                  5         U R4                  (       aE  U R                  SU R4                  5        [%        U R                  5       5      S:w  a  [+        S5      egg! ["         a(    U R                  SUS
   S	S9  U R                  5       n GNf = f! [0         a     Nf = f! [0         a     Nf = f)z=Initialize the connection, authenticate and select a databaseN)r5   2r   defaultr   HELLOAUTHr   Fr   OKzInvalid Username or Passwords   protoprotozInvalid RESP versionCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTzInvalid Database)r  r   r   r   r   r    get_credentialsr   r?   r   r   r   EXCEPTION_CLASSESrg   r   r   r   r"   r1   r!   getr$   r   r   r'   r   r   )rK   parser	auth_argscred_providerauth_responses        rP   r   AbstractConnection.on_connect  sd   %	##(( T5dmmT]]S  &557I h6$,,55-171I1I.''-9~"&	!5	gt}}fIyI&*&8&8&:D#
  fEyEuE5 $ 2 2 4 M*d2)*HII 3 ]](*$,,55-171I1I.''-gt}}5&*&8&8&:D#''++H5F++//8DMMI%&<== h	43C3CDD..01T9%&ABB	}}!!(Iz4==Q""$	!!(Iy$BRBRS""$
 77h0D..01T9%&899 : a 8 5
 !!&)B-e!L $ 2 2 45J  		  		s6   O, ?P! ?P1 ,.PP!
P.-P.1
P>=P>c                 Z   U R                   R                  5         U R                  nSU l        Uc  g[        R                  " 5       U R
                  :X  a    UR                  [        R                  5         UR                  5         g! [        [        4 a     N$f = f! [         a     gf = f)z!Disconnects from the Redis serverN)r  on_disconnectr   r   r   r   shutdownr  	SHUT_RDWRr  rG   close)rK   r:   	conn_socks      rP   r   AbstractConnection.disconnect  s    ""$JJ	
99;$(("""6#3#34	OO	 Y' 
  		s$   B 6B BB
B*)B*c                 t    U R                  SSS9  [        U R                  5       5      S:w  a  [        S5      eg)z Send PING, expect PONG in returnPINGFr&  PONGz#Bad response from PING health checkN)r   r1   r   r$   rv   s    rP   
_send_pingAbstractConnection._send_ping  s<    &u5**,-7!"GHH 8r4   c                 $    U R                  5         g)z Function to call when PING failsNr  )rK   r  s     rP   _ping_failedAbstractConnection._ping_failed      r4   c                     U R                   (       aJ  [        5       U R                  :  a1  U R                  R	                  U R
                  U R                  5        ggg)z3Check the health of the connection with a PING/PONGN)r   r   r   r   r  r?  rB  rv   s    rP   r   AbstractConnection.check_health  sA    %%$&43I3I*IJJ&&t8I8IJ +J%r4   Tc                 v   U R                   (       d  U R                  5         U(       a  U R                  5          [        U[        5      (       a  U/nU H  nU R                   R                  U5        M      g! [        R                   a    U R                  5         [        S5      e[         ao  nU R                  5         [        UR                  5      S:X  a  SUR                  S   peOUR                  S   nUR                  S   n[        SU SU S35      eSnAf[         a    U R                  5         e f = f)	z2Send an already packed command to the Redis serverzTimeout writing to socketr   UNKNOWNr   zError z while writing to socket. r   N)r   r   r   r?   r@   sendallr  r   r   r(   r  rg   r:   r$   BaseException)rK   r   r   itemr  errnoerrmsgs          rP   r   &AbstractConnection.send_packed_command  s    zzLLN	'3''")

""4(  ~~ 	<OO:;; 	WOO166{a )166!9vq	!F5'1KF8ST"UVV 	
 OO	s   <A7 78D8/A*DD8c                 r    U R                  U R                  R                  " U6 UR                  SS5      S9  g)z+Pack and send a command to the Redis serverr   Tr&  N)r   r   rQ   r/  r   s      rP   r   AbstractConnection.send_command*  s7        %%t,ND9 	! 	
r4   c                    U R                   nU(       d  U R                  5         U R                  5       n U R                  R	                  U5      $ ! [
         a0  nU R                  5         [        SU SUR                   35      eSnAff = f)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:   )rK   r   r  
host_errorr  s        rP   r   AbstractConnection.can_read1  sy    zzLLN%%'
	V<<((11 	VOO!$=j\AFF8"TUU	Vs   A 
B
+BB
r   c                   U R                  5       n U R                  S;   a%  [        (       d  U R                  R	                  XS9nOU R                  R	                  US9n U R                  (       a  [        5       U R                  -   U l        [!        U["        5      (       a   UeU$ ! [
        R                   a&    U(       a  U R                  5         [        SU 35      e[         a7  nU(       a  U R                  5         [        SU SUR                   35      eSnAf[         a    U(       a  U R                  5         e f = f! Af = f)z0Read the response from a previously sent command)3r   )r   r   )r   zTimeout reading from rR  z : N)r  r   r+   r  r   r  r   r   r(   r  r$   r:   rJ  r   r   r   r?   r'   )rK   r   r   r   rS  responser  s          rP   r    AbstractConnection.read_response?  s,    %%'
	}}(1B1B<<55%5 6   <<55GW5X& %%%)Vd.H.H%HD"h.. 5 ~~ 	E"!!6zlCDD 	"!!+J<3qvvhG   	 #!	 s*   4B( B( $E (AE*2D&EEc                 4    U R                   R                  " U6 $ )r=   )r   rQ   r   s     rP   rF   AbstractConnection.pack_commandm  s    ##(($//r4   c                    / n/ nSnU R                   nU H  nU R                  R                  " U6  H  n[        U5      nXE:  d  X:  d  [	        U[
        5      (       a/  U(       a$  UR                  [        R                  U5      5        Sn/ nX:  d  [	        U[
        5      (       a  UR                  U5        M  UR                  U5        XH-  nM     M     U(       a$  UR                  [        R                  U5      5        U$ )z.Pack multiple commands into the Redis protocolr   )	r_   r   rQ   rg   r?   rj   rD   rd   re   )	rK   r   rL   piecesbuffer_lengthr`   cmdchunkchunklens	            rP   r    AbstractConnection.pack_commandsq  s    ++C--22C8u:!1/!%44innV&<=$%MF+z%/L/LMM%(MM%(!-M! 9 & MM)..01r4   rq   c                     U R                   $ r]   )r   rv   s    rP   get_protocolAbstractConnection.get_protocol  s    }}r4   c                     U R                   $ r]   _handshake_metadatarv   s    rP   r   %AbstractConnection.handshake_metadata  s    '''r4   rN   c                     Xl         g r]   rf  )rK   rN   s     rP   r   rh    s    #( r4   )r_   r   r   rg  r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )0rT   rU   rV   rW   __doc__r   r6   r0   r   r   r@   floatboolr   r	   r
   r   ra   r   r   rw   r   r   r}   r   r   r   r
  r  r  r   r   r?  rB  r   r   r   r   r   rF   r   rc  r   r   r   r   setterrX   rS   r4   rP   r   r      s   6 "&*.26!&'!&" %%&%)",%4%6"&"&;?<@"#7;-XNXN 3-XN !	XN
 !)XN XN XN XN XN XN  #XN c]XN 3-XN  c]!XN" 3-#XN$ S$Y%XN& %Xb$h%78'XN( &&89)XN* 3-+XN, !"d(!34-XNtW  R
/	M!F    CX:t(IK
>
V  , !,\0<cjS  (E$ue|*<d38n*L$M ( ( )d5%<.@$sCx..P(Q ) )r4   r   c                   L   ^  \ rS rSrSr     SU 4S jjrS rS rS rSr	U =r
$ )	
Connectioni  z4Manages TCP communication to and from a Redis serverc                    > Xl         [        U5      U l        X0l        U=(       d    0 U l        XPl        [        TU ]  " S0 UD6  g NrS   )hostr   portsocket_keepalivesocket_keepalive_optionssocket_typesuperra   )rK   rr  rs  rt  ru  rv  r   r   s          rP   ra   Connection.__init__  s>     	I	 0(@(FB%&"6"r4   c                     SU R                   4SU R                  4SU R                  4/nU R                  (       a  UR	                  SU R                  45        U$ )Nrr  rs  r   r   )rr  rs  r   r   rD   rK   r\  s     rP   rw   Connection.repr_pieces  sM    499%		':T477OLMM=$*:*:;<r4   c                 `   Sn[         R                  " U R                  U R                  U R                  [         R
                  5       GH  nUu  p4pVnSn [         R                   " X4U5      nUR                  [         R                  [         R                  S5        U R                  (       ar  UR                  [         R                  [         R                  S5        U R                  R                  5        H%  u  pUR                  [         R                  X5        M'     UR                  U R                  5        UR!                  U5        UR                  U R"                  5        Us  $    Ub  Ue[%        S5      e! [$         a(  nUnUb  UR'                  5          SnAGMY   SnAGM`  SnAff = f)zCreate a TCP socket connectionNr   z)socket.getaddrinfo returned an empty list)r  getaddrinforr  rs  rv  SOCK_STREAM
setsockoptIPPROTO_TCPTCP_NODELAYrt  
SOL_SOCKETSO_KEEPALIVEru  items
settimeoutr   r   r   r  r9  )rK   errresfamilysocktyper(  	canonnamesocket_addressr  r   r   rM   s               rP   r
  Connection._connect  sX   
 %%IItyy$"2"2F4F4F
C BE>FeD!}}Vu= 2 2F4F4FJ ((OOF$5$5v7J7JAN $ = = C C E(:(:AA !F  ; ;< ^,  3 341
> ?IABB  !#JJLL $!s   DE;;
F-F((F-c                 8    U R                    SU R                   3$ )N:)rr  rs  rv   s    rP   r  Connection._host_error  s    ))Adii[))r4   )rr  rs  rt  ru  rv  )	localhosti  FNr   rT   rU   rV   rW   rj  ra   rw   r
  r  rX   __classcell__r   s   @rP   ro  ro    s2    : !%# 'CR* *r4   ro  c                   :   \ rS rSrSrSrSrS\S\S\	R                  4S jrS	 rS
 rS rS rS rS rS rS rS$S jrS rS%S jr S&SSS.S jjrS rS r\S\\\\4   \\\4   4   4S j5       rS r S r!S\SS4S jr"S  r#S!\$\\\%\$\      4      4S" jr&S#r'g)'CacheProxyConnectioni  s   fooz7.4.0redisconncache	pool_lockc                    [         R                  " 5       U l        Xl        U R                  R                  U l        U R                  R
                  U l        U R                  R                  U l        X0l        X l        [        R                  " 5       U l        S U l        S U l        U R                  U R                  5        g r]   )r   r   r   _connr   rr  rs  
_pool_lock_cache	threadingLock_cache_lock_current_command_cache_key_current_optionsr}   _enable_tracking_callback)rK   r  r  r  s       rP   ra   CacheProxyConnection.__init__  s     99;
ZZ%%
JJOO	JJOO	#$>>+*.' $&&t'E'EFr4   c                 6    U R                   R                  5       $ r]   )r  rw   rv   s    rP   rw    CacheProxyConnection.repr_pieces  s    zz%%''r4   c                 :    U R                   R                  U5        g r]   )r  r}   r{   s     rP   r}   .CacheProxyConnection.register_connect_callback  s    

,,X6r4   c                 :    U R                   R                  U5        g r]   )r  r   r{   s     rP   r   0CacheProxyConnection.deregister_connect_callback  s    

..x8r4   c                 :    U R                   R                  U5        g r]   )r  r   r   s     rP   r   CacheProxyConnection.set_parser  s    

l+r4   c                 (   U R                   R                  5         U R                   R                  R                  SS 5      nUc&  U R                   R                  R                  SS 5      nU R                   R                  R                  SS 5      nUc&  U R                   R                  R                  SS 5      nUb  Uc  [	        S5      e[        U5      n[        U5      nXR                  :w  d  [        X R                  5      S:X  a  [	        S5      eg )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$   r.   DEFAULT_SERVER_NAMEr-   MIN_ALLOWED_VERSION)rK   server_name
server_vers      rP   r   CacheProxyConnection.connect  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 333
,D,DEJ!{  Kr4   c                 8    U R                   R                  5         g r]   )r  r   rv   s    rP   r   CacheProxyConnection.on_connect  s    

r4   c                     U R                      U R                  R                  5         S S S 5        U R                  R                  " U6   g ! , (       d  f       N(= fr]   )r  r  flushr  r   r   s     rP   r   CacheProxyConnection.disconnect  s;    KK 

t$ s   A


Ac                 8    U R                   R                  5         g r]   )r  r   rv   s    rP   r   !CacheProxyConnection.check_health#  s    

!r4   Tc                 :    U R                   R                  U5        g r]   )r  r   r   s      rP   r   (CacheProxyConnection.send_packed_command&  s     	

&&w/r4   c           
         U R                  5         U R                     U R                  R                  [	        US   SS95      (       d-  S U l        U R                  R                  " U0 UD6   S S S 5        g  S S S 5        UR                  S5      c  [        S5      e[	        US   [        UR                  S5      5      S9U l        U R                     U R                  R                  U R
                  5      (       a  U R                  R                  U R
                  5      nUR                  U R                  :w  an  U R                     UR                  R                  5       (       a:  UR                  R                  SS9  UR                  R                  5       (       a  M:  S S S 5         S S S 5        g U R                  R                  [!        U R
                  U R"                  [$        R&                  U R                  S95        S S S 5        U R                  R                  " U0 UD6  g ! , (       d  f       GN= f! , (       d  f       N= f! , (       d  f       NN= f)	Nr   rS   )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   rA   r  r  r   r   setr   DUMMY_CACHE_VALUEr   IN_PROGRESS)rK   r:   r   entrys       rP   r   !CacheProxyConnection.send_command+  s   ++- ;;**8DGPR+STT26/

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

00W 0 ) s9   AH*A6IAH<"	I4AI*
H9<
I
	I
Ic                 8    U R                   R                  U5      $ r]   )r  r   r   s     rP   r   CacheProxyConnection.can_read[  s    zz""7++r4   Fr   c                   U R                      U R                  b  U R                  R                  U R                  5      b  U R                  R                  U R                  5      R                  [
        R                  :w  aL  [        R                  " U R                  R                  U R                  5      R                  5      sS S S 5        $ S S S 5        U R                  R                  UUUS9nU R                      U R                  c  UsS S S 5        $ Uc1  U R                  R                  U R                  /5        UsS S S 5        $ U R                  R                  U R                  5      nUb6  [
        R                  Ul        XEl	        U R                  R                  U5        S S S 5        U$ ! , (       d  f       N= f! , (       d  f       U$ = f)N)r   r   r   )r  r  r  r/  r  r   r  r   r   r  r  r   delete_by_cache_keysVALIDr  )rK   r   r   r   rW  cache_entrys         rP   r   "CacheProxyConnection.read_response^  ss     //;KKOOD$C$CDPKKOOD$C$CDKK#//0 }}KKOOD$C$CDPP  ::++- 3% , 
 ..6 
 00$2Q2Q1RS  ++//$*I*IJK &%5%;%;"*2',! $ I $ $ s%   B7F2=G*G
AG2
G 
Gc                 4    U R                   R                  " U6 $ r]   )r  rF   r   s     rP   rF   !CacheProxyConnection.pack_command  s    zz&&--r4   c                 8    U R                   R                  U5      $ r]   )r  r   r   s     rP   r   "CacheProxyConnection.pack_commands  s    zz''11r4   rq   c                 .    U R                   R                  $ r]   )r  r   rv   s    rP   r   'CacheProxyConnection.handshake_metadata  s    zz,,,r4   c                 8    U R                   R                  5         g r]   )r  r
  rv   s    rP   r
  CacheProxyConnection._connect  s    

r4   c                 8    U R                   R                  5         g r]   )r  r  rv   s    rP   r   CacheProxyConnection._host_error  s    

 r4   Nc                     UR                  SSS5        UR                  5         UR                  R                  U R                  5        g )Nr)  TRACKINGON)r   r   r  set_invalidation_push_handler_on_invalidation_callback)rK   r  s     rP   r  .CacheProxyConnection._enable_tracking_callback  s8    (J52243Q3QRr4   c                     U R                  5       (       a1  U R                  R                  SS9  U R                  5       (       a  M0  g g )NTr  )r   r  r   rv   s    rP   r  3CacheProxyConnection._process_pending_invalidations  s/    mmooJJ$$$$7 mmoor4   datac                     U R                      US   c  U R                  R                  5         OU R                  R                  US   5        S S S 5        g ! , (       d  f       g = f)Nr   )r  r  r  delete_by_redis_keys)rK   r  s     rP   r  .CacheProxyConnection._on_invalidation_callback  sF    Aw!!#00a9 s   A A
A$)
r  r  r  r  r  r  rr  r   rs  r   r   r   r   )(rT   rU   rV   rW   r  r  r  rs   r   r  r  ra   rw   r}   r   r   r   r   r   r   r   r   r   r   rF   r   r   r   r   r   r@   r   r
  r  r  r  r   r   r  rX   rS   r4   rP   r  r    s   !!G!G G >>	G$(79,. %
"0
.1`,  %'=APU'R.2 -E$ue|*<d38n*L$M - -!S.A Sd S
8:d5htE{>S9S3T.U :r4   r  c                   ^   ^  \ rS rSrSr              SU 4S jjrU 4S jrS rSrU =r	$ )SSLConnectioni  zManages 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                   > [         (       d  [        S5      eXl        X l        Uc  [        R
                  nO^[        U[        5      (       aI  [        R
                  [        R                  [        R                  S.nUU;  a  [        SU 35      eUU   nX0l
        X@l        XPl        Xpl        X`l        Xl        Xl        Xl        Xl        Xl        Xl        Xl        [,        TU ]\  " S0 UD6  g)aq  Constructor

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

    ssl_validate_ocsp: If set, perform a full ocsp validation (i.e not a stapled verification)
    ssl_validate_ocsp_stapled: If set, perform a validation on a stapled ocsp response
    ssl_ocsp_context: A fully initialized OpenSSL.SSL.Context object to be used in verifying the ssl_ocsp_expected_cert
    ssl_ocsp_expected_cert: A PEM armoured string containing the expected certificate to be returned from the ocsp verification service.
    ssl_min_version: The lowest supported SSL version. It affects the supported SSL versions of the SSLContext. None leaves the default provided by ssl module.
    ssl_ciphers: A string listing the ciphers that are allowed to be used. Defaults to None, which means that the default ciphers are used. See https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_ciphers for more information.

Raises:
    RedisError
z$Python wasn't built with SSL supportN)noneoptionalrequiredz+Invalid SSL Certificate Requirements Flag: rS   )r,   r&   keyfilecertfilessl	CERT_NONEr?   r@   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_ciphersrw  ra   )rK   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                    rP   ra   SSLConnection.__init__  s    P }CDD"$ MMMs++----I
 I- A-Q  &m4M&$""0$0!!2)B& 0&<#.&"6"r4   c                    > [         TU ]  5       n U R                  U5      $ ! [        [        4 a    UR                  5         e f = f)z>
Wrap the socket with SSL support, handling potential errors.
)rw  r
  _wrap_socket_with_sslr  r&   r9  )rK   r  r   s     rP   r
  SSLConnection._connect  sH     w!	--d33$ 	JJL	s	   " "Ac                 x   [         R                  " 5       nU R                  Ul        U R                  Ul        U R
                  (       d  U R                  (       a/  UR                  U R
                  U R                  U R                  S9  U R                  c  U R                  c  U R                  b/  UR                  U R                  U R                  U R                  S9  U R                  b  U R                  Ul        U R                  (       a  UR!                  U R                  5        U R"                  SL a  [$        SL a  ['        S5      eU R(                  (       a  U R"                  (       a  ['        S5      eUR+                  XR,                  S9nU R(                  (       Ga,  S	SKnS
SKJn  U R4                  cf  UR6                  R9                  UR6                  R:                  5      nUR=                  U R
                  5        UR?                  U R                  5        OU R4                  nURA                  XPRB                  5        UR6                  RE                  U[F        RF                  " 5       5      nURI                  5         URK                  U R,                  U RL                  45        URO                  5         URQ                  5         U$ U R"                  SL a[  [$        (       aP  S
SKJ)n  U" X0R,                  U RL                  U R                  5      n	U	RU                  5       (       a  U$ [W        S5      eU$ )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_socketrr  OpenSSLocspr  r  SSLContextSSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackr  ro  r  request_ocspr   rs  do_handshaker7  r  is_validr$   )
rK   r  contextsslsockr  r  
staple_ctxconr  os
             rP   r  #SSLConnection._wrap_socket_with_ssl  sw    ,,.!%!4!4"nn==DLL##22 $  MM%||'||'))}}T\\$,, *  +&*&:&:G# 0 01!!T).D.M=>>))d.D.D 
 %%dII%F )))2 $$,$[[001J1JK
//>..t||<!22
//$&A&A
 ++((V]]_ECKKDII./LLNN !!T).D.D*WiiDMMJAzz||%&=>>r4   )r  r  r  r  r  r  r  r  r  r   r  r  r  r  )NNr  NNFNNFFNNNN)
rT   rU   rV   rW   rj  ra   r
  r  rX   r  r  s   @rP   r  r    sL       "'#F#P	M Mr4   r  c                   B   ^  \ rS rSrSrSU 4S jjrS rS rS rSr	U =r
$ )	UnixDomainSocketConnectioniR  z4Manages UDS communication to and from a Redis serverc                 >   > [         TU ]  " S0 UD6  Xl        X l        g rq  )rw  ra   pathr   )rK   r1  r   r   r   s       rP   ra   #UnixDomainSocketConnection.__init__U  s    "6"	,r4   c                     SU R                   4SU R                  4/nU R                  (       a  UR                  SU R                  45        U$ )Nr1  r   r   )r1  r   r   rD   rz  s     rP   rw   &UnixDomainSocketConnection.repr_piecesZ  sB    499%dgg7MM=$*:*:;<r4   c                 N   [         R                   " [         R                  [         R                  5      nUR                  U R                  5         UR                  U R                  5        UR                  U R                  5        U$ ! [         a    UR                  5         e f = f)z&Create a Unix domain socket connection)
r  AF_UNIXr~  r  r   r   r1  r  r9  r   )rK   r  s     rP   r
  #UnixDomainSocketConnection._connect`  sy    }}V^^V-?-?@334	LL#
 	++,  	JJL	s   B B$c                     U R                   $ r]   )r1  rv   s    rP   r  &UnixDomainSocketConnection._host_errorm  s    yyr4   )r1  r   ) Nr  r  s   @rP   r/  r/  R  s    :-
 r4   r/  )0FFALSENNOc                     U b  U S:X  a  g [        U [        5      (       a  U R                  5       [        ;   a  g[	        U 5      $ )Nr:  F)r?   r@   upperFALSE_STRINGSrl  )rN   s    rP   to_boolrC  t  s7    }%%++-="@;r4   )
r   r   r   rt  r   r   max_connectionsr   r  r   c                    U R                  S5      (       d7  U R                  S5      (       d!  U R                  S5      (       d  [        S5      e[        U 5      n 0 n[        U R                  5      R                  5        HZ  u  p#U(       d  M  [        U5      S:  d  M  [        US   5      n[        R                  U5      nU(       a   U" U5      X'   MV  X1U'   M\     U R                  (       a  [        U R                  5      US'   U R                  (       a  [        U R                  5      US	'   U R                  S
:X  a4  U R                  (       a  [        U R                  5      US'   [        US'   U$ U R                   (       a  [        U R                   5      US'   U R"                  (       a  [%        U R"                  5      US'   U R                  (       a8  SU;  a2   [%        [        U R                  5      R'                  SS5      5      US'   U R                  S:X  a	  [*        US'   U$ ! [        [        4 a    [        SU S35      ef = f! [(        [        4 a     NPf = f)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   unixr1  connection_classrr  rs  r   /r:  rediss)
startswithr   r   r   queryr  rg   r   URL_QUERY_ARGUMENT_PARSERSr/  rG   r   r   schemer1  r/  hostnamers  r   replaceAttributeErrorr  )urlr   namerN   r0  s        rP   	parse_urlrS    s   z"">>+&&>>)$$5
 	

 3-CF		*0025SZ!^E!H%E/33D9FW#)%=FL  %t 3 ||$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   
H(1I ( IIIc                       \ rS rSrSr\S 5       r\SS4S\\	   S\\
   4S jjrS\\44S	 jrS
 rSS jrSS jrS\SS4S jrS\4S jrSS jrSS jrSSS\	4S jrSS\SS4S jjrSS jrSS jrSrg)ConnectionPooli  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.

Any additional keyword arguments are passed to the constructor of
``connection_class``.
c                 f    [        U5      nSU;   a  US   US'   UR                  U5        U " S0 UD6$ )a1  
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.
rG  rS   )rS  update)clsrQ  r   url_optionss       rP   from_urlConnectionPool.from_url  s?    R  n'.45G.HK*+k"}V}r4   NrD  cache_factoryc                 *   U=(       d    Sn[        U[        5      (       a  US:  a  [        S5      eXl        X@l        X l        S U l        X0l        UR                  S5      (       d  UR                  S5      (       a  UR                  S5      S;  a  [        S5      eU R                  R                  S5      nUb'  [        U[        5      (       d  [        S	5      eXPl        OdU R                  b   U R                  R                  5       U l        O7[        U R                  R                  S5      5      R                  5       U l        UR                  SS 5        UR                  SS 5        [        R                  " 5       U l        U R#                  5         g )
Nl        r   z,"max_connections" must be a positive integercache_configr  r   )r   rV  z4Client caching is only supported with RESP version 3z#Cache must implement CacheInterface)r?   r   r   rG  connection_kwargsrD  r  _cache_factoryr/  r&   r   	get_cacher   popr  r  
_fork_lockreset)rK   rG  rD  r\  r_  r  s         rP   ra   ConnectionPool.__init__  sO    *2U/3//?Q3FKLL 0!2.
+  004E4I4I'4R4R $$Z0@ !WXX**..w7E !%88$%JKK"
&&2!%!4!4!>!>!@DJ!-..22>B"ik J 	gt,nd3 $..*

r4   rq   c                     S[        U 5      R                   S[        U 5      R                   S[        U R                  " S0 U R
                  D65       S3$ )Nr   r   r   r   rS   )typerU   rT   reprrG  r_  rv   s    rP   r   ConnectionPool.__repr__4  sS    T
%%&aT
(;(;'<T**DT-C-CDEFbJ	
r4   c                 :    U R                   R                  SS5      $ )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/  rv   s    rP   rc  ConnectionPool.get_protocol:  s     %%))*d;;r4   c                     [         R                  " 5       U l        SU l        / U l        [        5       U l        [        R                  " 5       U l	        g )Nr   )
r  r  _lock_created_connections_available_connectionsr  _in_use_connectionsr   r   r   rv   s    rP   rd  ConnectionPool.resetB  s9    ^^%
$%!&(##&5  99;r4   c                 r   U R                   [        R                  " 5       :w  au  U R                  R	                  SS9nU(       d  [
        e U R                   [        R                  " 5       :w  a  U R                  5         U R                  R                  5         g g ! U R                  R                  5         f = f)N   )r   )r   r   r   rc  acquirer#   rd  release)rK   acquireds     rP   	_checkpidConnectionPool._checkpidS  s    F 88ryy{"..q.9H***88ryy{*JJL'') # '')s   3B B6command_namero  c                    U R                  5         U R                      U R                  R                  5       nU R                  R                  U5        SSS5         WR                  5          UR                  5       (       a  U R                  c  [        S5      eU$ ! [         a    U R                  5       n Nf = f! , (       d  f       No= f! [        [        4 aD    UR                  5         UR                  5         UR                  5       (       a  [        S5      e U$ f = f! [         a    U R                  W5        e f = f)zGet a connection from the poolNConnection has dataConnection not ready)rw  rm  ro  rb  
IndexErrormake_connectionrp  addr   r   r  r$   r  r   rJ  ru  rK   ry  r  options
connections        rP   get_connectionConnectionPool.get_connection  s)   ZZ4!88<<>
 $$((4 	 
B&&((TZZ-?)*?@@ 3  4!113
4 Z" $W- B%%'""$&&(()*@AA ) B
  	 LL$		sX   B=BB=D% .-C B:7B=9B::B==
CAD"D% !D""D% %Ec                     U R                   n[        UR                  SS5      UR                  SS5      UR                  SS5      S9$ )z,Return an encoder based on encoding settingsr   r   r   r   r   F)r   r   r   )r_  r   r/  )rK   r   s     rP   get_encoderConnectionPool.get_encoder  sF    ''ZZ
G4"JJ'8(C#ZZ(:EB
 	
r4   c                 >   U R                   U R                  :  a  [        S5      eU =R                   S-  sl         U R                  b;  [	        U R
                  " S0 U R                  D6U R                  U R                  5      $ U R
                  " S0 U R                  D6$ )zCreate a new connectionzToo many connectionsr   rS   )rn  rD  r$   r  r  rG  r_  rm  rv   s    rP   r~  ConnectionPool.make_connection  s    $$(<(<<!"899!!Q&!::!'%%?(>(>?TZZ  $$>t'='=>>r4   r  c                    U R                  5         U R                      U R                  R                  U5        U R                  U5      (       a  U R                  R                  U5        O/U =R                  S-  sl        UR                  5          SSS5        g SSS5        g! [         a     Nwf = f! , (       d  f       g= f)z(Releases the connection back to the poolr   N)
rw  rm  rp  r  KeyErrorowns_connectionro  rD   rn  r   rK   r  s     rP   ru  ConnectionPool.release  s    ZZ((//
; ##J//++22:>
 ))Q.)%%'! Z ? Z    Zs.   B5B%AB5%
B2/B51B22B55
Cc                 4    UR                   U R                   :H  $ r]   )r   r  s     rP   r  ConnectionPool.owns_connection  s    ~~))r4   inuse_connectionsc                 
   U R                  5         U R                     U(       a!  [        U R                  U R                  5      nOU R                  nU H  nUR                  5         M     SSS5        g! , (       d  f       g= f)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)rw  rm  r   ro  rp  r   )rK   r  connectionsr  s       rP   r   ConnectionPool.disconnect  s`     	ZZ #//1I1I #99)
%%' * ZZs   AA44
Bc                 $    U R                  5         g)z-Close the pool, disconnecting all connectionsNr  rv   s    rP   r9  ConnectionPool.close  rD  r4   c                     U R                   R                  SU05        U R                   H	  nXl        M     U R                   H	  nXl        M     g )Nr   )r_  rW  ro  r   rp  )rK   r   r  s      rP   	set_retryConnectionPool.set_retry  sE    %%w&67//DJ 0,,DJ -r4   )ro  r`  rn  rc  rp  rm  r  rG  r_  rD  r   rp   )rq   rs   )r  ro  rq   Nr   )r   r)   rq   N)rT   rU   rV   rW   rj  classmethodrZ  ro  r   r   r   ra   r@   r   rc  rd  rw  r  r   r  r~  ru  r  rl  r   r9  r  rX   rS   r4   rP   rU  rU    s     . .d $)-9=	0 "#0   56	0d
3* 
<"-*^3 \ B
W 
?**, *3 *(D (D ((r4   rU  c                   V   ^  \ rS rSrSrSS\\4U 4S jjrS rS r	S r
S	 rS
 rSrU =r$ )BlockingConnectionPooli  a  
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                 D   > X@l         X l        [        TU ]  " SUUS.UD6  g )N)rG  rD  rS   )queue_classr   rw  ra   )rK   rD  r   rG  r  r_  r   s         rP   ra   BlockingConnectionPool.__init__  s2     ' 	
-+	
  	
r4   c                     U R                  U R                  5      U l          U R                  R                  S 5        M  ! [         a     Of = f/ U l        [        R                  " 5       U l        g r]   )	r  rD  pool
put_nowaitr   _connectionsr   r   r   rv   s    rP   rd  BlockingConnectionPool.reset#  sf    $$T%9%9:			$$T*   
  99;s   A   
AAc                    U R                   b<  [        U R                  " S0 U R                  D6U R                   U R                  5      nOU R                  " S0 U R                  D6nU R
                  R                  U5        U$ )zMake a fresh connection.rS   )r  r  rG  r_  rm  r  rD   r  s     rP   r~  &BlockingConnectionPool.make_connection;  sn    ::!-%%?(>(>?TZZJ ..H1G1GHJ  ,r4   c                     U R                  5         Sn U R                  R                  SU R                  S9nUc  U R                  5       n UR                  5          UR                  5       (       a  [        S5      e U$ ! [         a    [        S5      ef = f! [
        [        4 aD    UR                  5         UR                  5         UR                  5       (       a  [        S5      e U$ f = f! [         a    U R                  U5        e f = f)a  
Get a connection, blocking for ``self.timeout`` until a connection
is available from the pool.

If the connection returned is ``None`` then creates a new connection.
Because we use a last-in first-out queue, the existing connections
(having been returned to the pool after the initial ``None`` values
were added) will be returned before ``None`` values. This means we only
create new connections when we need to, i.e.: the actual number of
connections will only increase in response to demand.
NT)blockr   zNo connection available.r{  r|  )rw  r  r/  r   r   r$   r~  r   r   r  r   rJ  ru  r  s        rP   r  %BlockingConnectionPool.get_connectionF  s    	 
	>T4<<HJ --/J	 
B&&(()*?@@ ) =  	> ""<==	>( $W- B%%'""$&&(()*@AA ) B
  	LL$	s6   $B  C0  B  BAC-)C0 ,C--C0 0Dc                     U R                  5         U R                  U5      (       d,  UR                  5         U R                  R	                  S5        g U R                  R	                  U5        g! [
         a     gf = f)z)Releases the connection back to the pool.N)rw  r  r   r  r  r   r  s     rP   ru  BlockingConnectionPool.releasez  sm     	##J//
 !!#II  &	II  , 	 	s   A0 0
A=<A=c                 j    U R                  5         U R                   H  nUR                  5         M     g)z(Disconnects all connections in the pool.N)rw  r  r   r  s     rP   r   !BlockingConnectionPool.disconnect  s(    ++J!!# ,r4   )r  r   r  r  r   )rT   rU   rV   rW   rj  ro  r   ra   rd  r~  r  ru  r   rX   r  r  s   @rP   r  r    s;    F #
 0	2h*$ $r4   r  )\r   r   r  r  rH   r  r   abcr   	itertoolsr   queuer   r   r   r   typingr	   r
   r   r   r   r   r   urllib.parser   r   r   redis.cacher   r   r   r   r   r   _parsersr   r   r   r   backoffr   credentialsr   r    
exceptionsr!   r"   r#   r$   r%   r&   r'   r(   r   r)   utilsr*   r+   r,   r-   r.   r/   r0   r1   rE   rf   rk   rh   rd   r   objectr   __annotations__r6   r8   rZ   rs   r   ro  r  r  r/  rB  rC  r   rk  listrL  rS  rU  r  rS   r4   rP   <module>r     s    	  
 
     ( (  C C C 4 4  J I  O	 	 	 	 	 	 
	 8E,nDEF F"M M $0 0fB BJJ), J)ZC*# C*LE:. E:PfJ fR!3 > / # ! 6rk k\	b$^ b$r4   