
    >i                        U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZm Z  ejB                  dk\  rd dl m"Z# nd dl#m"Z# d d	l$m%Z% d d
l&m'Z' d dl(m)Z)m*Z* d dl+m,Z, d dl-m.Z.m/Z/ d dl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 d dl9m:Z: d dl;m<Z<m=Z=m>Z> ddl?m@Z@mAZAmBZBmCZCmDZD dZEdZFdZGdZHdZI G d dej                        ZKeKj                  ZMeeeCeDeBf      eNd<   e<reBZOneCZO G d de)      ZP G d de)      ZQeePeQf   ZR G d d       ZS G d! d"eS      ZT G d# d$eT      ZU G d% d&      ZV G d' d(eS      ZWd)ZXd*eeY   fd+ZZ ee[e\e\eZeZe[e[eZd,      Z]ee^ed-e_f   f   eNd.<    G d/ d0e*d12      Z`d3e^d*e`fd4Za ed5d67      Zb G d8 d6      Zc G d9 d:ec      Zdy);    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalSetTupleTypeTypeVarUnion)ParseResultparse_qsunquoteurlparse)      r   timeout)Retry)	NoBackoff)Protocol	TypedDict)DEFAULT_RESP_VERSION)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorChildDeadlockedErrorConnectionError	DataError
RedisErrorResponseErrorTimeoutError)
EncodableT)HIREDIS_AVAILABLEget_lib_versionstr_if_bytes   )
BaseParserEncoder_AsyncHiredisParser_AsyncRESP2Parser_AsyncRESP3Parser   *   $s   
   
    c                       e Zd Z e       Zy)	_SentinelN)__name__
__module____qualname__objectsentinel r5   t/var/www/html/wine-match-dev/backend/winematch-backend/venv/lib/python3.12/site-packages/redis/asyncio/connection.pyr7   r7   E   s	    xHr5   r7   DefaultParserc                       e Zd ZddZy)ConnectCallbackProtocolc                      y Nr=   self
connections     r>   __call__z ConnectCallbackProtocol.__call__T   s    r5   NrF   AbstractConnectionr8   r9   r:   rG   r=   r5   r>   rA   rA   S       r5   rA   c                       e Zd ZddZy)AsyncConnectCallbackProtocolc                    K   y wrC   r=   rD   s     r>   rG   z%AsyncConnectCallbackProtocol.__call__Y   s	        NrH   rJ   r=   r5   r>   rM   rM   X   rK   r5   rM   c            ,          e Zd ZdZdZdddddedddedddd	 e       dddedd
dde	e
ef   dee
   dee   dee   dede	eef   de
de
dedee   dededee
   dee
   dee
   dee
   dee   dee   dee   dee   d ee   f*d!Zd" Zed#        Zed$        Zd% Zd& Zdee   d'dfd(Zd) Zed*        Z ed'e
fd+       Z!ed,e"d'e
fd-       Z#dFd.Z$dGd/ed'dfd0Z%d1 Z&d2 Z'd3 Z(d4e)e*   d'dfd5Z+	 dHd4e	e*e
e)e*   f   d7ed'dfd8Z,d9e-d:e-d'dfd;Z.d< Z/	 	 dId6dd=d>ed?ee   d@edAee   fdBZ0d9e1d'e2e*   fdCZ3dDe)e)e1      d'e2e*   fdEZ4y)JrI   z0Manages communication to and from a Redis server)piddbusernameclient_namelib_namelib_versioncredential_providerpasswordsocket_timeoutsocket_connect_timeoutredis_connect_funcretry_on_timeoutretry_on_errorhealth_check_intervalnext_health_checklast_active_atencoderssl_contextprotocol_reader_writer_parser_connect_callbacks_buffer_cutoff_lock_socket_read_size__dict__r   NFutf-8stricti   zredis-pyr,   )rR   rX   rY   rZ   r\   r]   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizer^   rT   rU   rV   rS   retryr[   encoder_classrW   rc   rR   rX   rY   rZ   r\   r]   rn   ro   rp   rq   rr   r^   rT   rU   rV   rS   rs   r[   rt   rW   rc   c                (   |s|r|t        d      t        j                         | _        || _        || _        || _        || _        || _        || _	        || _
        || _        ||}|| _        || _        |t        u rg }|rS|j                  t                |j                  t"        j$                         |j                  t&        j                          || _        |s|rR|st+        t-               d      | _        nt1        j2                  |      | _        | j.                  j5                  |       nt+        t-               d      | _        || _        d| _         ||||	      | _        || _        d | _        d | _         || _!        | jE                  |
       g | _#        d| _$        	 tK        |      }|dk  s|dkD  rtS        d	      || _*        y # tL        $ r	 tN        }Y .tP        $ r tS        d      w xY w# dk  s|dkD  rtS        d	      || _*        w xY w)
Nz'username' and 'password' cannot be passed along with 'credential_provider'. Please provide only one of the following arguments: 
1. 'password' and (optional) 'username'
2. 'credential_provider'   r   ip  zprotocol must be an integerr,   r   zprotocol must be either 2 or 3)+r$   osgetpidrQ   rR   rT   rU   rV   rW   rX   rS   rY   rZ   r\   SENTINELappendr'   socketr   asyncior]   r   r   rs   copydeepcopyupdate_supported_errorsr^   r_   ra   r[   rd   re   rj   
set_parserrg   rh   int	TypeErrorr   
ValueErrorr#   rc   )rE   rR   rX   rY   rZ   r\   r]   rn   ro   rp   rq   rr   r^   rT   rU   rV   rS   rs   r[   rt   rW   rc   ps                          r>   __init__zAbstractConnection.__init__   s   2 &9&E+  99;& &#6   ,!)%3"&<# 0X%N!!,/!!&..1!!'"6"67,N"9;2
 "]]51
