o
    i                     @   s`  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m	Z	 d dl
mZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZm Z  ddl!m"Z" e"rtd dl#Z#d d	l#m$Z$m%Z%m&Z& ndZ#dZ%dZ$dZ&dd
l'm(Z( ddl)m*Z*m+Z+ ddl,m-Z-m.Z. ddl!m/Z/m0Z0 ej1dkrd dl m2Z3 nd dl3m2Z3 d dl4m5Z5 d dl6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z< d dl=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE d dlFmGZG d dlHmIZImJZJ ddlKmLZLmMZMmNZNmOZOmPZP dZQdZRdZSdZTdZUG dd dejVZWeWjXZYeeeOePeNf  eZd< eIreNZ[neOZ[G d d! d!eZ\G d"d# d#eZ]ee\e]f Z^G d$d% d%Z_G d&d' d'e_Z`G d(d) d)e`ZaG d*d+ d+ZbG d,d- d-e_Zcd.Zdd/eee fd0d1Zfd2d3 Zgeeheieiefefehehefegegeid4Zjeeked5elf f eZd6< G d7d8 d8ed9d:Zmd;ekd/emfd<d=Zned>d?d@ZoG dAd? d?ZpG dBdC dCepZqdS )D    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalProtocolSetTupleType	TypedDictTypeVarUnion)ParseResultparse_qsunquoteurlparse   )SSL_AVAILABLE)
SSLContext
TLSVersionVerifyFlags)TokenInterface)
DriverInforesolve_driver_info)!AsyncAfterConnectionReleasedEventEventDispatcher)deprecated_argsformat_error_message)      r"   )timeout)Retry)	NoBackoff)DEFAULT_RESP_VERSION)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorConnectionError	DataErrorMaxConnectionsError
RedisErrorResponseErrorTimeoutError)
EncodableT)HIREDIS_AVAILABLEstr_if_bytes)
BaseParserEncoder_AsyncHiredisParser_AsyncRESP2Parser_AsyncRESP3Parser   *   $s   
   
    c                   @   s   e Zd Ze ZdS )	_SentinelN)__name__
__module____qualname__objectsentinel rD   rD   O/home/app/Keep/.python/lib/python3.10/site-packages/redis/asyncio/connection.pyr>   T   s    
r>   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocol
connectionAbstractConnectionc                 C      d S NrD   selfrI   rD   rD   rE   __call__c   s    z ConnectCallbackProtocol.__call__NrI   rJ   r?   r@   rA   rO   rD   rD   rD   rE   rH   b       rH   c                   @   rG   )AsyncConnectCallbackProtocolrI   rJ   c                       d S rL   rD   rM   rD   rD   rE   rO   g   s    z%AsyncConnectCallbackProtocol.__call__NrP   rQ   rD   rD   rD   rE   rS   f   rR   rS   c                1   @   s  e Zd ZdZdZeddgddddddd	ed
dd	edddddddddeddddde	e
ef dee
 dee dee dede	eef de
de
dedee dededee
 dee
 dee
 dee dee
 dee dee d ee d!ee d"ee d#ee f.d$d%Zefd&efd'd(Zd)d* Zd+d, Zed-d. Ze d/d0 Z!d1d2 Z"d3d4 Z#dee d5dfd6d7Z$d8d9 Z%	:d{d;ed<efd=d>Z&d?d@ Z'dAdB Z(dCdD Z)edEdF Z*ed5e
fdGdHZ+dIe,d5e
fdJdKZ-dLdM Z.d|dNdOZ/d}d;ed5dfdPdQZ0d~dRed5dfdSdTZ1dUdV Z2dWdX Z3dYdZ Z4d[e5e6 d5dfd\d]Z7	:d}d[e	e6e
e5e6 f d;ed5dfd^d_Z8d`edaed5dfdbdcZ9ddde Z:			dd:d	dfdgedhee diedjee fdkdlZ;d`e<d5e=e6 fdmdnZ>doe5e5e<  d5e=e6 fdpdqZ?drds Z@dtdu ZAdveBfdwdxZCdydz ZDdS )rJ   z0Manages communication to and from a Redis server)dbusernameclient_namelib_namelib_versioncredential_providerpasswordsocket_timeoutsocket_connect_timeoutredis_connect_funcretry_on_timeoutretry_on_errorhealth_check_intervalnext_health_checkZlast_active_atencoderssl_contextprotocol_reader_writer_parser_connect_callbacks_buffer_cutoff_lock_socket_read_size__dict__rX   rY   zbUse 'driver_info' parameter instead. lib_name and lib_version will be removed in a future version.)args_to_warnreasonr   NFutf-8stricti   r   )rU   r[   r\   r]   r_   r`   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizera   rW   rX   rY   driver_inforV   retryr^   encoder_classrZ   re   event_dispatcherrU   r[   r\   r]   r_   r`   rr   rs   rt   ru   rv   ra   rW   rw   rV   rx   r^   ry   rZ   re   rz   c                C   s  |s|r|durt d|du rt | _n|| _|| _|| _t|||| _|| _|| _|| _	|| _
|du r7|}|| _|| _|tu rCg }|rV|t |tj |tj || _|s]|rt|sgtt d| _nt|| _| j| ntt d| _|| _d| _||||	| _|| _d| _d| _|| _ | !|
 g | _"d| _#d| _$d| _%zt&|}W n t'y   t(}Y dS  t)y   t*dw |d	k s|d
krt*d|| _+dS )ag  
        Initialize a new async Connection.

        Parameters
        ----------
        driver_info : DriverInfo, optional
            Driver metadata for CLIENT SETINFO. If provided, lib_name and lib_version
            are ignored. If not provided, a DriverInfo will be created from lib_name
            and lib_version (or defaults if those are also None).
        lib_name : str, optional
            **Deprecated.** Use driver_info instead. Library name for CLIENT SETINFO.
        lib_version : str, optional
            **Deprecated.** Use driver_info instead. Library version for CLIENT SETINFO.
        Nz'username' and 'password' cannot be passed along with 'credential_provider'. Please provide only one of the following arguments: 
1. 'password' and (optional) 'username'
2. 'credential_provider'   r   ip  Fzprotocol must be an integerr   r"   zprotocol must be either 2 or 3),r-   r   _event_dispatcherrU   rW   r   rw   rZ   r[   rV   r\   r]   r_   SENTINELappendr1   socketr$   asyncior`   r%   r&   rx   copydeepcopyZupdate_supported_errorsra   rb   rc   r^   rf   rg   rl   
set_parserri   rj   _re_auth_token_should_reconnectint	TypeErrorr'   
ValueErrorr,   re   )rN   rU   r[   r\   r]   r_   r`   rr   rs   rt   ru   rv   ra   rW   rX   rY   rw   rV   rx   r^   ry   rZ   re   rz   prD   rD   rE   __init__   sj   .




zAbstractConnection.__init__	_warningsc                 C   sR   t | dd r'|jd| t| d zt  |   W d S  ty&   Y d S w d S )Nrg   zunclosed Connection )source)getattrwarnResourceWarningr   get_running_loop_closeRuntimeError)rN   r   rD   rD   rE   __del__   s   zAbstractConnection.__del__c                 C   s$   | j r| j   d | _ | _dS dS )zR
        Internal method to silently close the connection without waiting
        N)rg   closerf   rN   rD   rD   rE   r     s   
zAbstractConnection._closec                 C   s8   d dd |  D }d| jj d| jj d| dS )N,c                 s   s"    | ]\}}| d | V  qdS )=NrD   .0kvrD   rD   rE   	<genexpr>  s     z.AbstractConnection.__repr__.<locals>.<genexpr><.(z)>)joinrepr_pieces	__class__r@   r?   )rN   Z	repr_argsrD   rD   rE   __repr__  s    zAbstractConnection.__repr__c                 C   rK   rL   rD   r   rD   rD   rE   r        zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rL   )rf   rg   r   rD   rD   rE   is_connected  s   zAbstractConnection.is_connectedc                 C   s(   t |}|| jvr| j| dS dS )a^  
        Register a callback to be called when the connection is established either
        initially or reconnected.  This allows listeners to issue commands that
        are ephemeral to the connection, for example pub/sub subscription or
        key tracking.  The callback must be a _method_ and will be kept as
        a weak reference.
        N)weakref
WeakMethodri   r   )rN   callbackZwmrD   rD   rE   register_connect_callback!  s   

z,AbstractConnection.register_connect_callbackc                 C   s.   z| j t| W dS  ty   Y dS w )z
        De-register a previously registered callback.  It will no-longer receive
        notifications on connection events.  Calling this is not required when the
        listener goes away, since the callbacks are kept as weak methods.
        N)ri   remover   r   r   )rN   r   rD   rD   rE   deregister_connect_callback-  s
   z.AbstractConnection.deregister_connect_callbackreturnc                 C   s   || j d| _dS )z
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rv   N)rl   rh   )rN   ru   rD   rD   rE   r   8  s   zAbstractConnection.set_parserc                    s*    j  fdd fddI dH  dS )z5Connects to the Redis server if not already connectedc                      s    j dddS )NTF)check_healthretry_socket_connect)connect_check_healthrD   r   rD   rE   <lambda>E  s    z,AbstractConnection.connect.<locals>.<lambda>c                          S rL   
disconnecterrorr   rD   rE   r   H      N)rx   call_with_retryr   rD   r   rE   connect@  s
   

zAbstractConnection.connectTr   r   c              
      sh   j rd S z|r j fdd fddI d H  n  I d H  W n9 tjy-     tjtjfy;   td t	yM } zt
 |d }~w ty] } zt
||d }~ww z" jsl j|dI d H  nt jrz  I d H n   W n ty     I d H   w dd  jD  _ jD ]}| }| }|rt|r|I d H  qd S )Nc                      r   rL   )_connectrD   r   rD   rE   r   S  r   z9AbstractConnection.connect_check_health.<locals>.<lambda>c                    r   rL   r   r   r   rD   rE   r   S  r   zTimeout connecting to serverr   c                 S   s   g | ]}| r|qS rD   rD   )r   refrD   rD   rE   
<listcomp>s  s    z;AbstractConnection.connect_check_health.<locals>.<listcomp>)r   rx   r   r   r   CancelledErrorr   r$   r1   OSErrorr,   _error_message	Exceptionr^   on_connect_check_healthiscoroutinefunctionr/   r   ri   inspectisawaitable)rN   r   r   eexcr   r   taskrD   r   rE   r   K  sP   



z'AbstractConnection.connect_check_healthc                 C   
   d| _ d S )NTr   r   rD   rD   rE   mark_for_reconnectz     
z%AbstractConnection.mark_for_reconnectc                 C      | j S rL   r   r   rD   rD   rE   should_reconnect}     z#AbstractConnection.should_reconnectc                 C   r   )NFr   r   rD   rD   rE   reset_should_reconnect  r   z)AbstractConnection.reset_should_reconnectc                    rT   rL   rD   r   rD   rD   rE   r     s   zAbstractConnection._connectc                 C   rK   rL   rD   r   rD   rD   rE   _host_error  r   zAbstractConnection._host_error	exceptionc                 C   s   t |  |S rL   )r!   r   )rN   r   rD   rD   rE   r        z!AbstractConnection._error_messagec                 C   r   rL   )re   r   rD   rD   rE   get_protocol  r   zAbstractConnection.get_protocolc                    s   | j ddI dH  dS )z=Initialize the connection, authenticate and select a databaseTr   N)r   r   rD   rD   rE   
on_connect  s   zAbstractConnection.on_connectc           
   	      s&  | j |  | j }d }| js| js| jr&| jpt| j| j}| I d H }|r| jdvrt| j t	rC| 
t |j| j _| j |  t|dkrOd|d g}| jd| jdg|R ddiI d H  |  I d H }|d	t| jkr|d
t| jkrtdnq|r| jdg|R ddiI d H  z	|  I d H }W n ty   | jd|d ddI d H  |  I d H }Y nw t|dkrtdn.| jdvrt| j t	r| 
t |j| j _| j |  | jd| j|dI d H  |  I d H }| jr| jdd| j|dI d H  t|  I d H dkrtdd}d}| jr1| jjr1| jddd| jj|dI d H  d}| jrK| jjrK| jddd| jj|dI d H  d}| jr[| jd| j|dI d H  tt||gD ]}	z
|  I d H  W qc tyz   Y qcw | jrt|  I d H dkrtdd S d S )N)r   2r{   defaultr   ZHELLOAUTHr   Fs   protoprotozInvalid RESP versionr|   r   OKzInvalid Username or PasswordZCLIENTZSETNAMEzError setting client nameZSETINFOzLIB-NAMETzLIB-VERZSELECTzInvalid Database)rh   r   rZ   rV   r[   r)   Zget_credentials_asyncre   
isinstancer8   r   r9   ZEXCEPTION_CLASSESlensend_commandread_responsegetr   r,   r+   r4   r*   rW   rw   Zformatted_namerY   rU   rangesumr0   )
rN   r   parserZ	auth_argsZcred_providerresponseZauth_responseZlib_name_sentZlib_version_sent_rD   rD   rE   r     s   




z*AbstractConnection.on_connect_check_healthnowaitc              	      s   zht | j4 I dH Q | j  |   | js%	 W d  I dH  W dS z#z| j  |s6| j I dH  W n	 t	y@   Y nw W d| _
d| _nd| _
d| _w W d  I dH  W dS 1 I dH sbw   Y  W dS  tjyz   td| j dw )z!Disconnects from the Redis serverNz#Timed out closing connection after )async_timeoutr]   rh   Zon_disconnectr   r   rg   r   wait_closedr   rf   r   r1   )rN   r   rD   rD   rE   r     s:   


2
zAbstractConnection.disconnectc                    s8   | j dddI dH  t|  I dH dkrtddS )z Send PING, expect PONG in returnZPINGFr   NZPONGz#Bad response from PING health check)r   r4   r   r,   r   rD   rD   rE   
_send_ping!  s
   zAbstractConnection._send_pingc                       |   I dH  dS )z Function to call when PING failsNr   rN   r   rD   rD   rE   _ping_failed'     zAbstractConnection._ping_failedc                    s>   | j rt  | jkr| j| j| jI dH  dS dS dS )z3Check the health of the connection with a PING/PONGN)	ra   r   r   timerb   rx   r   r   r   r   rD   rD   rE   r   +  s   zAbstractConnection.check_healthcommandc                    s"   | j | | j  I d H  d S rL   )rg   
writelinesdrain)rN   r   rD   rD   rE   _send_packed_command3  s   z'AbstractConnection._send_packed_commandc              
      sX  | j s| jddI d H  |r|  I d H  z5t|tr | }t|tr(|g}| jr;t	| 
|| jI d H  W d S | j| | j I d H  W d S  tjya   | jddI d H  tdd  ty } z/| jddI d H  t|jdkrd|jd }}n
|jd }|jd }td	| d
| d|d }~w ty   | jddI d H   w )NFr   Tr   zTimeout writing to socketr{   UNKNOWNr   zError z while writing to socket. r   )r   r   r   r   strencodebytesr\   r   wait_forr   rg   r   r   r1   r   r   r   argsr,   BaseException)rN   r   r   r   Zerr_noerrmsgrD   rD   rE   send_packed_command7  sF   




z&AbstractConnection.send_packed_commandr   kwargsc                    s(   | j | j| |dddI dH  dS )z+Pack and send a command to the Redis serverr   Tr   N)r   pack_commandr   )rN   r   r   rD   rD   rE   r   `  s   zAbstractConnection.send_commandc              
      s^   z	| j  I dH W S  ty. } z| jddI dH  |  }td| d|j d}~ww )z8Poll the socket to see if there's data that can be read.NTr   Error while reading from z: )rh   can_read_destructiver   r   r   r,   r   )rN   r   
