o
    >h                     @   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"rrd dl#Z#d d	l#m$Z$m%Z% n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, ej-dkrd dl m.Z/ nd dl/m.Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8 d dl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ d dlAmBZB d dlCmDZDmEZEmFZF ddlGmHZHmIZImJZJmKZKmLZL dZMdZNdZOdZPdZQG dd dejRZSeSjTZUeeeKeLeJf  eVd< eDreJZWneKZWG dd  d eZXG d!d" d"eZYeeXeYf ZZG d#d$ d$Z[G d%d& d&e[Z\G d'd( d(e\Z]G d)d* d*Z^G d+d, d,e[Z_d-Z`d.eea fd/d0Zbeecededebebececebedd1	Zeeefed2egf f eVd3< G d4d5 d5ed6d7Zhd8efd.ehfd9d:Zied;d<d=ZjG d>d< d<ZkG d?d@ d@ekZldS )A    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)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 rA   rA   x/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/site-packages/redis/asyncio/connection.pyr;   Q   s    
r;   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocol
connectionAbstractConnectionc                 C      d S NrA   selfrF   rA   rA   rB   __call__`   s    z ConnectCallbackProtocol.__call__NrF   rG   r<   r=   r>   rL   rA   rA   rA   rB   rE   _       rE   c                   @   rD   )AsyncConnectCallbackProtocolrF   rG   c                       d S rI   rA   rJ   rA   rA   rB   rL   d   s    z%AsyncConnectCallbackProtocol.__call__NrM   rN   rA   rA   rA   rB   rP   c   rO   rP   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$drd9efd:d;Z%ed<d= Z&ed3e
fd>d?Z'd@e(d3e
fdAdBZ)dCdD Z*dsdEdFZ+drd9ed3dfdGdHZ,dtdIed3dfdJdKZ-dLdM Z.dNdO Z/dPdQ Z0dRe1e2 d3dfdSdTZ3	8drdRe	e2e
e1e2 f d9ed3dfdUdVZ4dWedXed3dfdYdZZ5d[d\ Z6		dud8dd]d^ed_ee d`edaee fdbdcZ7dWe8d3e9e2 fdddeZ:dfe1e1e8  d3e9e2 fdgdhZ;didj Z<dkdl Z=dme>fdndoZ?dpdq Z@dS )vrG   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   )rR   rX   rY   rZ   r\   r]   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizer^   rT   rU   rV   rS   retryr[   encoder_classrW   rc   event_dispatcherrR   rX   rY   rZ   r\   r]   rn   ro   rp   rq   rr   r^   rT   rU   rV   rS   rs   r[   rt   rW   rc   ru   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_dispatcherrR   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   _re_auth_tokenint	TypeErrorr$   
ValueErrorr)   rc   )rK   rR   rX   rY   rZ   r\   r]   rn   ro   rp   rq   rr   r^   rT   rU   rV   rS   rs   r[   rt   rW   rc   ru   prA   rA   rB   __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 )Nre   zunclosed Connection )source)getattrwarnResourceWarningr|   get_running_loop_closeRuntimeError)rK   r   rA   rA   rB   __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)re   closerd   rK   rA   rA   rB   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 )=NrA   ).0kvrA   rA   rB   	<genexpr>   s     z.AbstractConnection.__repr__.<locals>.<genexpr><.()>)joinrepr_pieces	__class__r=   r<   )rK   	repr_argsrA   rA   rB   __repr__   s    zAbstractConnection.__repr__c                 C   rH   rI   rA   r   rA   rA   rB   r         zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rI   )rd   re   r   rA   rA   rB   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
WeakMethodrg   rz   )rK   callbackwmrA   rA   rB   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)rg   remover   r   r   )rK   r   rA   rA   rB   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
        )rr   N)rj   rf   )rK   rq   rA   rA   rB   r     s   zAbstractConnection.set_parserc                       | j ddI dH  dS )z5Connects to the Redis server if not already connectedTcheck_healthN)connect_check_healthr   rA   rA   rB   connect&     zAbstractConnection.connectTr   c              
      sT   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sb j|dI d H  nt jrp  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                            S rI   )_connectrA   r   rA   rB   <lambda>/      z9AbstractConnection.connect_check_health.<locals>.<lambda>c                    r   rI   