JJ..~>y{A.DJ%:"(*$X@PQ"47;7;!1%NP"		%HA 1uA%&FGG$DM  	%$A 	A!"?@@	A 1uA%&FGG$DMs$   #G G0G3 G00G3 3Hc                     dj                  d | j                         D              }| j                  j                   d| dS )N,c              3   0   K   | ]  \  }}| d |   yw)=Nr=   ).0kvs      r>   	<genexpr>z.AbstractConnection.__repr__.<locals>.<genexpr>   s     HTQ1QCjHs   <>)joinrepr_pieces	__class__r8   )rE   	repr_argss     r>   __repr__zAbstractConnection.__repr__   s=    HHHT5E5E5GHI	..))*!I;a88r5   c                      y rC   r=   rE   s    r>   r   zAbstractConnection.repr_pieces       r5   c                 >    | j                   d uxr | j                  d uS rC   )rd   re   r   s    r>   is_connectedzAbstractConnection.is_connected   s    ||4'DDLL,DDr5   c                 `    | j                   j                  t        j                  |             y rC   )rg   r{   weakref
WeakMethod)rE   callbacks     r>   register_connect_callbackz,AbstractConnection.register_connect_callback   s!    &&w'9'9('CDr5   c                     g | _         y rC   )rg   r   s    r>   clear_connect_callbacksz*AbstractConnection.clear_connect_callbacks   s
    "$r5   returnc                 4     || j                         | _        y)z
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rr   N)rj   rf   )rE   rq   s     r>   r   zAbstractConnection.set_parser   s     $T5K5KLr5   c                 H   K    j                   ry	  j                  j                   fd fd       d{    	  j                  s j                          d{    nIt        j                   j                        r j                          d{   n j                           j"                  D ]4  } |       } |       }|st%        j&                  |      s+| d{    6 y7 # t        j                  $ r  t
        j                  t        j                  f$ r t        d      t        $ r}t         j                  |            d}~wt        $ r}t        |      |d}~ww xY w7 7 # t        $ r  j!                          d{  7    w xY w7 w)z5Connects to the Redis server if not already connectedNc                  $     j                         S rC   )_connectr   s   r>   <lambda>z,AbstractConnection.connect.<locals>.<lambda>   s     r5   c                 $    j                         S rC   