host_errorrD   rD   rE   r   f  s   z'AbstractConnection.can_read_destructive)disconnect_on_errorpush_requestdisable_decodingr$   r  r  c          
   
      s  |dur|n| j }|  }z}|durB| jdv rBt|4 I dH  | jj||dI dH }W d  I dH  n1 I dH s<w   Y  nH|durot|4 I dH  | jj|dI dH }W d  I dH  n1 I dH siw   Y  n| jdv r| jj||dI dH }n
| jj|dI dH }W nT tjy   |durY dS |r| jddI dH  td|  t	y } z|r| jddI dH  t
d| d	|j d}~w ty   |r| jddI dH   w | jrt  | j }	|	| _t|tr|d|S )
z0Read the response from a previously sent commandN)3r"   )r  r  )r  Tr   zTimeout reading from r   z : )r\   r   re   r   rh   r   r   r1   r   r   r,   r   r   ra   r   r   rb   r   r0   )
rN   r  r$   r  r  read_timeoutr   r   r   Z	next_timerD   rD   rE   r   o  s`   	((

z AbstractConnection.read_responsec              	   G   s*  g }t |d trJ t |d tr#t|d   |dd  }nd|d v r7t|d  |dd  }tttt	| t
f}| j}t| jj|D ]>}t	|}t	||ksd||ksdt |tr~t|tt| t
f}|| || t
}qOt|tt| t
|t
f}qO|| |S )z2Pack a series of arguments into the Redis protocolr   r{   N    )r   floatr   tupler   split	SYM_EMPTYr   SYM_STARr   SYM_CRLFrj   maprc   
memoryview
SYM_DOLLARr   )rN   r   outputZbuffbuffer_cutoffargZ
arg_lengthrD   rD   rE   r     s>   "




zAbstractConnection.pack_commandcommandsc           	      C   s   g }g }d}| j }|D ]A}| j| D ]9}t|}||ks%||ks%t|tr3|r/|t| d}g }||ks<t|trB|| q|| ||7 }qq|rW|t| |S )z.Pack multiple commands into the Redis protocolr   )rj   r   r   r   r  r   r
  r   )	rN   r  r  piecesZbuffer_lengthr  cmdchunkZchunklenrD   rD   rE   pack_commands  s.   

z AbstractConnection.pack_commandsc                 C   s   t | jjdkS )zCheck if the socket is emptyr   )r   rf   _bufferr   rD   rD   rE   _socket_is_empty  s   z#AbstractConnection._socket_is_emptyc                    s,   |   s| jddI d H  |   rd S d S )NT)r  )r  r   r   rD   rD   rE   process_invalidation_messages  s   z0AbstractConnection.process_invalidation_messagestokenc                 C   s
   || _ d S rL   )r   rN   r  rD   rD   rE   set_re_auth_token  r   z$AbstractConnection.set_re_auth_tokenc                    sJ   | j d ur#| d| j d| j  I d H  |  I d H  d | _ d S d S Nr   oid)r   r   try_get	get_valuer   r   rD   rD   rE   re_auth   s   



zAbstractConnection.re_auth)TTr   NT)F)FN)Er?   r@   rA   __doc__	__slots__r    r~   rF   r6   r   r   r   r
   r  boollistr>   r   r5   r   r%   ConnectCallbackTr(   r   r   warningsr   r   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   r2   r   r   r  r  r  r   r  r"  rD   rD   rD   rE   rJ   m   s   

	
k


/

s
)
:.rJ   c                       s   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dZdd Zde	fddZdd ZdefddZ  ZS )
Connectionz4Manages TCP communication to and from a Redis server	localhosti  FNr   )hostportsocket_keepalivesocket_keepalive_optionssocket_typer.  r/  r0  r1  r2  c                   s<   || _ t|| _|| _|pi | _|| _t jdi | d S NrD   )r.  r   r/  r0  r1  r2  superr   )rN   r.  r/  r0  r1  r2  r   r   rD   rE   r     s   


zConnection.__init__c                 C   s6   d| j fd| jfd| jfg}| jr|d| jf |S )Nr.  r/  rU   rW   )r.  r/  rU   rW   r   rN   r  rD   rD   rE   r     s   zConnection.repr_piecesr   c                 C   s   | j | jdS )Nr.  r/  r7  r   rD   rD   rE   _connection_arguments%  r   z Connection._connection_argumentsc              	      s   t | j4 I dH  tjdi |  I dH \}}W d  I dH  n1 I dH s*w   Y  || _|| _|jd}|ry|	t
jt
jd z$| jre|	t
jt
jd | j D ]\}}|	t
j|| qXW dS W dS  ttfyx   |   w dS )zCreate a TCP socket connectionNr   r{   rD   )r   r]   r   open_connectionr8  rf   rg   	transportget_extra_info
setsockoptr   IPPROTO_TCPTCP_NODELAYr0  
SOL_SOCKETSO_KEEPALIVEr1  itemsSOL_TCPr   r   r   )rN   readerwritersockr   r   rD   rD   rE   r   (  s.   (zConnection._connectc                 C   s   | j  d| j S )N:r7  r   rD   rD   rE   r   @  s   zConnection._host_error)r?   r@   rA   r%  r   r   r   r'  r
   r	   r   r   r   r8  r   r   __classcell__rD   rD   r5  rE   r,    s,    
r,  c                       s$  e Zd ZdZ												d)dee dee deeejf dee	d	  d
ee	d	  dee dee dee de
dee dee dee f fddZdef fddZedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Z  ZS )*SSLConnectionzManages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    NrequiredTssl_keyfilessl_certfilessl_cert_reqsssl_include_verify_flagsssl.VerifyFlagsssl_exclude_verify_flagsssl_ca_certsssl_ca_datassl_ca_pathssl_check_hostnamessl_min_versionssl_ciphersssl_passwordc                    sD   t stdt|||||||||	|
||d| _t jdi | d S )N$Python wasn't built with SSL support)keyfilecertfile	cert_reqsinclude_verify_flagsexclude_verify_flagsca_certsca_dataca_pathcheck_hostnamemin_versionciphersr[   rD   )r   r/   RedisSSLContextrd   r4  r   )rN   rJ  rK  rL  rM  rO  rP  rQ  rR  rS  rT  rU  rV  r   r5  rD   rE   r   J  s"   zSSLConnection.__init__r   c                    s   t   }| j |d< |S )Nssl)r4  r8  rd   r   rN   r   r5  rD   rE   r8  m  s   
z#SSLConnection._connection_argumentsc                 C      | j jS rL   )rd   rX  r   rD   rD   rE   rX  r     zSSLConnection.keyfilec                 C   rf  rL   )rd   rY  r   rD   rD   rE   rY  v  rg  zSSLConnection.certfilec                 C   rf  rL   )rd   rZ  r   rD   rD   rE   rZ  z  rg  zSSLConnection.cert_reqsc                 C   rf  rL   )rd   r[  r   rD   rD   rE   r[  ~  rg  z"SSLConnection.include_verify_flagsc                 C   rf  rL   )rd   r\  r   rD   rD   rE   r\    rg  z"SSLConnection.exclude_verify_flagsc                 C   rf  rL   )rd   r]  r   rD   rD   rE   r]    rg  zSSLConnection.ca_certsc                 C   rf  rL   )rd   r^  r   rD   rD   rE   r^    rg  zSSLConnection.ca_datac                 C   rf  rL   )rd   r`  r   rD   rD   rE   r`    rg  zSSLConnection.check_hostnamec                 C   rf  rL   )rd   ra  r   rD   rD   rE   ra    rg  zSSLConnection.min_version)NNrI  NNNNNTNNN)r?   r@   rA   r%  r
   r   r   rd  
VerifyModer   r'  r   r   r	   r8  r+  rX  rY  rZ  r[  r\  r]  r^  r`  ra  rG  rD   rD   r5  rE   rH  D  st    

	
#