disconnecterrorr   rA   rB   r   /  r   zTimeout connecting to serverr   c                 S   s   g | ]}| r|qS rA   rA   )r   refrA   rA   rB   
<listcomp>M  s    z;AbstractConnection.connect_check_health.<locals>.<listcomp>)r   rs   call_with_retryr|   CancelledErrorr{   r!   r-   OSErrorr)   _error_message	Exceptionr[   on_connect_check_healthiscoroutinefunctionr+   r   rg   inspectisawaitable)rK   r   eexcr   r   taskrA   r   rB   r   *  sJ   



z'AbstractConnection.connect_check_healthc                    rQ   rI   rA   r   rA   rA   rB   r   T  s   zAbstractConnection._connectc                 C   rH   rI   rA   r   rA   rA   rB   _host_errorX  r   zAbstractConnection._host_error	exceptionc                 C   s   t |  |S rI   )r   r   )rK   r   rA   rA   rB   r   \     z!AbstractConnection._error_messagec                 C      | j S rI   )rc   r   rA   rA   rB   get_protocol_     zAbstractConnection.get_protocolc                    r   )z=Initialize the connection, authenticate and select a databaseTr   N)r   r   rA   rA   rB   
on_connectb  r   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| jr%| jddd| j|dI d H  | jr7| jddd| j|dI d H  | jrG| jd| j|dI d H  dd | j| jfD D ]}z
|  I d H  W qR tyi   Y qRw | jr~t|  I d H dkrtdd S d S )N)r   2rv   defaultr   HELLOAUTHr   Fs   protoprotozInvalid RESP versionrw   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 rI   rA   )r   sentrA   rA   rB   r         z=AbstractConnection.on_connect_check_health.<locals>.<genexpr>zInvalid Database)rf   r   rW   rS   rX   r&   get_credentials_asyncrc   
isinstancer5   r   r6   EXCEPTION_CLASSESlensend_commandread_responsegetr   r)   r(   r1   r'   rT   rU   rV   rR   r,   )rK   r   parser	auth_argscred_providerresponseauth_response_rA   rA   rB   r   f  s   




z*AbstractConnection.on_connect_check_health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_timeoutrZ   rf   on_disconnectr   re   r   wait_closedr   rd   r|   r-   )rK   r   rA   rA   rB   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   r1   r   r)   r   rA   rA   rB   
_send_ping  s
   zAbstractConnection._send_pingc                       |   I dH  dS )z Function to call when PING failsNr   rK   r   rA   rA   rB   _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^   r|   r   timer_   rs   r   r   r   r   rA   rA   rB   r     s   zAbstractConnection.check_healthcommandc                    s"   | j | | j  I d H  d S rI   )re   
writelinesdrain)rK   r   rA   rA   rB   _send_packed_command  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 socketrv   UNKNOWNr   zError z while writing to socket. r   )r   r   r   r   strencodebytesrY   r|   wait_forr   re   r   r   r-   r   r   r   argsr)   BaseException)rK   r   r   r   err_noerrmsgrA   rA   rB   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   )rK   r   r  rA   rA   rB   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: )rf   can_read_destructiver   r   r   r)   r   )rK   r   
host_errorrA   rA   rB   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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 : )rY   r   rc   r   rf   r   r|   r-   r   r   r)   r   r   r^   r   r   r_   r   r,   )
rK   r	  r!   r  r  read_timeoutr  r   r   	next_timerA   rA   rB   r   7  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   rv   N    )r   floatr   tupler   split	SYM_EMPTYr   SYM_STARr   SYM_CRLFrh   mapra   
memoryview
SYM_DOLLARrz   )rK   r   outputbuffbuffer_cutoffarg
arg_lengthrA   rA   rB   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   )rh   r  r   r   r  rz   r  r   )	rK   r  r  piecesbuffer_lengthr  cmdchunkchunklenrA   rA   rB   pack_commands  s.   

z AbstractConnection.pack_commandsc                 C   s   t | jjdkS )zCheck if the socket is emptyr   )r   rd   _bufferr   rA   rA   rB   _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   rA   rA   rB   process_invalidation_messages  s   z0AbstractConnection.process_invalidation_messagestokenc                 C   s
   || _ d S rI   )r   rK   r&  rA   rA   rB   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   rA   rA   rB   re_auth  s   



zAbstractConnection.re_authTr   N)F)FN)Ar<   r=   r>   __doc__	__slots__ry   rC   r0   r3   r   r   r   r
   r  boollistr;   r   r2   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-  rA   rA   rA   rB   rG   j   s     

	

Y

*

l
)
:.rG   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_typer9  r:  r;  r<  r=  c                   s<   || _ t|| _|| _|pi | _|| _t jdi | d S NrA   )r9  r   r:  r;  r<  r=  superr   )rK   r9  r:  r;  r<  r=  r  r   rA   rB   r     s   