disconnect)errorrE   s    r>   r   z,AbstractConnection.connect.<locals>.<lambda>   s    t7H r5   zTimeout connecting to server)r   rs   call_with_retryr}   CancelledErrorr|   r   r'   OSErrorr#   _error_message	Exceptionr[   
on_connectiscoroutinefunctionr%   r   rg   inspectisawaitable)rE   eexcrefr   tasks   `     r>   connectzAbstractConnection.connect   s|    	0**,,')H  	**oo''' 8?7R7R++8d--d333..t4 ** 	CuHD>D++D1

		9 %% 	 4 45 	?=>> 	:!$"5"5a"899 	0!#&C/	0 ( 4  	//###	 s   F"%C1 C/C1 E9 E48E9 E7E9 + F"F""F"'F (F"/C1 1A	E1:EE1 E,,E11F"4E9 7E9 9FFFF"c                    K   y wrC   r=   r   s    r>   r   zAbstractConnection._connect  s	     rO   c                      y rC   r=   r   s    r>   _host_errorzAbstractConnection._host_error  r   r5   	exceptionc                      y rC   r=   )rE   r   s     r>   r   z!AbstractConnection._error_message  r   r5   c                 B	  K   | j                   j                  |        | j                   }d}| j                  s| j                  s| j                  r>| j                  xs  t        | j                  | j                        }|j                         }|r#| j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        t        |      dk(  rd|d   g} | j                  d| j                  dg|  d{    | j                          d{   }|j!                  d      t#        | j                        k7  r4|j!                  d	      t#        | j                        k7  rt%        d
      |rP | j                  dg|ddi d{    	 | j                          d{   }t)        |      dk7  rt+        d      | j                  dvrt        | j                   t              rK| j                  t               |j                  | j                   _        | j                   j                  |        | j                  d| j                         d{    | j                          d{   }| j,                  rT| j                  dd| j,                         d{    t)        | j                          d{         dk7  rt%        d      | j.                  r&| j                  ddd| j.                         d{    | j0                  r&| j                  ddd| j0                         d{    | j2                  r$| j                  d| j2                         d{    d | j.                  | j0                  fD        D ]  }	 | j                          d{     | j2                  r0t)        | j                          d{         dk7  rt%        d      yy7 7 7 Z7 D# t&        $ r= | j                  d|d   d       d{  7   | j                          d{  7  }Y w xY w7 7 7 7 7 B7 7 7 # t4        $ r Y w xY w7 w)z=Initialize the connection, authenticate and select a databaseN)r,   2rv   defaultr   HELLOAUTHs   protoprotozInvalid RESP versioncheck_healthFrw   r   OKzInvalid Username or PasswordCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTc              3   &   K   | ]	  }|s|  y wrC   r=   )r   sents     r>   r   z0AbstractConnection.on_connect.<locals>.<genexpr>n  s     M4$Ms   zInvalid Database)rf   r   rW   rS   rX   r   get_credentialsrc   
isinstancer0   r   r1   EXCEPTION_CLASSESlensend_commandread_responsegetr   r#   r!   r+   r    rT   rU   rV   rR   r&   )rE   parser	auth_argscred_providerresponseauth_response_s          r>   r   zAbstractConnection.on_connect!  s    %	##(( T5dmmT]]S  &557I h6$,,(9: 12171I1I.''-9~"&	!5	#$##GT]]FOYOOO!//11H||H%T]]);;AT]]#A$ &&<== #$##FKYKUKKK;&*&8&8&: : M*d2)*HII ]](*$,,(9: 12171I1I.''-##GT]];;;!//11H ##Hi9I9IJJJ$"4"4"6674?%&ABB ==##HiT]]SSS##HiDDTDTUUU77##Hdgg666 NDMM43C3C#DM 	A((***	 77$"4"4"6674?%&899 @ y P1 L !;7 ;
 ''	"E'RRR&*&8&8&: : :;$ <1 K6
 TU 7
 +   7sA  D:R<P#=RP&A:RP)RP/ (P,)P/ -B+RQ8R0Q;10R!Q>"R>R?ARR1R4R5/R$R
%&RRR R$&R
RR&R)R,P/ /#Q5QQ5+Q.,Q51R4Q55R;R>RRRR
RR	RRRRnowaitc                   K   	 t        | j                        4 d{    | j                  j                          | j                  s	 ddd      d{    y	 t        j                         | j                  k(  r>| j                  j                          |s"| j                  j                          d{    d| _        d| _        ddd      d{    y7 7 7 '# t        $ r Y 0w xY w# d| _        d| _        w xY w7 -# 1 d{  7  sw Y   yxY w# t        j                  $ r t        d| j                         dw xY ww)z!Disconnects from the Redis serverNz#Timed out closing connection after )async_timeoutrZ   rf   on_disconnectr   rx   ry   rQ   re   closewait_closedr   rd   r}   r'   )rE   r   s     r>   r   zAbstractConnection.disconnectx  s*    	$T%@%@A ( (**,((( ( ((yy{dhh.**,  &"&,,":":"<<< $(DL#'DL( ( ( ( =  $(DL#'DL( ( ( (  ## 	5d6Q6Q5RS	s   ED CD (D	D CD EAC5C6C:DD DD ED D C	C+(C.*C++C..C>>DD D	D
DD ED -EEc                    K   | j                  dd       d{    t        | j                          d{         dk7  rt        d      y7 47 w)z Send PING, expect PONG in returnPINGFr   NPONGz#Bad response from PING health check)r   r+   r   r#   r   s    r>   
_send_pingzAbstractConnection._send_ping  sR     U;;;d00223v=!"GHH > 	<2s   AAAAAAc                 @   K   | j                          d{    y7 w)z Function to call when PING failsNr   )rE   r   s     r>   _ping_failedzAbstractConnection._ping_failed  s     oos   c                    K   | j                   rit        j                         j                         | j                  kD  r9| j
                  j                  | j                  | j                         d{    yyy7 w)z3Check the health of the connection with a PING/PONGN)	r^   r}   get_running_looptimer_   rs   r   r   r   r   s    r>   r   zAbstractConnection.check_health  sf      &&((*//1D4J4JJ**,,T__d>O>OPPP K ' Qs   A/A;1A92A;commandc                    K   | j                   j                  |       | j                   j                          d {    y 7 wrC   )re   
writelinesdrain)rE   r   s     r>   _send_packed_commandz'AbstractConnection._send_packed_command  s.     (ll  """s   9AAATr   c                   K   | j                   s| j                          d {    n|r| j                          d {    	 t        |t              r|j                         }t        |t              r|g}| j                  r8t        j                  | j                  |      | j                         d {    y | j                  j                  |       | j                  j                          d {    y 7 7 7 G7 # t        j                  $ r( | j                  d       d {  7   t        d      d t         $ r{}| j                  d       d {  7   t#        |j$                        dk(  rd|j$                  d   }}n|j$                  d   }|j$                  d   }t'        d| d| d	      |d }~wt(        $ r | j                  d       d {  7    w xY ww)
NTr   zTimeout writing to socketrv   UNKNOWNr   Error z while writing to socket. .)r   r   r   r   strencodebytesrY   r}   wait_forr   re   r   r   r'   r   r   r   argsr#   BaseException)rE   r   r   r   err_noerrmsgs         r>   send_packed_commandz&AbstractConnection.send_packed_command  s       ,,.  ##%%%	'3'!..*'5)")""&&--g68K8K   ''0ll((*** !%
 +## 	F///...:;E 		///...166{a!*AFF1I! :6(!D  	
 ///...	s    G$C8G$C:G$A1D  4C<5D  9G$:8D  2C>3D  7G$:G$<D  >D   (G!(D+)G!F8EA F88!G!GG!!G$r   kwargsc                    K   | j                   | j                  | |j                  dd             d{    y7 w)z+Pack and send a command to the Redis serverr   Tr   N)r   pack_commandr   )rE   r   r   s      r>   r   zAbstractConnection.send_command  s@     &&Dt$6::nd3S ' 
 	
 	
s   4><>c                   K   	 | j                   j                          d{   S 7 # t        $ rK}| j                  d       d{  7   | j	                         }t        d| d|j                         d}~ww xY ww)z8Poll the socket to see if there's data that can be read.NTr   Error while reading from z: )rf   can_read_destructiver   r   r   r#   r   )rE   r   
host_errors      r>   r  z'AbstractConnection.can_read_destructive  su     	V::<<<< 	V///...))+J!$=j\AFF8"TUU	Vs<   A?( &( A?( 	A<A7A	0A77A<<A?)disconnect_on_errorpush_requestdisable_decodingr   r  r  c                  K   ||n| j                   }| j                         }	 |^| j                  dv rPt        sJt	        |      4 d{    | j
                  j                  ||       d{   }ddd      d{    n|It	        |      4 d{    | j
                  j                  |       d{   }ddd      d{    n^| j                  dv r,t        s&| j
                  j                  ||       d{   }n$| j
                  j                  |       d{   }| j                  r6t        j                         j!                         | j                  z   }	|	| _        t%        t&              r|d|S 7 ;7 7 # 1 d{  7  sw Y   rxY w7 7 7 # 1 d{  7  sw Y   xY w7 7 # t        j                  $ r0 |Y y|r| j                  d       d{  7   t        d|       t        $ r=}|r| j                  d       d{  7   t        d| d	|j                         d}~wt        $ r |r| j                  d       d{  7    w xY ww)
z0Read the response from a previously sent commandN)3r   )r  r  )r  Tr   zTimeout reading from r  z : )rY   r   rc   r)   r   rf   r   r}   r'   r   r   r#   r   r   r^   r   r   r_   r   r&   )
rE   r  r   r  r  read_timeoutr  r   r   	next_times
             r>   r   z AbstractConnection.read_response  sq     #*"5w4;N;N%%'
)	(MMX-)(6  %)\\%?%?)9 &@ &  H   )(6  %)\\%?%?)9 &@ &  H   (*3D!%!;!;%5L "< "  "&!;!;%5 "< " . %%002779D<V<VVI%.D"h.$W    
    
 ## 	E""ooTo222!6zlCDD 	W"ooTo222!$=j\QVVH"UVV 	 #ooTo222	s%  !I2%G 	F
G !F.F/F3G >F
?G F"G  F)9F%:F)>G 	F'
9G F>$G (G )G -AI2G F
G FFFG %F)'G )F;/F20F;7G  G I/I2I/0G31I/I#H&$ I#I/'I*(I//I2c           	         g }t        |d   t              rJ t        |d   t              r1t        |d   j	                         j                               |dd z   }n)d|d   v r"t        |d   j                               |dd z   }t        j                  t        t        t        |            j	                         t        f      }| j                  }t        | j                  j                  |      D ]  }t        |      }t        |      |kD  s||kD  st        |t              rat        j                  |t        t        |      j	                         t        f      }|j!                  |       |j!                  |       t        }t        j                  |t        t        |      j	                         t        |t        f      } |j!                  |       |S )z2Pack a series of arguments into the Redis protocolr   rv   N    )r   floatr   tupler   split	SYM_EMPTYr   SYM_STARr   SYM_CRLFrh   mapra   
memoryview
SYM_DOLLARr{   )rE   r   outputbuffbuffer_cutoffarg
arg_lengths          r>   r   zAbstractConnection.pack_command  s    d1gu---d1gs#a)//12T!"X=DT!W_a)DH4D~~xSY)>)>)@(KL++t||**D1 	C SJD	M)-c:. ~~:s:'='='?J d#c" ~~"J..0  	!	4 	dr5   commandsc                    g }g }d}| j                   }|D ]  } | j                  | D ]  }t        |      }||kD  s||kD  st        |t              r*|r$|j                  t        j                  |             d}g }||kD  st        |t              r|j                  |       y|j                  |       ||z  }  |r$|j                  t        j                  |             |S )z.Pack multiple commands into the Redis protocolr   )rh   r   r   r   r  r{   r  r   )	rE   r  r  piecesbuffer_lengthr  cmdchunkchunklens	            r>   pack_commandsz AbstractConnection.pack_commandsJ  s      ++ 	.C***C0 .u:!M1-/!%4innV&<=$%MFm+z%/LMM%(MM%(!X-M!.	.& MM)..01r5   )r   N)FT)FN)5r8   r9   r:   __doc__	__slots__rz   r?   r*   r.   r   r   r   r   r  boollistr7   r   r-   r   ConnectCallbackTr   r   r   r   r   propertyr   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"  r=   r5   r>   rI   rI   `   sN   :IB  "&*.26!&19'!&)6 %'(%)",%4%6"&!%9='.<@"#/Q% #s(OQ% 3-	Q%
 !Q% !)Q% Q% dIo.Q% Q% Q% Q% :&Q% Q%  %Q% c]Q%  3-!Q%" c]#Q%$ 3-%Q%& 'Q%( %%56)Q%* G}+Q%, &&89-Q%. 3-/Q%f9   E EE%MtJ'7 MD M%N   S    #  U:nt  0I Q#(5/ #d #
 QU'UC%89'IM'	'R
 