rH  c                   @   s   e Zd ZdZ												ddee dee deeeejf  dee	d  d	ee	d  d
ee dee dee de
dee dee dee fddZdefddZdS )rc  )rX  rY  rZ  r[  r\  r]  r^  r_  contextr`  ra  rb  r[   NFrX  rY  rZ  r[  rN  r\  r]  r^  r_  r`  ra  rb  r[   c                 C   s   t std|| _|| _|d u rtj}nt|tr1tjtjtj	d}||vr-td| || }|| _
|| _|| _|| _|| _|| _| j
tjkrK|	nd| _|
| _|| _|| _d | _d S )NrW  )noneoptionalrI  z+Invalid SSL Certificate Requirements Flag: F)r   r/   rX  rY  rd  	CERT_NONEr   r   CERT_OPTIONALCERT_REQUIREDrZ  r[  r\  r]  r^  r_  r`  ra  rb  r[   ri  )rN   rX  rY  rZ  r[  r\  r]  r^  r_  r`  ra  rb  r[   Z	CERT_REQSrD   rD   rE   r     s8   

zRedisSSLContext.__init__r   c                 C   s   | j slt }| j|_| j|_| jr| jD ]	}| j|O  _q| jr0| jD ]
}| j| M  _q%| j	s6| j
rA|j| j	| j
| jd | jsJ| jsJ| jrU|j| j| j| jd | jd ur^| j|_| jd uri|| j || _ | j S )N)rY  rX  r[   )cafilecapathcadata)ri  rd  create_default_contextr`  rZ  verify_moder[  verify_flagsr\  rY  rX  load_cert_chainr[   r]  r^  r_  load_verify_locationsra  minimum_versionrb  set_ciphers)rN   ri  flagrD   rD   rE   r     s4   



zRedisSSLContext.get)NNNNNNNNFNNN)r?   r@   rA   r&  r
   r   r   rd  rh  r   r'  r   r   r   r   rD   rD   rD   rE   rc    sP    

	

/rc  c                       sd   e Zd ZdZdddef fddZdeeeeee	f f  fdd	Z
d
d ZdefddZ  ZS )UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server pathr}  c                   s   || _ t jdi | d S r3  )r}  r4  r   )rN   r}  r   r5  rD   rE   r     s   z#UnixDomainSocketConnection.__init__r   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )Nr}  rU   rW   )r}  rU   rW   r   r6  rD   rD   rE   r     s   z&UnixDomainSocketConnection.repr_piecesc              	      sv   t | j4 I d H  tj| jdI d H \}}W d   I d H  n1 I d H s'w   Y  || _|| _|  I d H  d S )Nr|  )r   r]   r   open_unix_connectionr}  rf   rg   r   )rN   rC  rD  rD   rD   rE   r     s   (z#UnixDomainSocketConnection._connectc                 C   r   rL   r|  r   rD   rD   rE   r     r   z&UnixDomainSocketConnection._host_error)r?   r@   rA   r%  r   r   r   r   r   r   r   r   r   rG  rD   rD   r5  rE   rz    s    "rz  )0FFALSENNOr   c                 C   s6   | d u s| dkr
d S t | tr|  tv rdS t| S )Nr{  F)r   r   upperFALSE_STRINGSr'  )valuerD   rD   rE   to_bool  s
   r  c                 C   s\   |  dd dd}g }|dD ]}| }tt|s#td| |tt| q|S )N[r{  ]r   zInvalid ssl verify flag: )replacer	  striphasattrr   r   r   r   )r  Zverify_flags_strrt  ry  rD   rD   rE   parse_ssl_verify_flags  s   
r  )rU   r\   r]   r0  r_   max_connectionsra   rS  rM  rO  r$   .URL_QUERY_ARGUMENT_PARSERSc                   @   sJ   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< dS )	ConnectKwargsrV   r[   connection_classr.  r/  rU   r}  N)r?   r@   rA   r   __annotations__r   rJ   r   rD   rD   rD   rE   r  6  s   
 r  F)totalurlc              
   C   s|  t | }i }t|j D ]7\}}|rDt|dkrDt|d }t|}|r@z||||< W q tt	fy?   t	d| dw |||< q|j
rOt|j
|d< |jrYt|j|d< |jdkrn|jrht|j|d< t|d< |S |jd	v r|jr}t|j|d
< |jrt|j|d< |jrd|vrztt|jdd|d< W n tt	fy   Y nw |jdkrt|d< |S d}t	d| d)Nr   zInvalid value for 'z' in connection URL.rV   r[   unixr}  r  )Zredisredissr.  r/  rU   /r{  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrA  r   r   r  r   r   r   rV   r[   schemer}  rz  hostnamer/  r   r  AttributeErrorrH  )r  parsedr   nameZ
value_listr  r   Zvalid_schemesrD   rD   rE   	parse_url@  sR   




r  _CPConnectionPool)boundc                   @   s  e Zd ZdZedee dedefddZe	dfdee
 d	ee fd
dZdd Zdd ZdefddZedgdddd5ddZdd Zdd Zdd Zde
fdd Zde
fd!d"Zd6d$efd%d&Zd'd( Zd7d)d*Zd8d-d.Zd/efd0d1Zd2efd3d4Z dS )9r  a  
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.ConnectionError` when the pool's
    limit is reached.

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

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    clsr  r   c                 K   s    t |}|| | 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.
        NrD   )r  update)r  r  r   Zurl_optionsrD   rD   rE   from_url  s   +
