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 d dlmZmZmZmZ ejdkred dl m Z! nd dl!m Z! d d	l"m#Z# d d
l$m%Z% d dl&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 d dl6m7Z7 d dl8m9Z9m:Z:m;Z; ddl<m=Z=m>Z>m?Z?m@Z@mAZA dZBdZCdZDdZEdZFG dd dejGZHeHjIZJeee@eAe?f  eKd< e9re?ZLne@ZLG dd de'ZMG dd de'ZNeeMeNf ZOG dd  d ZPG d!d" d"ePZQG d#d$ d$eQZRG d%d& d&ZSG d'd( d(ePZTd)ZUd*eeV fd+d,ZWeeXeYeYeWeWeXeXeWd-ZZee[ed.e\f f eKd/< G d0d1 d1e(d2d3Z]d4e[d*e]fd5d6Z^ed7d8d9Z_G d:d8 d8Z`G d;d< d<e`ZadS )=    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalSetTupleTypeTypeVarUnion)ParseResultparse_qsunquoteurlparse)      r   )timeout)Retry)	NoBackoff)Protocol	TypedDict)DEFAULT_RESP_VERSION)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsError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 r9   r9   S/var/www/html/philips/venv/lib/python3.10/site-packages/redis/asyncio/connection.pyr3   B   s    
r3   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocol
connectionAbstractConnectionc                 C      d S Nr9   selfr>   r9   r9   r:   __call__Q   s   z ConnectCallbackProtocol.__call__Nr>   r?   r4   r5   r6   rD   r9   r9   r9   r:   r=   P       r=   c                   @   r<   )AsyncConnectCallbackProtocolr>   r?   c                       d S rA   r9   rB   r9   r9   r:   rD   V   s   z%AsyncConnectCallbackProtocol.__call__NrE   rF   r9   r9   r9   r:   rH   U   rG   rH   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e	e
ef dee
 dee dee dede	eef de
de
dedee dededee
 dee
 dee
 dee
 dee dee dee dee d ee f*d!d"Zd#d$ Zed%d& Zed'd( Zd)d* Zd+d, Zdee d-dfd.d/Zd0d1 Zed2d3 Z ed-e
fd4d5Z!ed6e"d-e
fd7d8Z#d]d9d:Z$d^d;ed-dfd<d=Z%d>d? Z&d@dA Z'dBdC Z(dDe)e* d-dfdEdFZ+	Gd_dDe	e*e
e)e* f dHed-dfdIdJZ,dKe-dLe-d-dfdMdNZ.dOdP Z/		d`dGddQdRedSee dTedUee fdVdWZ0dKe1d-e2e* fdXdYZ3dZe)e)e1  d-e2e* fd[d\Z4dS )ar?   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)   )rJ   rP   rQ   rR   rT   rU   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizerV   rL   rM   rN   rK   retryrS   encoder_classrO   r[   rJ   rP   rQ   rR   rT   rU   rf   rg   rh   ri   rj   rV   rL   rM   rN   rK   rk   rS   rl   rO   r[   c                C   s  |s|r|d urt d|| _|| _|| _|| _|| _|| _|| _|| _|d u r*|}|| _	|| _
|tu r6g }|rI|t |tj |tj || _|sP|rg|sZtt d| _nt|| _| j| ntt d| _|| _d| _||||	| _|| _d | _d | _|| _| |
 g | _ 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!   rJ   rL   rM   rN   rO   rP   rK   rQ   rR   rT   SENTINELappendr$   socketr   asynciorU   r   r   rk   copydeepcopyupdate_supported_errorsrV   rW   rY   rS   r\   r]   rb   
set_parserr_   r`   int	TypeErrorr   
ValueErrorr    r[   )rC   rJ   rP   rQ   rR   rT   rU   rf   rg   rh   ri   rj   rV   rL   rM   rN   rK   rk   rS   rl   rO   r[   pr9   r9   r:   __init__}   sj   


