o
    jEi                     @   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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# dd	l$m%Z%m&Z& dd
l'm(Z(m)Z) ej*dkrd dl m+Z, nd dl,m+Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4m5Z5 d dl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= d dl>m?Z? d dl@mAZAmBZBmCZC ddlDmEZEmFZFmGZGmHZHmIZI dZJdZKdZLdZMdZNG dd dejOZPePjQZReeeHeIeGf  eSd< eAreGZTneHZTG dd deZUG dd  d eZVeeUeVf ZWG d!d" d"ZXG d#d$ d$eXZYG d%d& d&eYZZG d'd( d(Z[G d)d* d*eXZ\d+Z]d,ee^ fd-d.Z_ee`eaeae_e_e`e`e_ead/	Zbeeced0edf f eSd1< G d2d3 d3ed4d5Zed6ecd,eefd7d8Zfed9d:d;ZgG d<d: d:ZhG d=d> d>ehZidS )?    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalProtocolSetTupleType	TypedDictTypeVarUnion)ParseResultparse_qsunquoteurlparse   )TokenInterface)!AsyncAfterConnectionReleasedEventEventDispatcher)deprecated_argsformat_error_message)      r   )timeout)Retry)	NoBackoff)DEFAULT_RESP_VERSION)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorConnectionError	DataError
RedisErrorResponseErrorTimeoutError)
EncodableT)HIREDIS_AVAILABLEget_lib_version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 r>   r>   U/var/www/agentarbitrage/venv/lib/python3.10/site-packages/redis/asyncio/connection.pyr8   H   s    
r8   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocol
connectionAbstractConnectionc                 C      d S Nr>   selfrC   r>   r>   r?   __call__W   s    z ConnectCallbackProtocol.__call__NrC   rD   r9   r:   r;   rI   r>   r>   r>   r?   rB   V       rB   c                   @   rA   )AsyncConnectCallbackProtocolrC   rD   c                       d S rF   r>   rG   r>   r>   r?   rI   [   s    z%AsyncConnectCallbackProtocol.__call__NrJ   rK   r>   r>   r>   r?   rM   Z   rL   rM   c                .   @   s  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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 f,d"d#Zefd$efd%d&Zd'd( Zd)d* Zed+d, Zed-d. Z d/d0 Z!d1d2 Z"dee d3dfd4d5Z#d6d7 Z$ed8d9 Z%ed3e
fd:d;Z&d<e'd3e
fd=d>Z(d?d@ Z)dndAdBZ*dodCed3dfdDdEZ+dFdG Z,dHdI Z-dJdK Z.dLe/e0 d3dfdMdNZ1	OdpdLe	e0e
e/e0 f dPed3dfdQdRZ2dSedTed3dfdUdVZ3dWdX Z4		dqdOddYdZed[ee d\ed]ee fd^d_Z5dSe6d3e7e0 fd`daZ8dbe/e/e6  d3e7e0 fdcddZ9dedf Z:dgdh Z;die<fdjdkZ=dldm Z>dS )rrD   z0Manages communication to and from a Redis server)dbusernameclient_namelib_namelib_versioncredential_providerpasswordsocket_timeoutsocket_connect_timeoutredis_connect_funcretry_on_timeoutretry_on_errorhealth_check_intervalnext_health_checklast_active_atencoderssl_contextprotocol_reader_writer_parser_connect_callbacks_buffer_cutoff_lock_socket_read_size__dict__r   NFutf-8stricti   zredis-pyr   )rO   rU   rV   rW   rY   rZ   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizer[   rQ   rR   rS   rP   retryrX   encoder_classrT   r`   event_dispatcherrO   rU   rV   rW   rY   rZ   rk   rl   rm   rn   ro   r[   rQ   rR   rS   rP   rp   rX   rq   rT   r`   rr   c                C   s  |s|r|d urt d|d u rt | _n|| _|| _|| _|| _|| _|| _|| _|| _	|| _
|d u r6|}|| _|| _|tu rBg }|rU|t |tj |tj || _|s\|rs|sftt d| _nt|| _| j| ntt d| _|| _d| _||||	| _|| _d | _d | _|| _ | !|
 g | _"d| _#d | _$z.zt%|}W n t&y   t'}Y n t(y   t)dw W |dk s|dkrt)d	|| _*d S |dk s|dkrt)d	|| _*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'   r   _event_dispatcherrO   rQ   rR   rS   rT   rU   rP   rV   rW   rY   SENTINELappendr*   socketr   asynciorZ   r   r    rp   copydeepcopyupdate_supported_errorsr[   r\   r^   rX   ra   rb   rg   
