o
    /i                     @   sP  U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZm Z  ddl!m"Z" e"rtd dl#Z#d d	l#m$Z$m%Z%m&Z& ndZ#dZ%dZ$dZ&dd
l'm(Z( ddl)m*Z*m+Z+ ddl!m,Z,m-Z- ej.dkrd dl m/Z0 nd dl0m/Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZA d dlBmCZC d dlDmEZEmFZFmGZG ddlHmIZImJZJmKZKmLZLmMZM dZNdZOdZPdZQdZRG dd dejSZTeTjUZVeeeLeMeKf  eWd< eEreKZXneLZXG dd  d eZYG d!d" d"eZZeeYeZf Z[G 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-Zad.eeb fd/d0Zcd1d2 Zdeeeefefececeeeeecededefd3Zgeehed4eif f eWd5< G d6d7 d7ed8d9Zjd:ehd.ejfd;d<Zked=d>d?ZlG d@d> d>ZmG dAdB dBemZndS )C    N)abstractmethod)chain)MappingProxyType)AnyCallableIterableListMappingOptionalProtocolSetTupleType	TypedDictTypeVarUnion)ParseResultparse_qsunquoteurlparse   )SSL_AVAILABLE)
SSLContext
TLSVersionVerifyFlags)TokenInterface)!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 rB   rB   X/var/www/html/flask_server/venv/lib/python3.10/site-packages/redis/asyncio/connection.pyr<   R   s    
r<   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocol
connectionAbstractConnectionc                 C      d S NrB   selfrG   rB   rB   rC   __call__a   s    z ConnectCallbackProtocol.__call__NrG   rH   r=   r>   r?   rM   rB   rB   rB   rC   rF   `       rF   c                   @   rE   )AsyncConnectCallbackProtocolrG   rH   c                       d S rJ   rB   rK   rB   rB   rC   rM   e   s    z%AsyncConnectCallbackProtocol.__call__NrN   rO   rB   rB   rB   rC   rQ   d   rP   rQ   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$	8dwd9ed:efd;d<Z%d=d> Z&d?d@ Z'edAdB Z(ed3e
fdCdDZ)dEe*d3e
fdFdGZ+dHdI Z,dxdJdKZ-dyd9ed3dfdLdMZ.dzdNed3dfdOdPZ/dQdR Z0dSdT Z1dUdV Z2dWe3e4 d3dfdXdYZ5	8dydWe	e4e
e3e4 f d9ed3dfdZd[Z6d\ed]ed3dfd^d_Z7d`da Z8		d{d8ddbdceddee deedfee fdgdhZ9d\e:d3e;e4 fdidjZ<dke3e3e:  d3e;e4 fdldmZ=dndo Z>dpdq Z?dre@fdsdtZAdudv ZBdS )|rH   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   )rS   rY   rZ   r[   r]   r^   encodingencoding_errorsdecode_responsesparser_classsocket_read_sizer_   rU   rV   rW   rT   retryr\   encoder_classrX   rd   event_dispatcherrS   rY   rZ   r[   r]   r^   ro   rp   rq   rr   rs   r_   rU   rV   rW   rT   rt   r\   ru   rX   rd   rv   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 | _$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  Fzprotocol must be an integerr   r    zprotocol must be either 2 or 3),r+   r   _event_dispatcherrS   rU   rV   rW   rX   rY   rT   rZ   r[   r]   SENTINELappendr.   socketr"   asyncior^   r#   r$   rt   copydeepcopyupdate_supported_errorsr_   r`   rb   r\   re   rf   rk   
set_parserrh   ri   _re_auth_token_should_reconnectint	TypeErrorr%   
ValueErrorr*   rd   )rL   rS   rY   rZ   r[   r]   r^   ro   rp   rq   rr   rs   r_   rU   rV   rW   rT   rt   r\   ru   rX   rd   rv   prB   rB   rC   __init__   st   



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 )Nrf   zunclosed Connection )source)getattrwarnResourceWarningr}   get_running_loop_closeRuntimeError)rL   r   rB   rB   rC   __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)rf   closere   rL   rB   rB   rC   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 )=NrB   .0kvrB   rB   rC   	<genexpr>   s     z.AbstractConnection.__repr__.<locals>.<genexpr><.(z)>)joinrepr_pieces	__class__r>   r=   )rL   	repr_argsrB   rB   rC   __repr__   s    zAbstractConnection.__repr__c                 C   rI   rJ   rB   r   rB   rB   rC   r        zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rJ   )re   rf   r   rB   rB   rC   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
WeakMethodrh   r{   )rL   callbackwmrB   rB   rC   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)rh   remover   r   r   )rL   r   rB   rB   rC   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
        )rs   N)rk   rg   )rL   rr   rB   rB   rC   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   rB   rB   rC   connect(     zAbstractConnection.connectTr   retry_socket_connectc              
      sh   j rd S z|r j fdd fddI d H  n  I d H  W n9 tjy-     tjtjfy;   td t	yM } zt
 |d }~w ty] } zt