zAbstractConnection.__init__c                 C   s,   d dd |  D }| jj d| dS )N,c                 s   s"    | ]\}}| d | V  qdS )=Nr9   ).0kvr9   r9   r:   	<genexpr>   s     z.AbstractConnection.__repr__.<locals>.<genexpr><>)joinrepr_pieces	__class__r4   )rC   	repr_argsr9   r9   r:   __repr__   s   zAbstractConnection.__repr__c                 C   r@   rA   r9   rC   r9   r9   r:   r         zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rA   )r\   r]   r   r9   r9   r:   is_connected   s   zAbstractConnection.is_connectedc                 C   s(   t |}|| jvr| j| d S d S rA   )weakref
WeakMethodr_   rp   )rC   callbackwmr9   r9   r:   _register_connect_callback   s   

z-AbstractConnection._register_connect_callbackc                 C   s.   z| j t| W d S  ty   Y d S w rA   )r_   remover   r   ry   )rC   r   r9   r9   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
        )rj   N)rb   r^   )rC   ri   r9   r9   r:   rv      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 rA   )_connectr9   r   r9   r:   <lambda>       z,AbstractConnection.connect.<locals>.<lambda>c                    r   rA   
disconnect)errorr   r9   r:   r      r   zTimeout connecting to serverc                 S   s   g | ]}| r|qS r9   r9   )r~   refr9   r9   r:   
<listcomp>  s    z.AbstractConnection.connect.<locals>.<listcomp>)r   rk   call_with_retryrr   CancelledErrorrq   r   r$   OSErrorr    _error_message	ExceptionrS   
on_connectiscoroutinefunctionr"   r   r_   inspectisawaitable)rC   eexcr   r   taskr9   r   r:   connect   sL   


zAbstractConnection.connectc                    rI   rA   r9   r   r9   r9   r:   r     s   zAbstractConnection._connectc                 C   r@   rA   r9   r   r9   r9   r:   _host_error  r   zAbstractConnection._host_error	exceptionc                 C   r@   rA   r9   )rC   r   r9   r9   r:   r     r   z!AbstractConnection._error_messagec              	      s  | j |  | j }d}| js| js| jr#| jpt| j| j}| }|r{| jdvr{t| j t	r@| 
t |j| j _| j |  t|dkrLd|d g}| jd| jdg|R  I dH  |  I dH }|dt| jkrz|d	t| jkrzt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r7| d| jI dH  dd | j| jfD D ]}z
|  I dH  W qB tyY   Y qBw | jrnt|  I dH dkrptddS dS )z=Initialize the connection, authenticate and select a databaseN)r)   2rm   defaultr   HELLOAUTHs   protoprotozInvalid RESP versioncheck_healthFrn   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 rA   r9   )r~   sentr9   r9   r:   r   p      z0AbstractConnection.on_connect.<locals>.<genexpr>zInvalid Database)r^   r   rO   rK   rP   r   get_credentialsr[   
isinstancer-   rv   r.   EXCEPTION_CLASSESlensend_commandread_responsegetrw   r    r   r(   r   rL   rM   rN   rJ   r#   )rC   parser	auth_argscred_providerresponseauth_response_r9   r9   r:   r   #  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_timeoutrR   r^   on_disconnectr   r]   closewait_closedr   r\   rr   r$   )rC   r   r9   r9   r:   r   z  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   r9   r9   r:   
_send_ping  s
   zAbstractConnection._send_pingc                       |   I dH  dS )z Function to call when PING failsNr   )rC   r   r9   r9   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)	rV   rr   get_running_looptimerW   rk   r   r   r   r   r9   r9   r:   r     s   zAbstractConnection.check_healthcommandc                    s"   | j | | j  I d H  d S rA   )r]   