set_parserrd   re   _re_auth_tokenint	TypeErrorr!   
ValueErrorr&   r`   )rH   rO   rU   rV   rW   rY   rZ   rk   rl   rm   rn   ro   r[   rQ   rR   rS   rP   rp   rX   rq   rT   r`   rr   pr>   r>   r?   __init__   sr   



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 )Nrb   zunclosed Connection )source)getattrwarnResourceWarningry   get_running_loop_closeRuntimeError)rH   r   r>   r>   r?   __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)rb   closera   rH   r>   r>   r?   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 )=Nr>   ).0kvr>   r>   r?   	<genexpr>   s     z.AbstractConnection.__repr__.<locals>.<genexpr><.()>)joinrepr_pieces	__class__r:   r9   )rH   	repr_argsr>   r>   r?   __repr__   s    zAbstractConnection.__repr__c                 C   rE   rF   r>   r   r>   r>   r?   r         zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rF   )ra   rb   r   r>   r>   r?   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
WeakMethodrd   rw   )rH   callbackwmr>   r>   r?   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)rd   remover   r   r   )rH   r   r>   r>   r?   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
        )ro   N)rg   rc   )rH   rn   r>   r>   r?   r}     s   zAbstractConnection.set_parserc              
      sP   j rdS z j fdd fddI dH  W n9 tjy#     tjtjfy1   td tyC } zt	 
|d}~w tyS } zt	||d}~ww z  js`  I dH  nt jrn  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 )z5Connects to the Redis server if not already connectedNc                            S rF   )_connectr>   r   r>   r?   <lambda>#      z,AbstractConnection.connect.<locals>.<lambda>c                    r   rF   
disconnecterrorr   r>   r?   r   #  r   zTimeout connecting to serverc                 S   s   g | ]}| r|qS r>   r>   )r   refr>   r>   r?   
<listcomp>A  s    z.AbstractConnection.connect.<locals>.<listcomp>)r   rp   call_with_retryry   CancelledErrorrx   r   r*   OSErrorr&   _error_message	ExceptionrX   
on_connectiscoroutinefunctionr(   r   rd   inspectisawaitable)rH   eexcr   r   taskr>   r   r?   connect  sJ   



zAbstractConnection.connectc                    rN   rF   r>   r   r>   r>   r?   r   H  s   zAbstractConnection._connectc                 C   rE   rF   r>   r   r>   r>   r?   _host_errorL  r   zAbstractConnection._host_error	exceptionc                 C   s   t |  |S rF   )r   r   )rH   r   r>   r>   r?   r   P     z!AbstractConnection._error_messagec                 C      | j S rF   )r`   r   r>   r>   r?   get_protocolS     zAbstractConnection.get_protocolc              	      s  | j |  | j }d}| js| js| jr&| jpt| j| j}| I dH }|r~| jdvr~t| j t	rC| 
t |j| j _| j |  t|dkrOd|d g}| jd| jdg|R  I dH  |  I dH }|dt| jkr}|d	t| jkr}td
no|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 |  | d| jI dH  |  I dH }| jr| dd| jI dH  t|  I dH dkrtd| jr| ddd| jI dH  | jr,| ddd| jI dH  | jr:| d| jI dH  dd | j| jfD D ]}z
|  I dH  W qE ty\   Y qEw | jrqt|  I dH dkrstddS dS )z=Initialize the connection, authenticate and select a databaseN)r   2rs   defaultr   HELLOAUTHs   protoprotozInvalid RESP versioncheck_healthFrt   r   OKzInvalid Username or PasswordCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTc                 s   s    | ]}|r|V  qd S rF   r>   )r   sentr>   r>   r?   r         z0AbstractConnection.on_connect.<locals>.<genexpr>zInvalid Database)rc   r   rT   rP   rU   r#   get_credentials_asyncr`   
isinstancer2   r}   r3   EXCEPTION_CLASSESlensend_commandread_responsegetr   r&   r%   r.   r$   rQ   rR   rS   rO   r)   )rH   parser	auth_argscred_providerresponseauth_response_r>   r>   r?   r   V  s   