||d }~ww z" jsl j|dI d H  nt jrz  I d H n   W n ty     I d H   w dd  jD  _ jD ]}| }| }|rt|r|I d H  qd S )Nc                            S rJ   )_connectrB   r   rB   rC   <lambda>4      z9AbstractConnection.connect_check_health.<locals>.<lambda>c                    r   rJ   
disconnecterrorr   rB   rC   r   4  r   zTimeout connecting to serverr   c                 S   s   g | ]}| r|qS rB   rB   )r   refrB   rB   rC   
<listcomp>T  s    z;AbstractConnection.connect_check_health.<locals>.<listcomp>)r   rt   call_with_retryr   r}   CancelledErrorr|   r"   r.   OSErrorr*   _error_message	Exceptionr\   on_connect_check_healthiscoroutinefunctionr,   r   rh   inspectisawaitable)rL   r   r   eexcr   r   taskrB   r   rC   r   ,  sP   



z'AbstractConnection.connect_check_healthc                 C   s
   d| _ d S )NTr   r   rB   rB   rC   mark_for_reconnect[     
z%AbstractConnection.mark_for_reconnectc                 C      | j S rJ   r   r   rB   rB   rC   should_reconnect^     z#AbstractConnection.should_reconnectc                    rR   rJ   rB   r   rB   rB   rC   r   a  s   zAbstractConnection._connectc                 C   rI   rJ   rB   r   rB   rB   rC   _host_errore  r   zAbstractConnection._host_error	exceptionc                 C   s   t |  |S rJ   )r   r   )rL   r   rB   rB   rC   r   i     z!AbstractConnection._error_messagec                 C   r   rJ   )rd   r   rB   rB   rC   get_protocoll  r   zAbstractConnection.get_protocolc                    r   )z=Initialize the connection, authenticate and select a databaseTr   N)r   r   rB   rB   rC   
on_connecto  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   2rw   defaultr   HELLOAUTHr   Fs   protoprotozInvalid RESP versionrx   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 rJ   rB   )r   sentrB   rB   rC   r         z=AbstractConnection.on_connect_check_health.<locals>.<genexpr>zInvalid Database)rg   r   rX   rT   rY   r'   get_credentials_asyncrd   
isinstancer6   r   r7   EXCEPTION_CLASSESlensend_commandread_responsegetr   r*   r)   r2   r(   rU   rV   rW   rS   r-   )rL   r   parser	auth_argscred_providerresponseauth_response_rB   rB   rC   r   s  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_timeoutr[   rg   on_disconnectr   rf   r   wait_closedr   re   r}   r.   )rL   r   rB   rB   rC   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   r2   r   r*   r   rB   rB   rC   
_send_ping  s
   zAbstractConnection._send_pingc                       |   I dH  dS )z Function to call when PING failsNr   rL   r   rB   rB   rC   _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`   rt   r   r   r   r   rB   rB   rC   r      s   zAbstractConnection.check_healthcommandc                    s"   | j | | j  I d H  d S rJ   )rf   
writelinesdrain)rL   r   rB   rB   rC   _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 socketrw   UNKNOWNr   zError z while writing to socket. r   )r   r   r   r   strencodebytesrZ   r}   wait_forr   rf   r   r   r.   r   r   r   argsr*   BaseException)rL   r   r   r   err_noerrmsgrB   rB   rC   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   )rL   r  r	  rB   rB   rC   r   5  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: )rg   can_read_destructiver   r   r   r*   r  )rL   r   
host_errorrB   rB   rC   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 : )rZ   r   rd   r   rg   r   r}   r.   r   r   r*   r  r  r_   r   r   r`   r   r-   )
rL   r  r"   r  r  read_timeoutr  r   r   	next_timerB   rB   rC   r   D  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   rw   N    )r   floatr   tupler  split	SYM_EMPTYr   SYM_STARr   SYM_CRLFri   maprb   
memoryview
SYM_DOLLARr{   )rL   r  outputbuffbuffer_cutoffarg
arg_lengthrB   rB   rC   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   )ri   r
  r   r   r  r{   r  r   )	rL   r#  r  piecesbuffer_lengthr   cmdchunkchunklenrB   rB   rC   pack_commands  s.   