writelinesdrain)rC   r   r9   r9   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 socketrm   UNKNOWNr   Error z while writing to socket. .)r   r   r   r   strencodebytesrQ   rr   wait_forr   r]   r   r   r$   r   r   r   argsr    BaseException)rC   r   r   r   err_noerrmsgr9   r9   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   )rC   r   r   r9   r9   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: )r^   can_read_destructiver   r   r   r    r   )rC   r   
host_errorr9   r9   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 : )rQ   r   r[   r&   r   r^   r   rr   r$   r   r   r    r   r   rV   r   r   rW   r   r#   )
rC   r   r   r   r   read_timeoutr   r   r   	next_timer9   r9   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   rm   N    )r   floatr   tupler   split	SYM_EMPTYr   SYM_STARr   SYM_CRLFr`   maprY   
memoryview
SYM_DOLLARrp   )rC   r   outputbuffbuffer_cutoffarg
arg_lengthr9   r9   r:   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   )r`   r   r   r   r   rp   r   r   )	rC   r   r   piecesbuffer_lengthr   cmdchunkchunklenr9   r9   r:   pack_commandsK  s.   

z AbstractConnection.pack_commandsr   N)FT)FN)5r4   r5   r6   __doc__	__slots__ro   r;   r'   r+   r   r   rw   r
   r   boollistr3   r   r*   r   ConnectCallbackTr   r{   r   r   r   propertyr   r   r   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r   r   r  r9   r9   r9   r:   r?   ]   s     

	

R

)

W
)
>".r?   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de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  r  r  r  c                   s<   || _ t|| _|| _|pi | _|| _t jdi | d S Nr9   )r  rw   r  r  r  r  superr{   )rC   r  r  r  r  r  r   r   r9   r:   r{   m  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  rJ   rL   )r  r  rJ   rL   rp   rC   r   r9   r9   r:   r   ~  s   zConnection.repr_piecesr   c                 C   s   | j | jdS )Nr  r  r  r   r9   r9   r:   _connection_arguments  s   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 connectionNrq   rm   r9   )r   rR   rr   open_connectionr  r\   r]   	transportget_extra_info
setsockoptrq   IPPROTO_TCPTCP_NODELAYr  
SOL_SOCKETSO_KEEPALIVEr  itemsSOL_TCPr   rx   r   )rC   readerwritersockr   r   r9   r9   r:   r     s.   (zConnection._connectc                 C   s   | j  d| j S )N:r  r   r9   r9   r:   r     s   zConnection._host_errorr   c                 C   sd   |   }|jsd| dS t|jdkr d| d|jd  dS d|jd  d| d|jd  dS )	NzError connecting to z. Connection reset by peerrm   . r   r   r   z connecting to )r   r   r   rC   r   r   r9   r9   r:   r     s   zConnection._error_message)r4   r5   r6   r  r   r   rw   r
  r
   r	   r   r{   r   r  r   r   r   r   __classcell__r9   r9   r  r:   r  j  s.    
r  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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  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_hostnamec                    s,   t ||||||d| _t jdi | d S )N)keyfilecertfile	cert_reqsca_certsca_datacheck_hostnamer9   )RedisSSLContextrZ   r  r{   )rC   r.  r/  r0  r1  r2  r3  r   r  r9   r:   r{     s   
zSSLConnection.__init__r   c                    s   t   }| j |d< |S )Nssl)r  r  rZ   r   rC   r   r  r9   r:   r    s   
z#SSLConnection._connection_argumentsc                 C      | j jS rA   )rZ   r4  r   r9   r9   r:   r4       zSSLConnection.keyfilec                 C   r=  rA   )rZ   r5  r   r9   r9   r:   r5    r>  zSSLConnection.certfilec                 C   r=  rA   )rZ   r6  r   r9   r9   r:   r6    r>  zSSLConnection.cert_reqsc                 C   r=  rA   )rZ   r7  r   r9   r9   r:   r7    r>  zSSLConnection.ca_certsc                 C   r=  rA   )rZ   r8  r   r9   r9   r:   r8    r>  zSSLConnection.ca_datac                 C   r=  rA   )rZ   r9  r   r9   r9   r:   r9    r>  zSSLConnection.check_hostname)NNr-  NNF)r4   r5   r6   r  r
   r   r
  r{   r	   r  r  r4  r5  r6  r7  r8  r9  r+  r9   r9   r  r:   r,    sD    




r,  c                   @   sd   e Zd ZdZ						ddee dee dee dee dee d	efd
dZdej	fddZ
dS )r:  )r4  r5  r6  r7  r8  contextr9  NFr4  r5  r6  r7  r8  r9  c                 C   sv   || _ || _|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optionalr-  z+Invalid SSL Certificate Requirements Flag: )r4  r5  r;  	CERT_NONEr6  r   r   CERT_OPTIONALCERT_REQUIREDr"   r7  r8  r9  r?  )rC   r4  r5  r6  r7  r8  r9  	CERT_REQSr9   r9   r:   r{     s$   	