zAbstractConnection.on_connectnowaitc              	      s   zdt | j4 I dH M | j  | js!	 W d  I dH  W dS z#z| j  |s2| 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 s^w   Y  W dS  t
jyv   td| j dw )z!Disconnects from the Redis serverNz#Timed out closing connection after )async_timeoutrW   rc   on_disconnectr   rb   r   wait_closedr   ra   ry   r*   )rH   r   r>   r>   r?   r     s8   


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 returnPINGFr   NPONGz#Bad response from PING health check)r   r.   r   r&   r   r>   r>   r?   
_send_ping  s
   zAbstractConnection._send_pingc                       |   I dH  dS )z Function to call when PING failsNr   rH   r   r>   r>   r?   _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)	r[   ry   r   timer\   rp   r   r   r   r   r>   r>   r?   r     s   zAbstractConnection.check_healthcommandc                    s"   | j | | j  I d H  d S rF   )rb   
writelinesdrain)rH   r   r>   r>   r?   _send_packed_command  s   z'AbstractConnection._send_packed_commandTr   c              
      sV  | j s|  I d H  n	|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y`   | 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 )
NTr   zTimeout writing to socketrs   UNKNOWNr   zError z while writing to socket. r   )r   r   r   r   strencodebytesrV   ry   wait_forr   rb   r   r   r*   r   r   r   argsr&   BaseException)rH   r   r   r   err_noerrmsgr>   r>   r?   send_packed_command  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   )rH   r   r   r>   r>   r?   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: )rc   can_read_destructiver   r   r   r&   r   )rH   r   
host_errorr>   r>   r?   r   
  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rD| jdv rDtsDt|4 I dH  | jj||dI dH }W d  I dH  n1 I dH s>w   Y  nJ|durqt|4 I dH  | jj|dI dH }W d  I dH  n1 I dH skw   Y  n| jdv rts| 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 : )rV   r   r`   r,   r   rc   r   ry   r*   r   r   r&   r   r   r[   r   r   r\   r   r)   )
rH   r  r   r   r  read_timeoutr   r   r   	next_timer>   r>   r?   r     sf   	
((
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   rs   N    )r   floatr   tupler   split	SYM_EMPTYr   SYM_STARr   SYM_CRLFre   mapr^   
memoryview
SYM_DOLLARrw   )rH   r   outputbuffbuffer_cutoffarg
arg_lengthr>   r>   r?   r   Q  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   )re   r   r   r   r  rw   r
  r   )	rH   r  r  piecesbuffer_lengthr  cmdchunkchunklenr>   r>   r?   pack_commands  s.   

z AbstractConnection.pack_commandsc                 C   s   t | jjdkS )zCheck if the socket is emptyr   )r   ra   _bufferr   r>   r>   r?   _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   r>   r>   r?   process_invalidation_messages  s   z0AbstractConnection.process_invalidation_messagestokenc                 C   s
   || _ d S rF   )r~   rH   r  r>   r>   r?   set_re_auth_token  s   
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   r>   r>   r?   re_auth  s   



zAbstractConnection.re_authr   N)FT)FN)?r9   r:   r;   __doc__	__slots__rv   r@   r-   r0   r   r   r   r
   r  boollistr8   r   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  r  r   r!  r&  r>   r>   r>   r?   rD   a   s     

	

Y

+

X
)
>.rD   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_typer2  r3  r4  r5  r6  c                   s<   || _ t|| _|| _|pi | _|| _t jdi | d S Nr>   )r2  r   r3  r4  r5  r6  superr   )rH   r2  r3  r4  r5  r6  r   r   r>   r?   r     s   


zConnection.__init__c                 C   s6   d| j fd| jfd| jfg}| jr|d| jf |S )Nr2  r3  rO   rQ   )r2  r3  rO   rQ   rw   rH   r  r>   r>   r?   r     s   zConnection.repr_piecesr   c                 C   s   | j | jdS )Nr2  r3  r;  r   r>   r>   r?   _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 connectionNrx   rs   r>   )r   rW   ry   open_connectionr<  ra   rb   	transportget_extra_info
setsockoptrx   IPPROTO_TCPTCP_NODELAYr4  
SOL_SOCKETSO_KEEPALIVEr5  itemsSOL_TCPr   r   r   )rH   readerwritersockr   r   r>   r>   r?   r     s.   (zConnection._connectc                 C   s   | j  d| j S )N:r;  r   r>   r>   r?   r     s   zConnection._host_error)r9   r:   r;   r)  r   r   r   r+  r
   r	   r   r   r   r<  r   r   __classcell__r>   r>   r9  r?   r0    s,    
r0  c                       s   e Zd ZdZ								d dee dee dedee d	ee d
edeej 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  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requiredFssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_ca_datassl_check_hostnamessl_min_versionssl_ciphersc	           
   
      s0   t ||||||||d| _t jdi |	 d S )N)keyfilecertfile	cert_reqsca_certsca_datacheck_hostnamemin_versionciphersr>   )RedisSSLContextr_   r8  r   )