zConnectionPool.from_urlNr  r  c                 K   s   |pd}t |tr|dk rtd|| _|| _|| _g | _t | _| j	dt
| _t | _| j	dd | _| jd u rAt | _d S d S )Nl        r   z,"max_connections" must be a positive integerry   rz   )r   r   r   r  connection_kwargsr  _available_connectionsset_in_use_connectionsr   r6   ry   r   Lockrk   r}   r   )rN   r  r  r  rD   rD   rE   r     s   

zConnectionPool.__init__c                 C   sN   d dd | j D }d| jj d| jj d| jj d| jj d| dS )	Nr   c                 S   s   g | ]\}}| d | qS )r   rD   r   rD   rD   rE   r     s    z+ConnectionPool.__repr__.<locals>.<listcomp>r   r   z(<r   z)>)>)r   r  rA  r   r@   r?   r  )rN   Zconn_kwargsrD   rD   rE   r     s   zConnectionPool.__repr__c                 C   s   g | _ t | _d S rL   )r  r   WeakSetr  r   rD   rD   rE   reset  s   zConnectionPool.resetc                 C   s   | j p
t| j| jk S )z;Return True if a connection can be retrieved from the pool.)r  r   r  r  r   rD   rD   rE   can_get_connection  s   z!ConnectionPool.can_get_connection*)Use get_connection() without args instead5.3.0rn   ro   versionc              	      s|   | j 4 I dH  |  }W d  I dH  n1 I dH sw   Y  z| |I dH  |W S  ty=   | |I dH   w )z(Get a connected connection from the poolN)rk   get_available_connectionensure_connectionr   release)rN   command_namekeysoptionsrI   rD   rD   rE   get_connection  s   
(zConnectionPool.get_connectionc                 C   sT   z| j  }W n ty!   t| j| jkrtdd|  }Y nw | j| |S )zCGet a connection from the pool, without making sure it is connectedzToo many connectionsN)	r  pop
IndexErrorr   r  r  r.   make_connectionaddrM   rD   rD   rE   r    s   
z'ConnectionPool.get_available_connectionc                 C   s.   | j }| j|dd|dd|dddS )z,Return an encoder based on encoding settingsrr   rp   rs   rq   rt   F)rr   rs   rt   )r  ry   r   re  rD   rD   rE   get_encoder  s   