zRedisSSLContext.__init__r   c                 C   sf   | j s0t }| j|_| j|_| jr| jr|j| j| jd | j	s$| j
r-|j| j	| j
d || _ | j S )N)r5  r4  )cafilecadata)r?  r;  create_default_contextr9  r6  verify_moder5  r4  load_cert_chainr7  r8  load_verify_locations)rC   r?  r9   r9   r:   r     s   zRedisSSLContext.get)NNNNNF)r4   r5   r6   r	  r
   r   r
  r{   r;  
SSLContextr   r9   r9   r9   r:   r:    s,    
r:  c                       sv   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dedefddZ  ZS )UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server pathrP  c                   s   || _ t jdi | d S r  )rP  r  r{   )rC   rP  r   r  r9   r:   r{   (  s   z#UnixDomainSocketConnection.__init__r   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )NrP  rJ   rL   )rP  rJ   rL   rp   r  r9   r9   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 )NrO  )r   rR   rr   open_unix_connectionrP  r\   r]   r   )rC   r%  r&  r9   r9   r:   r   2  s   (z#UnixDomainSocketConnection._connectc                 C   s   | j S rA   rO  r   r9   r9   r:   r   9  s   z&UnixDomainSocketConnection._host_errorr   c                 C   sR   |   }t|jdkrd| d|jd  dS d|jd  d| d|jd  dS )Nrm   z!Error connecting to unix socket: r)  r   r   r   z connecting to unix socket: )r   r   r   r*  r9   r9   r:   r   <  s   z)UnixDomainSocketConnection._error_message)r4   r5   r6   r  r   r{   r   r   r   rw   r   r   r   r   r   r+  r9   r9   r  r:   rM  %  s    "rM  )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 )NrN  F)r   r   upperFALSE_STRINGSr
  )valuer9   r9   r:   to_boolN  s
   rZ  )rJ   rQ   rR   r  rT   max_connectionsrV   r3  .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 )	ConnectKwargsrK   rP   connection_classr  r  rJ   rP  N)r4   r5   r6   r   __annotations__r   r?   rw   r9   r9   r9   r:   r]  d  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.rK   rP   unixrP  r^  )redisredissr  r  rJ   /rN  rd  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryr#  r   r   r\  r   rx   ry   rK   rP   schemerP  rM  hostnamer  rw   replaceAttributeErrorr,  )ra  parsedr   name
value_listrY  r   valid_schemesr9   r9   r:   	parse_urln  sR   




rp  _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dd Zdd Zdd Zde
fddZde
fddZd'defdd Zd(d!d"Zd)d%d&ZdS )*rr  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``.
    clsra  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.
        Nr9   )rp  update)rt  ra  r   url_optionsr9   r9   r:   from_url  s   +