zConnection.__init__c                 C   s6   d| j fd| jfd| jfg}| jr|d| jf |S )Nr9  r:  rR   rT   )r9  r:  rR   rT   rz   rK   r  rA   rA   rB   r     s   zConnection.repr_piecesr   c                 C   s   | j | jdS )Nr9  r:  rB  r   rA   rA   rB   _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{   rv   rA   )r   rZ   r|   open_connectionrC  rd   re   	transportget_extra_info
setsockoptr{   IPPROTO_TCPTCP_NODELAYr;  
SOL_SOCKETSO_KEEPALIVEr<  itemsSOL_TCPr   r   r   )rK   readerwritersockr   r   rA   rA   rB   r     s.   (zConnection._connectc                 C   s   | j  d| j S )N:rB  r   rA   rA   rB   r     s   zConnection._host_error)r<   r=   r>   r0  r   r   r   r2  r
   r	   r   r   r   rC  r   r   __classcell__rA   rA   r@  rB   r7    s,    
r7  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	ee d
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  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_ca_certsssl_ca_datassl_check_hostnamessl_min_versionssl_ciphersc	           
   
      s<   t stdt||||||||d| _t jdi |	 d S )N$Python wasn't built with SSL support)keyfilecertfile	cert_reqsca_certsca_datacheck_hostnamemin_versionciphersrA   )r   r+   RedisSSLContextrb   r?  r   )
rK   rU  rV  rW  rX  rY  rZ  r[  r\  r  r@  rA   rB   r     s   
zSSLConnection.__init__r   c                    s   t   }| j |d< |S )Nssl)r?  rC  rb   r   rK   r  r@  rA   rB   rC  -  s   
z#SSLConnection._connection_argumentsc                 C      | j jS rI   )rb   r^  r   rA   rA   rB   r^  2     zSSLConnection.keyfilec                 C   ri  rI   )rb   r_  r   rA   rA   rB   r_  6  rj  zSSLConnection.certfilec                 C   ri  rI   )rb   r`  r   rA   rA   rB   r`  :  rj  zSSLConnection.cert_reqsc                 C   ri  rI   )rb   ra  r   rA   rA   rB   ra  >  rj  zSSLConnection.ca_certsc                 C   ri  rI   )rb   rb  r   rA   rA   rB   rb  B  rj  zSSLConnection.ca_datac                 C   ri  rI   )rb   rc  r   rA   rA   rB   rc  F  rj  zSSLConnection.check_hostnamec                 C   ri  rI   )rb   rd  r   rA   rA   rB   rd  J  rj  zSSLConnection.min_version)NNrT  NNTNN)r<   r=   r>   r0  r
   r   r   rg  
VerifyModer2  r   r   r	   rC  r6  r^  r_  r`  ra  rb  rc  rd  rR  rA   rA   r@  rB   rS    sT    	





rS  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ee d	e	d
ee
 dee fddZdefddZdS )rf  )	r^  r_  r`  ra  rb  contextrc  rd  re  NFr^  r_  r`  ra  rb  rc  rd  re  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rB|nd| _|| _|| _d | _d S )Nr]  )noneoptionalrT  z+Invalid SSL Certificate Requirements Flag: F)r   r+   r^  r_  rg  	CERT_NONEr   r   CERT_OPTIONALCERT_REQUIREDr`  ra  rb  rc  rd  re  rl  )
rK   r^  r_  r`  ra  rb  rc  rd  re  	CERT_REQSrA   rA   rB   r   \  s0   

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)r_  r^  )cafilecadata)rl  rg  create_default_contextrc  r`  verify_moder_  r^  load_cert_chainra  rb  load_verify_locationsrd  minimum_versionre  set_ciphers)rK   rl  rA   rA   rB   r     s   

zRedisSSLContext.get)NNNNNFNN)r<   r=   r>   r1  r
   r   r   rg  rk  r2  r   r   r   r   rA   rA   rA   rB   rf  O  s8    	