z AbstractConnection.pack_commandsc                 C   s   t | jjdkS )zCheck if the socket is emptyr   )r   re   _bufferr   rB   rB   rC   _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   rB   rB   rC   process_invalidation_messages  s   z0AbstractConnection.process_invalidation_messagestokenc                 C   s
   || _ d S rJ   )r   rL   r-  rB   rB   rC   set_re_auth_token  r   z$AbstractConnection.set_re_auth_tokenc                    sJ   | j d ur#| d| j d| j  I d H  |  I d H  d | _ d S d S Nr   oid)r   r   try_get	get_valuer   r   rB   rB   rC   re_auth  s   



zAbstractConnection.re_auth)TTr   NT)F)FN)Cr=   r>   r?   __doc__	__slots__rz   rD   r1   r4   r   r   r   r
   r  boollistr<   r   r3   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/  r4  rB   rB   rB   rC   rH   k   s    

	

Z


/

l
)
:.rH   c                       s   e Zd ZdZddddddded	eeef d
edee	eeee
f f  def
 fddZdd Zde	fddZdd ZdefddZ  ZS )
Connectionz4Manages TCP communication to and from a Redis server	localhosti  FNr   )hostportsocket_keepalivesocket_keepalive_optionssocket_typer@  rA  rB  rC  rD  c                   s<   || _ t|| _|| _|pi | _|| _t jdi | d S NrB   )r@  r   rA  rB  rC  rD  superr   )rL   r@  rA  rB  rC  rD  r	  r   rB   rC   r     s   


zConnection.__init__c                 C   s6   d| j fd| jfd| jfg}| jr|d| jf |S )Nr@  rA  rS   rU   )r@  rA  rS   rU   r{   rL   r$  rB   rB   rC   r     s   zConnection.repr_piecesr   c                 C   s   | j | jdS )Nr@  rA  rI  r   rB   rB   rC   _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|   rw   rB   )r   r[   r}   open_connectionrJ  re   rf   	transportget_extra_info
setsockoptr|   IPPROTO_TCPTCP_NODELAYrB  
SOL_SOCKETSO_KEEPALIVErC  itemsSOL_TCPr   r   r   )rL   readerwritersockr   r   rB   rB   rC   r     s.   (zConnection._connectc                 C   s   | j  d| j S )N:rI  r   rB   rB   rC   r     s   zConnection._host_error)r=   r>   r?   r7  r   r   r   r9  r
   r	   r  r   r   rJ  r   r   __classcell__rB   rB   rG  rC   r>    s,    
r>  c                       s  e Zd ZdZ										d'dee dee deeejf dee	d	  d
ee	d	  dee dee de
dee dee f fddZdef fddZedd Zedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Z  ZS )(SSLConnectionzManages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    NrequiredTssl_keyfilessl_certfilessl_cert_reqsssl_include_verify_flagsssl.VerifyFlagsssl_exclude_verify_flagsssl_ca_certsssl_ca_datassl_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include_verify_flagsexclude_verify_flagsca_certsca_datacheck_hostnamemin_versionciphersrB   )r   r,   RedisSSLContextrc   rF  r   )rL   r\  r]  r^  r_  ra  rb  rc  rd  re  rf  r	  rG  rB   rC   r     s   zSSLConnection.__init__r   c                    s   t   }| j |d< |S )Nssl)rF  rJ  rc   r   rL   r	  rG  rB   rC   rJ  >  s   
z#SSLConnection._connection_argumentsc                 C      | j jS rJ   )rc   rh  r   rB   rB   rC   rh  C     zSSLConnection.keyfilec                 C   ru  rJ   )rc   ri  r   rB   rB   rC   ri  G  rv  zSSLConnection.certfilec                 C   ru  rJ   )rc   rj  r   rB   rB   rC   rj  K  rv  zSSLConnection.cert_reqsc                 C   ru  rJ   )rc   rk  r   rB   rB   rC   rk  O  rv  z"SSLConnection.include_verify_flagsc                 C   ru  rJ   )rc   rl  r   rB   rB   rC   rl  S  rv  z"SSLConnection.exclude_verify_flagsc                 C   ru  rJ   )rc   rm  r   rB   rB   rC   rm  W  rv  zSSLConnection.ca_certsc                 C   ru  rJ   )rc   rn  r   rB   rB   rC   rn  [  rv  zSSLConnection.ca_datac                 C   ru  rJ   )rc   ro  r   rB   rB   rC   ro  _  rv  zSSLConnection.check_hostnamec                 C   ru  rJ   )rc   rp  r   rB   rB   rC   rp  c  rv  zSSLConnection.min_version)
NNr[  NNNNTNN)r=   r>   r?   r7  r
   r   r   rs  