zConnectionPool.from_urlNr^  r[  c                 K   sV   |pd}t |tr|dk rtd|| _|| _|| _g | _t | _| j	dt
| _d S )Nl        r   z,"max_connections" must be a positive integerrl   )r   rw   ry   r^  connection_kwargsr[  _available_connectionsset_in_use_connectionsr   r+   rl   )rC   r^  r[  rx  r9   r9   r:   r{     s   zConnectionPool.__init__c                 C   s"   | j j d| jdi | jdS )Nr   r   r9   )r   r4   r^  rx  r   r9   r9   r:   r     s   
zConnectionPool.__repr__c                 C   s   g | _ t | _d S rA   )ry  rz  r{  r   r9   r9   r:   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.)ry  r   r{  r[  r   r9   r9   r:   can_get_connection  s   z!ConnectionPool.can_get_connectionc                    s   z| j  }W n ty"   t| j| jkrtdd|  }Y nw | j| z| 	|I dH  W |S  t
yD   | |I dH   w )zGet a connection from the poolzToo many connectionsN)ry  pop
IndexErrorr   r{  r[  r    make_connectionaddensure_connectionr   release)rC   command_namekeysoptionsr>   r9   r9   r:   get_connection  s    
zConnectionPool.get_connectionc                 C   s.   | j }| j|dd|dd|dddS )z,Return an encoder based on encoding settingsrf   rd   rg   re   rh   F)rf   rg   rh   )rx  rl   r   r<  r9   r9   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.Nr9   )r^  rx  r   r9   r9   r:   r     s   zConnectionPool.make_connectionr>   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   rB   r9   r9   r:   r  $  s   

z ConnectionPool.ensure_connectionc                    s   | j | | j| dS )z(Releases the connection back to the poolN)r{  r   ry  rp   rB   r9   r9   r:   r  4  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 rA   r   )r~   r>   r9   r9   r:   r   J  r   z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTNc                 s   s    | ]
}t |tr|V  qd S rA   )r   r   )r~   rr9   r9   r:   r   M  s    )r   ry  r{  rr   gathernext)rC   r  connectionsrespr   r9   r9   r:   r   ;  s   zConnectionPool.disconnectc                    r   )z-Close the pool, disconnecting all connectionsNr   r   r9   r9   r:   acloseQ  r   zConnectionPool.acloserk   r   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rA   )ry  rk   r{  )rC   rk   connr9   r9   r:   	set_retryU  s
   

zConnectionPool.set_retryr  r  )rk   r   r   N)r4   r5   r6   r  classmethodr   rq  r   rw  r  r?   r
   rw   r{   r   r|  r
  r}  r  r  r  r  r  r   r  r  r9   r9   r9   r:   rr    s,    0
	
c                
       sj   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 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
    makes 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[  r9   )r  r{   rr   	Condition
_conditionr   )rC   r[  r   r^  r  rx  r  r9   r:   r{   ~  s   

zBlockingConnectionPool.__init__c              
      s   zft | j4 I dH O | j4 I dH 0 | j| jI dH  t j|g|R i |I dH W  d  I dH  W  d  I dH  W S 1 I dH sIw   Y  W d  I dH  W dS 1 I dH s`w   Y  W dS  tjyy } zt	d|d}~ww )z@Gets a connection from the pool, blocking until one is availableNzNo connection available.)
r   r   r  r   r}  r  r  rr   r$   r    )rC   r  r  r  errr  r9   r:   r    s   2
z%BlockingConnectionPool.get_connectionr>   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  notifyrB   r  r9   r:   r    s
   .zBlockingConnectionPool.release)r4   r5   r6   r  r  rr   	LifoQueuerw   r
   r   r?   Queuer{   r  r  r+  r9   r9   r  r:   r  \  s"    #
r  )brr   rs   enumr   rq   r;  sysr   abcr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   urllib.parser   r   r   r   version_infor   r   redis.asyncio.retryr   redis.backoffr   redis.compatr   r   redis.connectionr   redis.credentialsr   r   redis.exceptionsr   r   r    r!   r"   r#   r$   redis.typingr%   redis.utilsr&   r'   r(   _parsersr*   r+   r,   r-   r.   r   r   r   SYM_LFr   Enumr3   r8   ro   r_  r;   r=   rH   r  r?   r  r,  r:  rM  rX  r
  rZ  rw   r   r\  r   r7   r]  rp  rq  rr  r  r9   r9   r9   r:   <module>   s   
 4
$	    N85&
4 8