rH   rN  rO  rP  rQ  rR  rS  rT  rU  r   r9  r>   r?   r     s   
zSSLConnection.__init__r   c                    s   t   }| j |d< |S )Nssl)r8  r<  r_   r   rH   r   r9  r>   r?   r<  
  s   
z#SSLConnection._connection_argumentsc                 C      | j jS rF   )r_   rV  r   r>   r>   r?   rV       zSSLConnection.keyfilec                 C   ra  rF   )r_   rW  r   r>   r>   r?   rW    rb  zSSLConnection.certfilec                 C   ra  rF   )r_   rX  r   r>   r>   r?   rX    rb  zSSLConnection.cert_reqsc                 C   ra  rF   )r_   rY  r   r>   r>   r?   rY    rb  zSSLConnection.ca_certsc                 C   ra  rF   )r_   rZ  r   r>   r>   r?   rZ    rb  zSSLConnection.ca_datac                 C   ra  rF   )r_   r[  r   r>   r>   r?   r[  #  rb  zSSLConnection.check_hostnamec                 C   ra  rF   )r_   r\  r   r>   r>   r?   r\  '  rb  zSSLConnection.min_version)NNrM  NNFNN)r9   r:   r;   r)  r
   r   r+  r_  
TLSVersionr   r	   r<  r/  rV  rW  rX  rY  rZ  r[  r\  rK  r>   r>   r9  r?   rL    sT    	





rL  c                   @   sz   e Zd ZdZ								ddee dee dee dee dee d	ed
eej dee fddZ	dej
fddZdS )r^  )	rV  rW  rX  rY  rZ  contextr[  r\  r]  NFrV  rW  rX  rY  rZ  r[  r\  r]  c	           
      C   s   || _ || _|d u rtj| _nt|tr-tjtjtjd}	||	vr(t	d| |	| | _|| _
|| _|| _|| _|| _d | _d S )N)noneoptionalrM  z+Invalid SSL Certificate Requirements Flag: )rV  rW  r_  	CERT_NONErX  r   r   CERT_OPTIONALCERT_REQUIREDr(   rY  rZ  r[  r\  r]  rd  )
rH   rV  rW  rX  rY  rZ  r[  r\  r]  	CERT_REQSr>   r>   r?   r   9  s(   



zRedisSSLContext.__init__r   c                 C   s   | j sDt }| j|_| j|_| jr| jr|j| j| jd | j	s$| j
r-|j| j	| j
d | jd ur6| j|_| jd urA|| j || _ | j S )N)rW  rV  )cafilecadata)rd  r_  create_default_contextr[  rX  verify_moderW  rV  load_cert_chainrY  rZ  load_verify_locationsr\  minimum_versionr]  set_ciphers)rH   rd  r>   r>   r?   r   Z  s   

zRedisSSLContext.get)NNNNNFNN)r9   r:   r;   r*  r
   r   r+  r_  rc  r   
SSLContextr   r>   r>   r>   r?   r^  ,  s8    	
!r^  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 pathrw  c                   s   || _ t jdi | d S r7  )rw  r8  r   )rH   rw  r   r9  r>   r?   r   n  s   z#UnixDomainSocketConnection.__init__r   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )Nrw  rO   rQ   )rw  rO   rQ   rw   r:  r>   r>   r?   r   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 )Nrv  )r   rW   ry   open_unix_connectionrw  ra   rb   r   )rH   rG  rH  r>   r>   r?   r   x  s   (z#UnixDomainSocketConnection._connectc                 C   r   rF   rv  r   r>   r>   r?   r     r   z&UnixDomainSocketConnection._host_error)r9   r:   r;   r)  r   r   r   r   r   r   r   r   r   rK  r>   r>   r9  r?   rt  k  s    "rt  )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 )Nru  F)r   r   upperFALSE_STRINGSr+  )valuer>   r>   r?   to_bool  s
   r  )	rO   rV   rW   r4  rY   max_connectionsr[   rS  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 )	ConnectKwargsrP   rU   connection_classr2  r3  rO   rw  N)r9   r:   r;   r   __annotations__r   rD   r   r>   r>   r>   r?   r    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.rP   rU   unixrw  r  )redisredissr2  r3  rO   /ru  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrE  r   r   r  r   r   r   rP   rU   schemerw  rt  hostnamer3  r   replaceAttributeErrorrL  )r  parsedr   name