'rf  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 r>  )r~  r?  r   )rK   r~  r  r@  rA   rB   r     s   z#UnixDomainSocketConnection.__init__r   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )Nr~  rR   rT   )r~  rR   rT   rz   rA  rA   rA   rB   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   rZ   r|   open_unix_connectionr~  rd   re   r   )rK   rN  rO  rA   rA   rB   r     s   (z#UnixDomainSocketConnection._connectc                 C   r   rI   r}  r   rA   rA   rB   r     r   z&UnixDomainSocketConnection._host_error)r<   r=   r>   r0  r   r   r   r   r   r   r   r   r   rR  rA   rA   r@  rB   r{    s    "r{  )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_STRINGSr2  )valuerA   rA   rB   to_bool  s
   r  )	rR   rY   rZ   r;  r\   max_connectionsr^   rZ  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 )	ConnectKwargsrS   rX   connection_classr9  r:  rR   r~  N)r<   r=   r>   r   __annotations__r   rG   r   rA   rA   rA   rB   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.rS   rX   unixr~  r  )redisredissr9  r:  rR   /r|  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrL  r   r   r  r   r   r   rS   rX   schemer~  r{  hostnamer:  r   replaceAttributeErrorrS  )r  parsedr  name
value_listr  r   valid_schemesrA   rA   rB   	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.
        NrA   )r  update)r  r  r  url_optionsrA   rA   rB   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 integerrt   ru   )r   r   r   r  connection_kwargsr  _available_connectionsset_in_use_connectionsr   r3   rt   r|   Lockri   rx   r   )rK   r  r  r  rA   rA   rB   r   D  s   

zConnectionPool.__init__c              	   C   s.   d| j j d| j j d| jdi | jdS )Nr   r   r   r   rA   )r   r=   r<   r  r  r   rA   rA   rB   r   Z  s   zConnectionPool.__repr__c                 C   s   g | _ t | _d S rI   )r  r   WeakSetr  r   rA   rA   rB   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   rA   rA   rB   can_get_connectiond  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 rI   )ri   get_available_connectionensure_connectionr   release)rK   command_namekeysoptionsrF   rA   rA   rB   get_connectionk  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addrJ   rA   rA   rB   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 settingsrn   rl   ro   rm   rp   F)rn   ro   rp   )r  rt   r   rh  rA   rA   rB   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.NrA   )r  r  r   rA   rA   rB   r    s   zConnectionPool.make_connectionrF   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)   r-   r   r   rJ   rA   rA   rB   r    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  rz   rx   dispatch_asyncr   rJ   rA   rA   rB   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 rI   r   )r   rF   rA   rA   rB   r     r   z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTNc                 s   s    | ]
}t |tr|V  qd S rI   )r   r   )r   rrA   rA   rB   r     s    )r   r  r  r|   gathernext)rK   r  connectionsrespr   rA   rA   rB   r     s   zConnectionPool.disconnectc                    r   )z-Close the pool, disconnecting all connectionsNr   r   rA   rA   rB   aclose  r   zConnectionPool.aclosers   r"   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rI   )r  rs   r  )rK   rs   connrA   rA   rB   	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,  rA   )r  r&  rA   rB   r     s    z1ConnectionPool.re_auth_callback.<locals>.<lambda>c                    
     | S rI   _mockr   r   rA   rB   r        
 c                      r   rI   )r   rA   )r  rA   rB   r     r   c                    r  rI   r  r   r   rA   rB   r     r  )ri   r  rs   r   r  r(  r'  rA   )r  rK   r&  rB   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:
        NrA   r   rA   rA   rB   r    s   zConnectionPool._mockrI   r.  r/  )rs   r"   r   N) r<   r=   r>   r0  classmethodr   r  r   r  r7  rG   r
   r   r   r   r  r2  r  r   r  r  r  r  r  r  r   r  r  r   r  r+   r  rA   rA   rA   rB   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  rA   )r?  r   r|   	Condition
_conditionr!   )rK   r  r!   r  r  r  r@  rA   rB   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  r?  r  r|   r-   r)   r  r   r  )rK   r  r  r  rF   errr@  rA   rB   r    s(   *(
z%BlockingConnectionPool.get_connectionrF   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  r?  r  notifyrJ   r@  rA   rB   r  /  s
   .zBlockingConnectionPool.releaserI   )r<   r=   r>   r0  r7  r|   	LifoQueuer   r
   r   rG   Queuer   r   r  r  rR  rA   rA   r@  rB   r    s,    #r  )mr|   r}   enumr   r{   sysr5  r   abcr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   urllib.parser   r   r   r   utilsr   rg  r   r   
auth.tokenr   eventr   r   r   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/   r0   r1   _parsersr2   r3   r4   r5   r6   r  r  r  SYM_LFr  Enumr;   r@   ry   r  rC   rE   rP   r4  rG   r7  rS  rf  r{  r  r2  r  r   r  r  r   r?   r  r  r  r  r  rA   rA   rA   rB   <module>   s   
 <
$	    m9CE
4 `