VerifyModer   r9  r   r   r	   rJ  r=  rh  ri  rj  rk  rl  rm  rn  ro  rp  rY  rB   rB   rG  rC   rZ    sh    

	








rZ  c                   @   s   e Zd ZdZ										ddee dee deeeejf  dee	d  d	ee	d  d
ee dee de
dee dee fddZdefddZdS )rr  )rh  ri  rj  rk  rl  rm  rn  contextro  rp  rq  NFrh  ri  rj  rk  r`  rl  rm  rn  ro  rp  rq  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rH|nd| _|	| _|
| _d | _d S )Nrg  )noneoptionalr[  z+Invalid SSL Certificate Requirements Flag: F)r   r,   rh  ri  rs  	CERT_NONEr   r   CERT_OPTIONALCERT_REQUIREDrj  rk  rl  rm  rn  ro  rp  rq  rx  )rL   rh  ri  rj  rk  rl  rm  rn  ro  rp  rq  	CERT_REQSrB   rB   rC   r   w  s4   

zRedisSSLContext.__init__r   c                 C   s   | j set }| j|_| j|_| jr| jD ]	}| j|O  _q| jr0| jD ]
}| j| M  _q%| j	r?| j
r?|j| j	| j
d | jsE| jrN|j| j| jd | jd urW| j|_| jd urb|| j || _ | j S )N)ri  rh  )cafilecadata)rx  rs  create_default_contextro  rj  verify_moderk  verify_flagsrl  ri  rh  load_cert_chainrm  rn  load_verify_locationsrp  minimum_versionrq  set_ciphers)rL   rx  flagrB   rB   rC   r     s(   



zRedisSSLContext.get)
NNNNNNNFNN)r=   r>   r?   r8  r
   r   r   rs  rw  r   r9  r   r   r   r   rB   rB   rB   rC   rr  h  sD    

	

+rr  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 rE  )r  rF  r   )rL   r  r	  rG  rB   rC   r     s   z#UnixDomainSocketConnection.__init__r   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )Nr  rS   rU   )r  rS   rU   r{   rH  rB   rB   rC   r     s   z&UnixDomainSocketConnection.repr_piecesc              	      sv   t | j4 I d H  tj| jdI d H \}}W d   I d H  n1 I d H s'w   Y  || _|| _|  I d H  d S )Nr  )r   r[   r}   open_unix_connectionr  re   rf   r   )rL   rU  rV  rB   rB   rC   r     s   (z#UnixDomainSocketConnection._connectc                 C   r   rJ   r  r   rB   rB   rC   r     r   z&UnixDomainSocketConnection._host_error)r=   r>   r?   r7  r   r   r   r   r   r   r   r   r   rY  rB   rB   rG  rC   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_STRINGSr9  )valuerB   rB   rC   to_bool  s
   r  c                 C   s\   |  dd dd}g }|dD ]}| }tt|s#td| |tt| q|S )N[r  ]r   zInvalid ssl verify flag: )replacer  striphasattrr   r   r{   r   )r  verify_flags_strr  r  rB   rB   rC   parse_ssl_verify_flags  s   
r  )rS   rZ   r[   rB  r]   max_connectionsr_   rd  r_  ra  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 )	ConnectKwargsrT   rY   connection_classr@  rA  rS   r  N)r=   r>   r?   r   __annotations__r   rH   r   rB   rB   rB   rC   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.rT   rY   unixr  r  )redisredissr@  rA  rS   /r  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrS  r   r   r  r   r   r   rT   rY   schemer  r  hostnamerA  r   r  AttributeErrorrZ  )r  parsedr	  name
value_listr  r   valid_schemesrB   rB   rC   	parse_url  sR   




r  _CPConnectionPool)boundc                   @   s  e Zd ZdZedee dedefddZe	dfdee
 d	ee fd
dZdd Zdd ZdefddZedgdddd5ddZdd Zdd Zdd Zde
fdd Zde
fd!d"Zd6d$efd%d&Zd'd( Zd7d)d*Zd8d-d.Zd/efd0d1Zd2efd3d4Z dS )9r  a  
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.ConnectionError` when the pool's
    limit is reached.

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

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

        For example::

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

        Three URL schemes are supported:

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

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

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

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

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

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

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

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        NrB   )r  update)r  r  r	  url_optionsrB   rB   rC   from_urlL  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 integerru   rv   )r   r   r   r  connection_kwargsr  _available_connectionsset_in_use_connectionsr   r4   ru   r}   Lockrj   ry   r   )rL   r  r  r  rB   rB   rC   r   {  s   

zConnectionPool.__init__c                 C   sN   d dd | j D }d| jj d| jj d| jj d| jj d| dS )	Nr   c                 S   s   g | ]\}}| d | qS )r   rB   r   rB   rB   rC   r     s    z+ConnectionPool.__repr__.<locals>.<listcomp>r   r   z(<r   z)>)>)r   r  rS  r   r>   r=   r  )rL   conn_kwargsrB   rB   rC   r     s   zConnectionPool.__repr__c                 C   s   g | _ t | _d S rJ   )r  r   WeakSetr  r   rB   rB   rC   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   rB   rB   rC   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 rJ   )rj   get_available_connectionensure_connectionr  release)rL   command_namekeysoptionsrG   rB   rB   rC   get_connection  s   		zConnectionPool.get_connectionc                 C   sT   z| j  }W n ty!   t| j| jkrtdd|  }Y nw | j| |S )zCGet a connection from the pool, without making sure it is connectedzToo many connectionsN)	r  pop
IndexErrorr   r  r  r*   make_connectionaddrK   rB   rB   rC   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 settingsro   rm   rp   rn   rq   F)ro   rp   rq   )r  ru   r   rt  rB   rB   rC   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.NrB   )r  r  r   rB   rB   rC   r    s   zConnectionPool.make_connectionrG   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   rK   rB   rB   rC   r    s   