zConnectionPool.get_encoderc                 C   s   | j di | jS )z=Create a new connection.  Can be overridden by child classes.NrD   )r  r  r   rD   rD   rE   r    s   zConnectionPool.make_connectionrI   c              
      s~   |  I dH  z| I dH rtddW dS  tttfy>   | I dH  |  I dH  | I dH r;tddY dS w )z8Ensure that the connection object is connected and validNzConnection has datazConnection not ready)r   r   r,   r1   r   r   rM   rD   rD   rE   r  	  s   

z ConnectionPool.ensure_connectionc                    sJ   | j | | r| I dH  | j| | jt|I dH  dS )z(Releases the connection back to the poolN)	r  r   r   r   r  r   r}   Zdispatch_asyncr   rM   rD   rD   rE   r    s   zConnectionPool.releaseTinuse_connectionsc                    s\   |rt | j| j}n| j}tjdd |D ddiI dH }tdd |D d}|r,|dS )z
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other tasks. Otherwise only disconnect
        connections that are idle in the pool.
        c                 s   s    | ]}|  V  qd S rL   r   )r   rI   rD   rD   rE   r   5  s    z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTNc                 s   s    | ]
}t |tr|V  qd S rL   )r   r   )r   rrD   rD   rE   r   8  s    )r   r  r  r   gathernext)rN   r  connectionsrespr   rD   rD   rE   r   &  s   zConnectionPool.disconnectc              	      sV   | j 4 I dH  | jD ]}|  qW d  I dH  dS 1 I dH s$w   Y  dS )z<
        Mark all active connections for reconnect.
        N)rk   r  r   )rN   connrD   rD   rE   'update_active_connections_for_reconnect<  s   