s 
t 
V "'#'<
 %)',<< %<
 "< tn<|,* ,e ,\hx
/C&D e r5   rI   c                        e Zd ZdZddddddded	eeef   d
edee	eeee
f   f      def
 fdZd Zde	fdZd ZdefdZdedefdZ xZS )
Connectionz4Manages TCP communication to and from a Redis server	localhosti  FNr   )hostportsocket_keepalivesocket_keepalive_optionssocket_typer-  r.  r/  r0  r1  c                    || _         t        |      | _        || _        |xs i | _        || _        t        |   di | y Nr=   )r-  r   r.  r/  r0  r1  superr   )rE   r-  r.  r/  r0  r1  r   r   s          r>   r   zConnection.__init__l  sD     	I	 0(@(FB%&"6"r5   c                     d| j                   fd| j                  fd| j                  fg}| j                  r|j	                  d| j                  f       |S )Nr-  r.  rR   rT   )r-  r.  rR   rT   r{   rE   r  s     r>   r   zConnection.repr_pieces}  sM    499%		':T477OLMM=$*:*:;<r5   r   c                 4    | j                   | j                  dS )Nr-  r.  r8  r   s    r>   _connection_argumentsz Connection._connection_arguments  s    		49955r5   c                   K   t        | j                        4 d{    t        j                  di | j	                          d{   \  }}ddd      d{    | _        | _        |j                  j                  d      }|r|j                  t        j                  t        j                  d       	 | j                  rs|j                  t        j                  t        j                  d       | j                   j#                         D ]&  \  }}|j                  t        j$                  ||       ( yyy7 7 7 # 1 d{  7  sw Y   xY w# t&        t(        f$ r |j+                           w xY ww)zCreate a TCP socket connectionNr|   rv   r=   )r   rZ   r}   open_connectionr9  rd   re   	transportget_extra_info
setsockoptr|   IPPROTO_TCPTCP_NODELAYr/  
SOL_SOCKETSO_KEEPALIVEr0  itemsSOL_TCPr   r   r   )rE   readerwritersockr   r   s         r>   r   zConnection._connect  sE     !<!<= 	 	#*#:#: $,,.$ NFF	 	 ..x8OOF..0B0BAF((OOF$5$5v7J7JAN $ = = C C E >11=> )	 		 	 	 	  Y'  	sp   E;D;E;'ED>EE;E AE;:A>E 8E;>E E;EE	EE;!E88E;c                 8    | j                    d| j                   S )N:r8  r   s    r>   r   zConnection._host_error  s    ))Adii[))r5   r   c                     | j                         }|j                  sd| dS t        |j                        dk(  rd| d|j                  d    dS d|j                  d    d| d|j                  d    dS )	NzError connecting to z. Connection reset by peerrv   . r   r   r   z connecting to )r   r   r   rE   r   r  s      r>   r   zConnection._error_message  s     %%'
~~ **5OPP A%)*R	q8I7J!LL *+?:,b>>!$%Q(r5   )r8   r9   r:   r$  r   r   r   r&  r   r
   r   r   r   r9  r   r   r   r   __classcell__r   s   @r>   r+  r+  i  s    :
   $!&NR# # CHo	#
 # #+73c5j8I3I+J"K# #"6w 60*S * # r5   r+  c                        e Zd ZdZ	 	 	 	 	 	 ddee   dee   dedee   dee   def fdZd	ef fd