z ConnectionPool.ensure_connectionc                    sJ   | j | | r| I dH  | j| | jt|I dH  dS )z(Releases the connection back to the poolN)	r  r   r   r   r  r{   ry   dispatch_asyncr   rK   rB   rB   rC   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 rJ   r   )r   rG   rB   rB   rC   r     r   z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTNc                 s   s    | ]
}t |tr|V  qd S rJ   )r   r  )r   rrB   rB   rC   r     s    )r   r  r  r}   gathernext)rL   r  connectionsrespr   rB   rB   rC   r     s   zConnectionPool.disconnectc              	      sV   | j 4 I dH  | jD ]}|  qW d  I dH  dS 1 I dH s$w   Y  dS )z<
        Mark all active connections for reconnect.
        N)rj   r  r   )rL   connrB   rB   rC   'update_active_connections_for_reconnect   s   

.z6ConnectionPool.update_active_connections_for_reconnectc                    r   )z-Close the pool, disconnecting all connectionsNr   r   rB   rB   rC   aclose  r   zConnectionPool.aclosert   r#   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rJ   )r  rt   r  )rL   rt   r  rB   rB   rC   	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 r0  )r   r2  r3  rB   )r  r-  rB   rC   r     s    z1ConnectionPool.re_auth_callback.<locals>.<lambda>c                    
     | S rJ   _mockr   r   rB   rC   r        
 c                      r   rJ   )r   rB   )r  rB   rC   r     r   c                    r  rJ   r  r   r   rB   rC   r     r  )rj   r  rt   r   r  r/  r.  rB   )r  rL   r-  rC   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:
        NrB   r   rB   rB   rC   r  !  s   zConnectionPool._mockrJ   r6  r5  )rt   r#   r   N)!r=   r>   r?   r7  classmethodr   r  r   r  r>  rH   r
   r   r   r   r  r9  r  r   r  r  r  r  r  r  r   r  r  r  r   r  r,   r  rB   rB   rB   rC   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  rB   )rF  r   r}   	Condition
_conditionr"   )rL   r  r"   r  r  r  rG  rB   rC   r   L  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  rF  r  r}   r.   r*   r  r  r  )rL   r  r  r  rG   errrG  rB   rC   r  \  s(   *(
z%BlockingConnectionPool.get_connectionrG   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  rF  r  notifyrK   rG  rB   rC   r  s  s
   .zBlockingConnectionPool.releaserJ   )r=   r>   r?   r7  r>  r}   	LifoQueuer   r
   r  r   rH   Queuer   r   r  r  rY  rB   rB   rG  rC   r  *  s,    #r  )or}   r~   enumr   r|   sysr<  r   abcr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   urllib.parser   r   r   r   utilsr   rs  r   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.utilsr0   r1   r2   _parsersr3   r4   r5   r6   r7   r  r  r  SYM_LFr  Enumr<   rA   rz   r  rD   rF   rQ   r;  rH   r>  rZ  rr  r  r  r9  r  r  r   r  r  r   r@   r  r  r  r  r  rB   rB   rB   rC   <module>   s   
 <
$	    y9OQ
5 n