.z6ConnectionPool.update_active_connections_for_reconnectc                    r   )z-Close the pool, disconnecting all connectionsNr   r   rD   rD   rE   acloseD  r   zConnectionPool.acloserx   r%   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rL   )r  rx   r  )rN   rx   r  rD   rD   rE   	set_retryH  s
   

zConnectionPool.set_retryr  c              	      s   j 4 I d H B jD ]'  j fddfddI d H   j fddfddI d H  qjD ]   q7W d   I d H  d S 1 I d H sPw   Y  d S )Nc                      s     dd S r  )r   r   r!  rD   )r  r  rD   rE   r   R  s    z1ConnectionPool.re_auth_callback.<locals>.<lambda>c                    
     | S rL   _mockr   r   rD   rE   r   U     
 c                      r   rL   )r   rD   )r  rD   rE   r   X  r   c                    r  rL   r  r   r   rD   rE   r   X  r  )rk   r  rx   r   r  r  r  rD   )r  rN   r  rE   re_auth_callbackN  s   



.zConnectionPool.re_auth_callbackr   c                    s   dS )z
        Dummy functions, needs to be passed as error callback to retry object.
        :param error:
        :return:
        NrD   r   rD   rD   rE   r  ]  s   zConnectionPool._mockrL   r$  r#  )rx   r%   r   N)!r?   r@   rA   r%  classmethodr   r  r   r  r,  rJ   r
   r   r   r   r  r'  r  r    r  r  r  r  r  r  r   r  r  r  r   r  r/   r  rD   rD   rD   rE   r  x  s>    0
	