Z	e
d        Ze
d        Ze
d        Ze
d        Ze
d        Ze
d        Z xZS )SSLConnectionzManages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    ssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_ca_datassl_check_hostnamec                 P    t        ||||||      | _        t        |   di | y )N)keyfilecertfile	cert_reqsca_certsca_datacheck_hostnamer=   )RedisSSLContextrb   r4  r   )	rE   rQ  rR  rS  rT  rU  rV  r   r   s	           r>   r   zSSLConnection.__init__  s6     -<!#!--
 	"6"r5   r   c                 ^    t         |          }| j                  j                         |d<   |S )Nssl)r4  r9  rb   r   )rE   r   r   s     r>   r9  z#SSLConnection._connection_arguments  s-    .0((,,.ur5   c                 .    | j                   j                  S rC   )rb   rX  r   s    r>   rX  zSSLConnection.keyfile      '''r5   c                 .    | j                   j                  S rC   )rb   rY  r   s    r>   rY  zSSLConnection.certfile      (((r5   c                 .    | j                   j                  S rC   )rb   rZ  r   s    r>   rZ  zSSLConnection.cert_reqs  s    )))r5   c                 .    | j                   j                  S rC   )rb   r[  r   s    r>   r[  zSSLConnection.ca_certs  rd  r5   c                 .    | j                   j                  S rC   )rb   r\  r   s    r>   r\  zSSLConnection.ca_data  rb  r5   c                 .    | j                   j                  S rC   )rb   r]  r   s    r>   r]  zSSLConnection.check_hostname  s    ...r5   )NNrequiredNNF)r8   r9   r:   r$  r   r   r&  r   r
   r9  r)  rX  rY  rZ  r[  r\  r]  rM  rN  s   @r>   rP  rP    s     &*&*'&*%)#(#c]# sm# 	#
 sm# c]# !#(w 
 ( ( ) ) * * ) ) ( ( / /r5   rP  c                   |    e Zd ZdZ	 	 	 	 	 	 ddee   dee   dee   dee   dee   defd	Zd
ej                  fdZ
y)r^  )rX  rY  rZ  r[  r\  contextr]  NrX  rY  rZ  r[  r\  r]  c                 @   || _         || _        |t        j                  | _        n\t        |t              rLt        j                  t        j                  t        j                  d}||vrt        d|       ||   | _        || _
        || _        || _        d | _        y )N)noneoptionalri  z+Invalid SSL Certificate Requirements Flag: )rX  rY  r`  	CERT_NONErZ  r   r   CERT_OPTIONALCERT_REQUIREDr%   r[  r\  r]  rk  )rE   rX  rY  rZ  r[  r\  r]  	CERT_REQSs           r>   r   zRedisSSLContext.__init__  s       ]]DN	3'----I
 	) A)M  'y1DN ,15r5   r   c                    | j                   st        j                         }| j                  |_        | j                  |_        | j                  r3| j                  r'|j                  | j                  | j                         | j                  s| j                  r'|j                  | j                  | j                         || _         | j                   S )N)rY  rX  )cafilecadata)rk  r`  create_default_contextr]  rZ  verify_moderY  rX  load_cert_chainr[  r\  load_verify_locations)rE   rk  s     r>   r   zRedisSSLContext.get  s    ||002G%)%8%8G""&..G}}'''U}}--T]]4<<-X"DL||r5   )NNNNNF)r8   r9   r:   r%  r   r   r&  r   r`  
SSLContextr   r=   r5   r>   r^  r^    s    I "&"&#'"&!%$6#6 3-6 C=	6
 3-6 #6 6:
S^^ 
r5   r^  c                   v     e Zd ZdZdddef fdZdeeeeee	f   f      fdZ
d Zdefd	Zd
edefdZ xZS )UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server pathr  c                2    || _         t        |   di | y r3  )r  r4  r   )rE   r  r   r   s      r>   r   z#UnixDomainSocketConnection.__init__'  s    	"6"r5   r   c                     d| j                   fd| j                  fg}| j                  r|j                  d| j                  f       |S )Nr  rR   rT   )r  rR   rT   r{   r6  s     r>   r   z&UnixDomainSocketConnection.repr_pieces+  sB    499%dgg7MM=$*:*:;<r5   c                 D  K   t        | j                        4 d {    t        j                  | j                         d {   \  }}d d d       d {    | _        | _        | j                          d {    y 7 f7 @7 /# 1 d {  7  sw Y   ?xY w7  w)Nr~  )r   rZ   r}   open_unix_connectionr  rd   re   r   )rE   rE  rF  s      r>   r   z#UnixDomainSocketConnection._connect1  s      !<!<= 	P 	P#*#?#?TYY#OONFF	P 	Poo		PO	P 	P 	P 	P 	 sb   B BB $B	BB	B B%B =B>B B	B 	BBBB c                     | j                   S rC   r~  r   s    r>   r   z&UnixDomainSocketConnection._host_error8  s    yyr5   r   c                     | j                         }t        |j                        dk(  rd| d|j                  d    dS d|j                  d    d| d|j                  d    dS )Nrv   z!Error connecting to unix socket: rK  r   r   r   z connecting to unix socket: )r   r   r   rL  s      r>   r   z)UnixDomainSocketConnection._error_message;  s}     %%'
y~~!#3J<r)..QRBSATTUV
 *++G,b!2 316r5   )r8   r9   r:   r$  r   r   r   r   r   r   r   r   r   r   r   rM  rN  s   @r>   r|  r|  $  s\    :&( # #XeCsCx,@&AB  S  # r5   r|  )0FFALSENNOr   c                 v    | | dk(  ry t        | t              r| j                         t        v ryt	        |       S )Nr}  F)r   r   upperFALSE_STRINGSr&  )values    r>   to_boolr  M  s4    }%%++-="@;r5   )rR   rY   rZ   r/  r\   max_connectionsr^   rV  .URL_QUERY_ARGUMENT_PARSERSc                   Z    e Zd ZU eed<   eed<   ee   ed<   eed<   eed<   eed<   eed<   y)	ConnectKwargsrS   rX   connection_classr-  r.  rR   r  N)r8   r9   r:   r   __annotations__r   rI   r   r=   r5   r>   r  r  c  s,    MM-..
I
IG
Ir5   r  F)totalurlc                    t        |       }i }t        |j                        j                         D ]N  \  }}|s	t	        |      dkD  st        |d         }t        j                  |      }|r	  ||      ||<   J|||<   P |j                  rt        |j                        |d<   |j                  rt        |j                        |d<   |j                  dk(  r/|j                  rt        |j                        |d<   t        |d<   |S |j                  d	v r|j                  rt        |j                        |d
<   |j                   rt#        |j                         |d<   |j                  r6d|vr2	 t#        t        |j                        j%                  dd            |d<   |j                  dk(  r	t(        |d<   |S d}t        d| d      # t        t        f$ r t        d| d      w xY w# t&        t        f$ r Y ^w xY w)Nr   zInvalid value for `z` in connection URL.rS   rX   unixr  r  )redisredissr-  r.  rR   /r}  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrC  r   r   r  r   r   r   rS   rX   schemer  r|  hostnamer.  r   replaceAttributeErrorrP  )r  parsedr   name
value_listr  r   valid_schemess           r>   	parse_urlr  m  s   "3-FF$V\\288: 
%j#j/A-JqM*E/33D9FW#)%=F4L  %t
% $V__5z$V__5z }};;$V[[1F6N%?!"0 M- 
-	-??$V__5F6N;; -F6N ;;4v-"76;;#7#?#?R#HIt ==H$)6F%& M 7CM?RST
 	
E ":. W$':4&@T%UVVW6 #J/ s   /G/1G- G*-G?>G?_CPConnectionPool)boundc                       e Zd ZdZedee   dedefd       Ze	dfdee
   dee   fd	Zd
 Zd Zd Zd Zd Zd Zde
fdZde
fdZddefdZddZy)r  a  
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.ConnectionError` when the pool's
    limit is reached.

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

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    clsr  r   c                 J    t        |      }|j                  |        | di |S )a  
        Return a connection pool configured from the given URL.

        For example::

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

        Three URL schemes are supported:

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

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

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

        1. A ``db`` querystring option, e.g. redis://localhost?db=0

        2. If using the redis:// or rediss:// schemes, the path argument
               of the url, e.g. redis://localhost/0

        3. A ``db`` keyword argument to this function.

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

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        r=   )r  update)r  r  r   url_optionss       r>   from_urlzConnectionPool.from_url  s&    V  nk"}V}r5   Nr  r  c                 T   |xs d}t        |t              r|dk  rt        d      || _        || _        || _        t        j                         | _        t        j                         | _
        |  |  |  | j                          | j                  j                  dt              | _        y )Nl        r   z,"max_connections" must be a positive integerrt   )r   r   r   r  connection_kwargsr  	threadingLock
_fork_lockr}   ri   resetr   r.   rt   )rE   r  r  r  s       r>   r   zConnectionPool.__init__  s     *2U/3/?Q3FKLL 0!2. $..*\\^


!3377Qr5   c                 n    | j                   j                   d | j                  di | j                  dS )Nr   r   r=   )r   r8   r  r  r   s    r>   r   zConnectionPool.__repr__  s>    ~~&&'%%%?(>(>?B!E	
r5   c                     t        j                         | _        d| _        g | _        t               | _        t        j                         | _	        y )Nr   )
r}   r  ri   _created_connections_available_connectionsset_in_use_connectionsrx   ry   rQ   r   s    r>   r  zConnectionPool.reset  s8    \\^
$%!&(##&5  99;r5   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   )rQ   rx   ry   r  acquirer"   r  release)rE   acquireds     r>   	_checkpidzConnectionPool._checkpid  s    F 88ryy{"..q.9H***88ryy{*JJL'') # '')s   1B B0c                   K   | j                          | j                  4 d{    	 | j                  j                         }| j                  j                  |       ddd      d{    	 j                          d{    	 |j                          d{   rt        d      d	 |S 7 # t        $ r | j                         }Y w xY w7 f# 1 d{  7  sw Y   vxY w7 d7 M# t        t        f$ r[ |j                          d{  7   |j                          d{  7   |j                          d{  7  rt        d      dY |S w xY w# t        $ r | j                         d{  7    w xY ww)zGet a connection from the poolNConnection has dataConnection not ready)r  ri   r  pop
IndexErrormake_connectionr  addr   r  r#   r   r   r   r  rE   command_namekeysoptionsrF   s        r>   get_connectionzConnectionPool.get_connectionE  sv    :: 	5 	54!88<<>
 $$((4	5 	5	$$&&&
L#88:::)*?@dJ ; 9	5  4!113
4	5 	5 	5 	5 ' ;#W- L ++--- ((***#88:::)*@AtK ; L
  	 ,,z***		s   !F B/F CB1CF )C*F /E C'E C+ C)C+ -F 1C
CCCF C$CC$ F 'E )C+ +"EDE&D)'E?E EE F EE E=5E86E==F c                     | j                   }| j                  |j                  dd      |j                  dd      |j                  dd            S )z,Return an encoder based on encoding settingsrn   rl   ro   rm   rp   F)rn   ro   rp   )r  rt   r   )rE   r   s     r>   get_encoderzConnectionPool.get_encoderf  sQ    ''!!ZZ
G4"JJ'8(C#ZZ(:EB " 
 	
r5   c                     | j                   | j                  k\  rt        d      | xj                   dz  c_          | j                  di | j                  S )zCreate a new connectionzToo many connectionsrv   r=   )r  r  r#   r  r  r   s    r>   r  zConnectionPool.make_connectiono  sO    $$(<(<<!"899!!Q&!$t$$>t'='=>>r5   rF   c                   K   | j                          | j                  4 d{    	 | j                  j                  |       | j                  |      r| j                  j                  |       n?| xj                  dz  c_        |j                          d{    	 ddd      d{    yddd      d{    y7 # t        $ r Y w xY w7 87 )7 # 1 d{  7  sw Y   yxY ww)z(Releases the connection back to the poolNrv   )
r  ri   r  removeKeyErrorowns_connectionr  r{   r  r   rD   s     r>   r  zConnectionPool.releasev  s     :: 	 	((//
; ##J/++22:>
 ))Q.) ++---!	 	 	 	 	    .	 	 	 	 	s   !C-CC-CCACCCC-*C+C-;C<C-	CCCCC-C-C*C!C*&C-c                 4    |j                   | j                   k(  S rC   )rQ   rD   s     r>   r  zConnectionPool.owns_connection  s    ~~))r5   inuse_connectionsc                   K   | j                          | j                  4 d{    |r!t        | j                  | j                        }n| j                  }t        j                  d |D        ddi d{   }t        d |D        d      }|r|ddd      d{    y7 7 .7 	# 1 d{  7  sw Y   yxY ww)z
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other tasks. Otherwise only disconnect
        connections that are idle in the pool.
        Nc              3   <   K   | ]  }|j                           y wrC   r   r   rF   s     r>   r   z,ConnectionPool.disconnect.<locals>.<genexpr>  s     Hj*'')H   return_exceptionsTc              3   B   K   | ]  }t        |t              s|  y wrC   r   r   r   rs     r>   r   z,ConnectionPool.disconnect.<locals>.<genexpr>       Ha:a+GH   )r  ri   r   r  r  r}   gathernext)rE   r  connectionsrespr   s        r>   r   zConnectionPool.disconnect  s      	:: 	 	 <A//1I1I= #99 HKH"& D H4H$OC		 	 		 	 	 	sW   !B>B#B>AB)6B%7B)B>B'B>%B)'B>)B;/B20B;7B>c                 d    | j                   D ]	  }||_         | j                  D ]	  }||_         y rC   )r  rs   r  )rE   rs   conns      r>   	set_retryzConnectionPool.set_retry  s:    // 	DDJ	,, 	DDJ	r5   r#  )rs   r   r   N)r8   r9   r:   r$  classmethodr   r  r   r  r+  rI   r   r   r   r   r  r  r  r  r  r  r  r&  r   r  r=   r5   r>   r  r    s     ,d3i ,c , , ,` 6@)-R12R "#R<
"-*^B
?(: ***< *$ 0r5   c            
            e Zd ZdZddeej                  fdedee   de	e
   de	ej                     f fdZd	 Zd
 Zd Zde
fdZddef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      r  r   r  queue_classc                 J    || _         || _        |  t        |   d||d| y )N)r  r  r=   )r  r   r4  r   )rE   r  r   r  r  r  r   s         r>   r   zBlockingConnectionPool.__init__  s9     ' 	
-+	
  	
r5   c                     | j                  | j                        | _        	 	 | j                  j                  d        # t        j
                  $ r Y nw xY wg | _        t        j                         | _	        y rC   )
r  r  pool
put_nowaitr}   	QueueFull_connectionsrx   ry   rQ   r   s    r>   r  zBlockingConnectionPool.reset  sl    $$T%9%9:			$$T*  $$ 
  99;s   ? AAc                 t     | j                   di | j                  }| j                  j                  |       |S )zMake a fresh connection.r=   )r  r  r  r{   rD   s     r>   r  z&BlockingConnectionPool.make_connection  s7    *T**DT-C-CD
  ,r5   c                 B  K   | j                          d}	 t        | j                        4 d{    | j                  j	                          d{   }ddd      d{    || j                         }	 |j                          d{    	 |j                          d{   rt        d      d	 |S 7 7 i7 [# 1 d{  7  sw Y   kxY w# t
        j                  t
        j                  f$ r t        d      w xY w7 y7 b# t        t        f$ r[ |j                          d{  7   |j                          d{  7   |j                          d{  7  rt        d      dY |S w xY w# t        $ r | j                  |       d{  7    w xY w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.
        NzNo connection available.r  r  )r  r   r   r  r   r}   
QueueEmptyr'   r#   r  r   r  r   r   r   r  r  s        r>   r  z%BlockingConnectionPool.get_connection  s     	 
	>$T\\2 3 3#'99==?2
3 3 --/J	$$&&&
L#88:::)*?@dJ ; A323 3 3 3""G$8$89 	> ""<==	> ' ;#W- L ++--- ((***#88:::)*@AtK ; L
  	,,z***	s  FC B9C B?B;B?C !B="C &F9E7 DE7 D
 %D&D
 7F9C ;B?=C ?CCCC /DFE7 D
 
"E4,D/-E4EE4E!E40E7 1F3E44E7 7FFFFrF   c                 $  K   | j                          | j                  |      s4|j                          d{    | j                  j	                  d       y	 | j                  j	                  |       y7 =# t
        j                  $ r Y yw xY ww)z)Releases the connection back to the pool.N)r  r  r   r  r  r}   r  rD   s     r>   r  zBlockingConnectionPool.release4  s      	##J/
 '')))II  &	II  , *    	 	s3   5BA5 BA7 4B7B
BBBr  c                 6  K   | j                          | j                  4 d{    t        j                  d | j                  D        ddi d{   }t        d |D        d      }|r|ddd      d{    y7 Z7 .7 	# 1 d{  7  sw Y   yxY ww)z(Disconnects all connections in the pool.Nc              3   <   K   | ]  }|j                           y wrC   r   r  s     r>   r   z4BlockingConnectionPool.disconnect.<locals>.<genexpr>N  s     Nj*'')Nr  r  Tc              3   B   K   | ]  }t        |t              s|  y wrC   r  r  s     r>   r   z4BlockingConnectionPool.disconnect.<locals>.<genexpr>Q  r  r  )r  ri   r}   r  r  r  )rE   r  r  r   s       r>   r   z!BlockingConnectionPool.disconnectI  s     :: 	 	 ND<M<MN"& D H4H$OC		 	 		 	 	 	sV   !BA>B*BB B-B8B9B BBB
BBBr#  )r8   r9   r:   r$  r+  r}   	LifoQueuer   r   r   rI   Queuer   r  r  r  r  r&  r   rM  rN  s   @r>   r  r    s    F  "!#5?+2+<+<

 #
 12	

 '--(
$03j(: *
$ 
r5   r  )er}   r~   enumr   rx   r|   r`  sysr  r   abcr   	itertoolsr   typesr   typingr   r   r   r	   r
   r   r   r   r   r   r   urllib.parser   r   r   r   version_infor   r   redis.asyncio.retryr   redis.backoffr   redis.compatr   r   redis.connectionr   redis.credentialsr   r   redis.exceptionsr    r!   r"   r#   r$   r%   r&   r'   redis.typingr(   redis.utilsr)   r*   r+   _parsersr-   r.   r/   r0   r1   r  r  r  SYM_LFr  Enumr7   r<   rz   r  r?   rA   rM   r(  rI   r+  rP  r^  r|  r  r&  r  r   r  r  r   r;   r  r  r  r  r  r=   r5   r>   <module>r     s       	  
 
     "    B A z!06 % # , 1 T	 	 	 $ H H  
				   E+->@SSTU U'M%Mh 
8 
 02NNO F FRK# K\5/J 5/p2 2j#!3 #L /htn  CS"'##!$%	C GC#v+)>$>? IU 13 1= 1h e+,F FRf^ fr5   