value_listr  r   valid_schemesr>   r>   r?   	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d3ddZdd Zdd Zdd Zde
fdd Zde
fd!d"Zd4d$efd%d&Zd5d'd(Zd6d+d,Zd-efd.d/Zd0efd1d2ZdS )7r  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                 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.
        Nr>   )r  update)r  r  r   url_optionsr>   r>   r?   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 integerrq   rr   )r   r   r   r  connection_kwargsr  _available_connectionsset_in_use_connectionsr   r0   rq   ry   Lockrf   ru   r   )rH   r  r  r  r>   r>   r?   r     s   

zConnectionPool.__init__c              	   C   s.   d| j j d| j j d| jdi | jdS )Nr   r   r   r   r>   )r   r:   r9   r  r  r   r>   r>   r?   r   1  s   zConnectionPool.__repr__c                 C   s   g | _ t | _d S rF   )r  r   WeakSetr  r   r>   r>   r?   reset7  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   r>   r>   r?   can_get_connection;  s   z!ConnectionPool.can_get_connection*)Use get_connection() without args instead5.3.0args_to_warnreasonversionc              	      s   | j 4 I d H , 	 |  }z
| |I d H  W n ty(   | |I d H   w W d   I d H  |S 1 I d H s:w   Y  |S rF   )rf   get_available_connectionensure_connectionr   release)rH   command_namekeysoptionsrC   r>   r>   r?   get_connectionB  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addrG   r>   r>   r?   r  S  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 settingsrk   ri   rl   rj   rm   F)rk   rl   rm   )r  rq   r   r`  r>   r>   r?   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.Nr>   )r  r  r   r>   r>   r?   r  g  s   zConnectionPool.make_connectionrC   c              	      s|   |  I dH  z| I dH rtddW dS  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&   r   r   rG   r>   r>   r?   r  k  s   

z ConnectionPool.ensure_connectionc                    s4   | j | | j| | jt|I dH  dS )z(Releases the connection back to the poolN)r  r   r  rw   ru   dispatch_asyncr   rG   r>   r>   r?   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 rF   r   )r   rC   r>   r>   r?   r     r   z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTNc                 s   s    | ]
}t |tr|V  qd S rF   )r   r   )r   rr>   r>   r?   r     s    )r   r  r  ry   gathernext)rH   r  connectionsrespr   r>   r>   r?   r     s   zConnectionPool.disconnectc                    r   )z-Close the pool, disconnecting all connectionsNr   r   r>   r>   r?   aclose  r   zConnectionPool.acloserp   r   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rF   )r  rp   r  )rH   rp   connr>   r>   r?   	set_retry  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%  r>   )r  r  r>   r?   r     s    z1ConnectionPool.re_auth_callback.<locals>.<lambda>c                    
     | S rF   _mockr   r   r>   r?   r        
 c                      r   rF   )r   r>   )r  r>   r?   r     r   c                    r  rF   r  r   r   r>   r?   r     r  )rf   r  rp   r   r  r!  r   r>   )r  rH   r  r?   re_auth_callback  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:
        Nr>   r   r>   r>   r?   r    s   zConnectionPool._mockrF   r(  r'  )rp   r   r   N) r9   r:   r;   r)  classmethodr   r  r   r  r0  rD   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    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  r>   )r8  r   ry   	Condition
_conditionr   )rH   r  r   r  r  r  r9  r>   r?   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  r8  r  ry   r*   r&   r  r   r  )rH   r  r  r  rC   errr9  r>   r?   r    s(   *(
z%BlockingConnectionPool.get_connectionrC   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  r8  r  notifyrG   r9  r>   r?   r    s
   .zBlockingConnectionPool.releaserF   )r9   r:   r;   r)  r0  ry   	LifoQueuer   r
   r   rD   Queuer   r   r  r  rK  r>   r>   r9  r?   r    s,    #r  )jry   rz   enumr   rx   r_  sysr.  r   abcr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   urllib.parser   r   r   r   
auth.tokenr   eventr   r   utilsr   r   version_infor   r   redis.asyncio.retryr   redis.backoffr    redis.connectionr!   redis.credentialsr"   r#   redis.exceptionsr$   r%   r&   r'   r(   r)   r*   redis.typingr+   redis.utilsr,   r-   r.   _parsersr/   r0   r1   r2   r3   r  r  r  SYM_LFr
  Enumr8   r=   rv   r  r@   rB   rM   r-  rD   r0  rL  r^  rt  r  r+  r  r   r  r  r   r<   r  r  r  r  r  r>   r>   r>   r?   <module>   s   
 <
$	    V9@?
4 `