c                
       s|   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d	Zed
gdddd fdd	Zdef fddZ  ZS )BlockingConnectionPoola  
    A blocking connection pool::

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

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

    The difference is that, in the event that a client tries to get a
    connection from the pool when all of connections are in use, rather than
    raising a :py:class:`~redis.ConnectionError` (as the default
    :py:class:`~redis.asyncio.ConnectionPool` implementation does), it
    blocks the current `Task` for a specified number of seconds until
    a connection becomes available.

    Use ``max_connections`` to increase / decrease the pool size::

        >>> pool = BlockingConnectionPool(max_connections=10)

    Use ``timeout`` to tell it either how many seconds to wait for a connection
    to become available, or to block forever:

        >>> # Block forever.
        >>> pool = BlockingConnectionPool(timeout=None)

        >>> # Raise a ``ConnectionError`` after five seconds if a connection is
        >>> # not available.
        >>> pool = BlockingConnectionPool(timeout=5)
    2      r  r$   r  queue_classc                    s,   t  jd||d| t | _|| _d S )N)r  r  rD   )r4  r   r   	Condition
_conditionr$   )rN   r  r$   r  r  r  r5  rD   rE   r     s   

zBlockingConnectionPool.__init__r  r  r  r  Nc              
      s   zM| j 4 I dH 9 t| j4 I dH  | j | jI dH  t  }W d  I dH  n1 I dH s3w   Y  W d  I dH  n1 I dH sHw   Y  W n tjy` } zt	d|d}~ww z| 
|I dH  |W S  ty|   | |I dH   w )z@Gets a connection from the pool, blocking until one is availableNzNo connection available.)r  r   r$   r   r  r4  r  r   r1   r,   r  r   r  )rN   r  r  r  rI   errr5  rD   rE   r    s(   *(
z%BlockingConnectionPool.get_connectionrI   c              	      s^   | j 4 I dH  t |I dH  | j   W d  I dH  dS 1 I dH s(w   Y  dS )z)Releases the connection back to the pool.N)r  r4  r  notifyrM   r5  rD   rE   r    s
   .zBlockingConnectionPool.releaserL   )r?   r@   rA   r%  r,  r   	LifoQueuer   r
   r  r   rJ   Queuer   r    r  r  rG  rD   rD   r5  rE   r  f  s,    #r  )rr   r   enumr   r   sysr*  r   abcr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   urllib.parser   r   r   r   utilsr   rd  r   r   r   Z
auth.tokenr   rw   r   r   eventr   r   r    r!   version_infor$   r   Zredis.asyncio.retryr%   Zredis.backoffr&   Zredis.connectionr'   Zredis.credentialsr(   r)   Zredis.exceptionsr*   r+   r,   r-   r.   r/   r0   r1   Zredis.typingr2   Zredis.utilsr3   r4   _parsersr5   r6   r7   r8   r9   r  r  r  ZSYM_LFr
  Enumr>   rC   r~   r  rF   rH   rS   r)  rJ   r,  rH  rc  rz  r  r'  r  r  r   r  r  r   rB   r  r  r  r  r  rD   rD   rD   rE   <module>   s   
 <
(
     #9S]
5 o