o
    Š¨ÊhN¯  ã                   @   sì  U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZm Z m!Z! ddl"m#Z# ej$d	krsd 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, d dl-m.Z.m/Z/ d dl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@mAZAmBZBmCZC dZDdZEdZFdZGdZHG dd„ dejIƒZJeJjKZLeeeBeCeAf  eMd< e;réeAZNneBZNG dd„ deƒZOG dd„ deƒZPeeOePf ZQG dd „ d ƒZRG d!d"„ d"eRƒZSG d#d$„ d$eSƒZTG d%d&„ d&ƒZUG d'd(„ d(eRƒZVd)ZWd*eeX fd+d,„ZYeeZe[e[eYeYeZeZeYe[d-œ	ƒZ\ee]ed.e^f f eMd/< G d0d1„ d1ed2d3�Z_d4e]d*e_fd5d6„Z`ed7d8d9�ZaG d:d8„ d8ƒZbG d;d<„ d<ebƒZcdS )=é    N)Úabstractmethod)Úchain)ÚMappingProxyType)ÚAnyÚCallableÚIterableÚListÚMappingÚOptionalÚProtocolÚSetÚTupleÚTypeÚ	TypedDictÚTypeVarÚUnion)ÚParseResultÚparse_qsÚunquoteÚurlparseé   )Úformat_error_message)é   é   r   )Útimeout)ÚRetry)Ú	NoBackoff)ÚDEFAULT_RESP_VERSION)ÚCredentialProviderÚ"UsernamePasswordCredentialProvider)ÚAuthenticationErrorÚ$AuthenticationWrongNumberOfArgsErrorÚConnectionErrorÚ	DataErrorÚ
RedisErrorÚResponseErrorÚTimeoutError)Ú
EncodableT)ÚHIREDIS_AVAILABLEÚget_lib_versionÚstr_if_bytes)Ú
BaseParserÚEncoderÚ_AsyncHiredisParserÚ_AsyncRESP2ParserÚ_AsyncRESP3Parseró   *ó   $s   
ó   
ó    c                   @   s   e Zd Zeƒ ZdS )Ú	_SentinelN)Ú__name__Ú
__module__Ú__qualname__ÚobjectÚsentinel© r:   r:   úJ/var/www/html/env/lib/python3.10/site-packages/redis/asyncio/connection.pyr4   F   s    
r4   ÚDefaultParserc                   @   ó   e Zd Zddd„ZdS )ÚConnectCallbackProtocolÚ
connectionÚAbstractConnectionc                 C   ó   d S ©Nr:   ©Úselfr?   r:   r:   r;   Ú__call__U   s    z ConnectCallbackProtocol.__call__N©r?   r@   ©r5   r6   r7   rE   r:   r:   r:   r;   r>   T   ó    r>   c                   @   r=   )ÚAsyncConnectCallbackProtocolr?   r@   c                 Ã   ó   �d S rB   r:   rC   r:   r:   r;   rE   Y   s   € z%AsyncConnectCallbackProtocol.__call__NrF   rG   r:   r:   r:   r;   rI   X   rH   rI   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efd#efd$d%„Zd&d'„ Zd(d)„ Zed*d+„ ƒZed,d-„ ƒZd.d/„ Z d0d1„ Z!dee d2dfd3d4„Z"d5d6„ Z#ed7d8„ ƒZ$ed2e
fd9d:„ƒZ%d;e&d2e
fd<d=„Z'dfd>d?„Z(dgd@ed2dfdAdB„Z)dCdD„ Z*dEdF„ Z+dGdH„ Z,dIe-e. d2dfdJdK„Z/	LdhdIe	e.e
e-e. f dMed2dfdNdO„Z0dPedQed2dfdRdS„Z1dTdU„ Z2		didLddVœdWedXee dYedZee fd[d\„Z3dPe4d2e5e. fd]d^„Z6d_e-e-e4  d2e5e. fd`da„Z7dbdc„ Z8ddde„ Z9dS )jr@   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   )rK   rQ   rR   rS   rU   rV   ÚencodingÚencoding_errorsÚdecode_responsesÚparser_classÚsocket_read_sizerW   rM   rN   rO   rL   ÚretryrT   Úencoder_classrP   r\   rK   rQ   rR   rS   rU   rV   rg   rh   ri   rj   rk   rW   rM   rN   rO   rL   rl   rT   rm   rP   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r¼t&d	ƒ‚|| _'d S |dk sÉ|dkrÍt&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#   rK   rM   rN   rO   rP   rQ   rL   rR   rS   rU   ÚSENTINELÚappendr&   Úsocketr   ÚasynciorV   r   r   rl   ÚcopyÚdeepcopyÚupdate_supported_errorsrW   rX   rZ   rT   r]   r^   rc   Ú
set_parserr`   ra   ÚintÚ	TypeErrorr   Ú
ValueErrorr"   r\   )rD   rK   rQ   rR   rS   rU   rV   rg   rh   ri   rj   rk   rW   rM   rN   rO   rL   rl   rT   rm   rP   r\   Úpr:   r:   r;   Ú__init__   sj   ÿ

ÿ€
þzAbstractConnection.__init__Ú	_warningsc                 C   s2   t | dd ƒr|jd| ›�t| d� |  ¡  d S d S )Nr^   zunclosed Connection )Úsource)ÚgetattrÚwarnÚResourceWarningÚ_close)rD   r}   r:   r:   r;   Ú__del__Ñ   s   ÿüzAbstractConnection.__del__c                 C   s$   | j r| j  ¡  d | _ | _dS dS )zR
        Internal method to silently close the connection without waiting
        N)r^   Úcloser]   ©rD   r:   r:   r;   r‚   Û   s   
þzAbstractConnection._closec                 C   s8   d  dd„ |  ¡ D ƒ¡}d| jj› d| jj› d|› d�S )Nú,c                 s   s"   � | ]\}}|› d |› �V  qdS )ú=Nr:   )Ú.0ÚkÚvr:   r:   r;   Ú	<genexpr>ä   s   €  z.AbstractConnection.__repr__.<locals>.<genexpr>ú<Ú.ú(ú)>)ÚjoinÚrepr_piecesÚ	__class__r6   r5   )rD   Ú	repr_argsr:   r:   r;   Ú__repr__ã   s    zAbstractConnection.__repr__c                 C   rA   rB   r:   r…   r:   r:   r;   r‘   ç   ó   zAbstractConnection.repr_piecesc                 C   s   | j d uo	| jd uS rB   )r]   r^   r…   r:   r:   r;   Úis_connectedë   s   zAbstractConnection.is_connectedc                 C   s(   t  |¡}|| jvr| j |¡ dS dS )a^  
        Register a callback to be called when the connection is established either
        initially or reconnected.  This allows listeners to issue commands that
        are ephemeral to the connection, for example pub/sub subscription or
        key tracking.  The callback must be a _method_ and will be kept as
        a weak reference.
        N)ÚweakrefÚ
WeakMethodr`   rq   )rD   ÚcallbackÚwmr:   r:   r;   Úregister_connect_callbackï   s   

ÿz,AbstractConnection.register_connect_callbackc                 C   s.   z| j  t |¡¡ W dS  ty   Y dS w )z÷
        De-register a previously registered callback.  It will no-longer receive
        notifications on connection events.  Calling this is not required when the
        listener goes away, since the callbacks are kept as weak methods.
        N)r`   Úremover—   r˜   rz   )rD   r™   r:   r:   r;   Úderegister_connect_callbackû   s
   ÿz.AbstractConnection.deregister_connect_callbackÚreturnc                 C   s   || j d�| _dS )zË
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rk   N)rc   r_   )rD   rj   r:   r:   r;   rw     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 ]}|ƒ }|ˆ ƒ}|r¥t |¡r¥|I dH  q�dS )z5Connects to the Redis server if not already connectedNc                      ó   ˆ   ¡ S rB   )Ú_connectr:   r…   r:   r;   Ú<lambda>  ó    z,AbstractConnection.connect.<locals>.<lambda>c                    rŸ   rB   ©Ú
disconnect)Úerrorr…   r:   r;   r¡     r¢   zTimeout connecting to serverc                 S   s   g | ]}|ƒ r|‘qS r:   r:   )rˆ   Úrefr:   r:   r;   Ú
<listcomp>2  s    z.AbstractConnection.connect.<locals>.<listcomp>)r–   rl   Úcall_with_retryrs   ÚCancelledErrorrr   r   r&   ÚOSErrorr"   Ú_error_messageÚ	ExceptionrT   Ú
on_connectÚiscoroutinefunctionr$   r¤   r`   ÚinspectÚisawaitable)rD   ÚeÚexcr¦   r™   Útaskr:   r…   r;   Úconnect  sJ   €ÿ€
€ÿ
ÿ€ý

€üzAbstractConnection.connectc                 Ã   rJ   rB   r:   r…   r:   r:   r;   r    9  s   €zAbstractConnection._connectc                 C   rA   rB   r:   r…   r:   r:   r;   Ú_host_error=  r•   zAbstractConnection._host_errorÚ	exceptionc                 C   s   t |  ¡ |ƒS rB   )r   rµ   )rD   r¶   r:   r:   r;   r«   A  ó   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r½tdƒ‚n,| jdvrêt| 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   Ú2rn   Údefaultr   ÚHELLOÚAUTHs   protoÚprotozInvalid RESP versionÚcheck_healthFro   ©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 rB   r:   )rˆ   Úsentr:   r:   r;   r‹   ‘  ó   € z0AbstractConnection.on_connect.<locals>.<genexpr>zInvalid Database)r_   r­   rP   rL   rQ   r   Úget_credentialsr\   Ú
isinstancer.   rw   r/   ÚEXCEPTION_CLASSESÚlenÚsend_commandÚread_responseÚgetrx   r"   r!   r*   r    rM   rN   rO   rK   r%   )rD   ÚparserÚ	auth_argsÚcred_providerÚresponseÚauth_responseÚ_r:   r:   r;   r­   D  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_timeoutrS   r_   Úon_disconnectr–   r^   r„   Úwait_closedrª   r]   rs   r&   )rD   rÓ   r:   r:   r;   r¤   ›  s8   €
ý
€ÿ€ÿ
2ò
ÿþÿzAbstractConnection.disconnectc                 Ã   s8   �| j ddd�I dH  t|  ¡ I dH ƒdkrtdƒ‚dS )z Send PING, expect PONG in returnÚPINGFr¾   NÚPONGz#Bad response from PING health check)rÊ   r*   rË   r"   r…   r:   r:   r;   Ú
_send_ping²  s
   €ÿzAbstractConnection._send_pingc                 Ã   ó   �|   ¡ I dH  dS )z Function to call when PING failsNr£   )rD   r¥   r:   r:   r;   Ú_ping_failed¸  ó   €zAbstractConnection._ping_failedc                 Ã   s>   �| j rt ¡  ¡ | jkr| j | j| j¡I dH  dS dS dS )z3Check the health of the connection with a PING/PONGN)	rW   rs   Úget_running_loopÚtimerX   rl   r¨   rÙ   rÛ   r…   r:   r:   r;   r½   ¼  s   €ÿüzAbstractConnection.check_healthÚcommandc                 Ã   s"   �| j  |¡ | j  ¡ I d H  d S rB   )r^   Ú
writelinesÚdrain)rD   rß   r:   r:   r;   Ú_send_packed_commandÄ  s   €z'AbstractConnection._send_packed_commandTr½   c              
   Ã   sV  �| j s|  ¡ I d H  n	|r|  ¡ I d H  z5t|tƒr| ¡ }t|tƒr'|g}| jr:t 	|  
|¡| j¡I d H  W d S | j |¡ | j ¡ I d H  W d S  tjy`   | jdd�I d H  tdƒd ‚ tyš } z/| jdd�I d H  t|jƒdkr€d|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 socketrn   ÚUNKNOWNr   zError z while writing to socket. r�   )r–   r´   r½   rÇ   ÚstrÚencodeÚbytesrR   rs   Úwait_forrâ   r^   rà   rá   r&   r¤   rª   rÉ   Úargsr"   ÚBaseException)rD   rß   r½   r±   Úerr_noÚerrmsgr:   r:   r;   Úsend_packed_commandÈ  sF   €

ÿ


ÿþ€úz&AbstractConnection.send_packed_commandré   Úkwargsc                 Ï   s(   �| j | j|Ž | dd¡d�I dH  dS )z+Pack and send a command to the Redis serverr½   Tr¾   N)rí   Úpack_commandrÌ   )rD   ré   rî   r:   r:   r;   rÊ   ñ  s   €ÿzAbstractConnection.send_commandc              
   Ã   s^   �z	| j  ¡ I dH W S  ty. } z| jdd�I dH  |  ¡ }td|› d|j› �ƒ‚d}~ww )z8Poll the socket to see if there's data that can be read.NTrã   úError while reading from z: )r_   Úcan_read_destructiverª   r¤   rµ   r"   ré   )rD   r±   Ú
host_errorr:   r:   r;   rñ   ÷  s   €€ýz'AbstractConnection.can_read_destructive)Údisconnect_on_errorÚpush_requestÚdisable_decodingr   ró   rô   c          
   
   Ã   sú  �|dur|n| j }|  ¡ }z�|durD| jdv rDtsDt|ƒ4 I dH š | jj||d�I dH }W d  ƒI dH  n1 I dH s>w   Y  nJ|durqt|ƒ4 I dH š | jj|d�I dH }W d  ƒI dH  n1 I dH skw   Y  n| jdv r„ts„| jj||d�I dH }n
| jj|d�I dH }W nT tjy°   |duržY 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rót ¡  ¡ | 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 : )rR   rµ   r\   r(   rÔ   r_   rË   rs   r&   r¤   rª   r"   ré   rê   rW   rÝ   rÞ   rX   rÇ   r%   )
rD   rõ   r   ró   rô   Úread_timeoutrò   rÐ   r±   Ú	next_timer:   r:   r;   rË      sf   €	
ÿÿ(ÿ€ÿ(ÿ€ÿÿ€€ú
z AbstractConnection.read_responsec              	   G   s*  g }t |d tƒrJ ‚t |d tƒr#t|d  ¡  ¡ ƒ|dd…  }nd|d v r7t|d  ¡ ƒ|dd…  }t ttt	|ƒƒ ¡ t
f¡}| j}t| jj|ƒD ]>}t	|ƒ}t	|ƒ|ksd||ksdt |tƒr~t |tt|ƒ ¡ t
f¡}| |¡ | |¡ t
}qOt |tt|ƒ ¡ t
|t
f¡}qO| |¡ |S )z2Pack a series of arguments into the Redis protocolr   rn   Nó    )rÇ   Úfloatrå   Útupleræ   ÚsplitÚ	SYM_EMPTYr�   ÚSYM_STARrÉ   ÚSYM_CRLFra   ÚmaprZ   Ú
memoryviewÚ
SYM_DOLLARrq   )rD   ré   ÚoutputÚbuffÚbuffer_cutoffÚargÚ
arg_lengthr:   r:   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   )ra   rï   rÉ   rÇ   r  rq   rý   r�   )	rD   r  r  ÚpiecesÚbuffer_lengthr  ÚcmdÚchunkÚchunklenr:   r:   r;   Úpack_commandsl  s.   ÿ

ðz AbstractConnection.pack_commandsc                 C   s   t | jjƒdkS )zCheck if the socket is emptyr   )rÉ   r]   Ú_bufferr…   r:   r:   r;   Ú_socket_is_emptyŠ  s   z#AbstractConnection._socket_is_emptyc                 Ã   s,   �|   ¡ s| jdd�I d H  |   ¡ rd S d S )NT)rô   )r  rË   r…   r:   r:   r;   Úprocess_invalidation_messagesŽ  s   €ÿz0AbstractConnection.process_invalidation_messages©rž   N)F©T)FN):r5   r6   r7   Ú__doc__Ú	__slots__rp   r<   r)   r,   r   rå   rx   r
   rú   ÚboolÚlistr4   r   r+   r   ÚConnectCallbackTr   r|   Úwarningsr   rƒ   r‚   r”   r   r‘   Úpropertyr–   r›   r�   rw   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@   _   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‡  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 ©Nr:   )r  rx   r  r  r   r!  Úsuperr|   )rD   r  r  r  r   r!  rî   ©r’   r:   r;   r|   –  s   


zConnection.__init__c                 C   s6   d| j fd| jfd| jfg}| jr| d| jf¡ |S )Nr  r  rK   rM   )r  r  rK   rM   rq   ©rD   r	  r:   r:   r;   r‘   §  s   zConnection.repr_piecesrž   c                 C   s   | j | jdœS )N©r  r  r&  r…   r:   r:   r;   Ú_connection_arguments­  r·   z Connection._connection_argumentsc              	   Ã   sö   �t | jƒ4 I dH š tjdi |  ¡ ¤ŽI dH \}}W d  ƒI dH  n1 I dH s*w   Y  || _|| _|j d¡}|ry| 	t
jt
jd¡ z$| jre| 	t
jt
jd¡ | j ¡ D ]\}}| 	t
j||¡ qXW dS W dS  ttfyx   | ¡  ‚ w dS )zCreate a TCP socket connectionNrr   rn   r:   )rÔ   rS   rs   Úopen_connectionr'  r]   r^   Ú	transportÚget_extra_infoÚ
setsockoptrr   ÚIPPROTO_TCPÚTCP_NODELAYr  Ú
SOL_SOCKETÚSO_KEEPALIVEr   ÚitemsÚSOL_TCPrª   ry   r„   )rD   ÚreaderÚwriterÚsockr‰   rŠ   r:   r:   r;   r    °  s.   €ÿ(ÿýü÷zConnection._connectc                 C   s   | j › d| j› �S )Nú:r&  r…   r:   r:   r;   rµ   È  s   zConnection._host_error)r5   r6   r7   r  rå   r   rx   r  r
   r	   rç   r|   r‘   r'  r    rµ   Ú__classcell__r:   r:   r$  r;   r  “  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deej dee f‡ fdd„Z	de
f‡ fdd„Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZ‡  ZS )!ÚSSLConnectionzåManages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    NÚrequiredFÚssl_keyfileÚssl_certfileÚssl_cert_reqsÚssl_ca_certsÚssl_ca_dataÚssl_check_hostnameÚssl_min_versionÚssl_ciphersc	           
   
      s0   t ||||||||d�| _tƒ jdi |	¤Ž d S )N)ÚkeyfileÚcertfileÚ	cert_reqsÚca_certsÚca_dataÚcheck_hostnameÚmin_versionÚciphersr:   )ÚRedisSSLContextr[   r#  r|   )
rD   r9  r:  r;  r<  r=  r>  r?  r@  rî   r$  r:   r;   r|   Ò  s   ø
zSSLConnection.__init__rž   c                    s   t ƒ  ¡ }| j ¡ |d< |S )NÚssl)r#  r'  r[   rÌ   ©rD   rî   r$  r:   r;   r'  ê  s   
z#SSLConnection._connection_argumentsc                 C   ó   | j jS rB   )r[   rA  r…   r:   r:   r;   rA  ï  ó   zSSLConnection.keyfilec                 C   rL  rB   )r[   rB  r…   r:   r:   r;   rB  ó  rM  zSSLConnection.certfilec                 C   rL  rB   )r[   rC  r…   r:   r:   r;   rC  ÷  rM  zSSLConnection.cert_reqsc                 C   rL  rB   )r[   rD  r…   r:   r:   r;   rD  û  rM  zSSLConnection.ca_certsc                 C   rL  rB   )r[   rE  r…   r:   r:   r;   rE  ÿ  rM  zSSLConnection.ca_datac                 C   rL  rB   )r[   rF  r…   r:   r:   r;   rF    rM  zSSLConnection.check_hostnamec                 C   rL  rB   )r[   rG  r…   r:   r:   r;   rG    rM  zSSLConnection.min_version)NNr8  NNFNN)r5   r6   r7   r  r
   rå   r  rJ  Ú
TLSVersionr|   r	   r'  r  rA  rB  rC  rD  rE  rF  rG  r6  r:   r:   r$  r;   r7  Ì  sT    ÷þýüûúùø	÷





r7  c                   @   sz   e Zd ZdZ								ddee dee dee dee dee d	ed
eej dee fdd„Z	dej
fdd„ZdS )rI  )	rA  rB  rC  rD  rE  ÚcontextrF  rG  rH  NFrA  rB  rC  rD  rE  rF  rG  rH  c	           
      C   s‚   || _ || _|d u rtj| _nt|tƒr-tjtjtjdœ}	||	vr(t	d|› �ƒ‚|	| | _|| _
|| _|| _|| _|| _d | _d S )N)ÚnoneÚoptionalr8  z+Invalid SSL Certificate Requirements Flag: )rA  rB  rJ  Ú	CERT_NONErC  rÇ   rå   ÚCERT_OPTIONALÚCERT_REQUIREDr$   rD  rE  rF  rG  rH  rO  )
rD   rA  rB  rC  rD  rE  rF  rG  rH  Ú	CERT_REQSr:   r:   r;   r|     s(   

ýÿ

zRedisSSLContext.__init__rž   c                 C   sŽ   | j sDt ¡ }| j|_| j|_| jr| jr|j| j| jd� | j	s$| j
r-|j| j	| j
d� | jd ur6| j|_| jd urA| | j¡ || _ | j S )N)rB  rA  )ÚcafileÚcadata)rO  rJ  Úcreate_default_contextrF  rC  Úverify_moderB  rA  Úload_cert_chainrD  rE  Úload_verify_locationsrG  Úminimum_versionrH  Úset_ciphers)rD   rO  r:   r:   r;   rÌ   :  s   

zRedisSSLContext.get)NNNNNFNN)r5   r6   r7   r  r
   rå   r  rJ  rN  r|   Ú
SSLContextrÌ   r:   r:   r:   r;   rI    s8    ÷þýüûúùø	
÷!rI  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Ú ©Úpathrb  c                   s   || _ tƒ jdi |¤Ž d S r"  )rb  r#  r|   )rD   rb  rî   r$  r:   r;   r|   N  s   z#UnixDomainSocketConnection.__init__rž   c                 C   s.   d| j fd| jfg}| jr| d| jf¡ |S )Nrb  rK   rM   )rb  rK   rM   rq   r%  r:   r:   r;   r‘   R  s   z&UnixDomainSocketConnection.repr_piecesc              	   Ã   sv   �t | jƒ4 I d H š tj| jd�I d H \}}W d   ƒI d H  n1 I d H s'w   Y  || _|| _|  ¡ I d H  d S )Nra  )rÔ   rS   rs   Úopen_unix_connectionrb  r]   r^   r­   )rD   r2  r3  r:   r:   r;   r    X  s   €(ÿz#UnixDomainSocketConnection._connectc                 C   s   | j S rB   ra  r…   r:   r:   r;   rµ   _  s   z&UnixDomainSocketConnection._host_error)r5   r6   r7   r  rå   r|   r   r   r   rx   r‘   r    rµ   r6  r:   r:   r$  r;   r_  K  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_STRINGSr  )Úvaluer:   r:   r;   Úto_boolf  s
   rl  )	rK   rR   rS   r  rU   Úmax_connectionsrW   r>  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 )	ÚConnectKwargsrL   rQ   Úconnection_classr  r  rK   rb  N)r5   r6   r7   rå   Ú__annotations__r   r@   rx   r:   r:   r:   r;   ro  }  s   
 ro  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r‡t|jƒ|d< |jr©d|vr©ztt|jƒ dd¡ƒ|d< W n tt	fy¨   Y nw |jdkr²t|d< |S d}t	d|› d�ƒ‚)Nr   zInvalid value for 'z' in connection URL.rL   rQ   Úunixrb  rp  )ÚredisÚredissr  r  rK   ú/r`  rv  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes (ú))r   r   Úqueryr0  rÉ   r   rn  rÌ   ry   rz   rL   rQ   Úschemerb  r_  Úhostnamer  rx   ÚreplaceÚAttributeErrorr7  )rs  Úparsedrî   ÚnameÚ
value_listrk  rÍ   Úvalid_schemesr:   r:   r;   Ú	parse_url‡  sR   
ÿ€

êÿ
û
ÿr‚  Ú_CPÚConnectionPool)Úboundc                   @   sÌ   e Zd ZdZedee dedefdd„ƒZe	dfdee
 d	ee fd
d„Zdd„ Zdd„ Zdefdd„Z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 ),r„  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``.
    Úclsrs  rž   c                 K   s    t |ƒ}| |¡ | di |¤ŽS )a  
        Return a connection pool configured from the given URL.

        For example::

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

        Three URL schemes are supported:

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

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

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

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

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

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

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

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        Nr:   )r‚  Úupdate)r†  rs  rî   Úurl_optionsr:   r:   r;   Úfrom_urlÌ  s   +
zConnectionPool.from_urlNrp  rm  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 integerrm   )rÇ   rx   rz   rp  Úconnection_kwargsrm  Ú_available_connectionsÚsetÚ_in_use_connectionsrÌ   r,   rm   )rD   rp  rm  rŠ  r:   r:   r;   r|   û  s   zConnectionPool.__init__c              	   C   s.   d| j j› d| j j› d| jdi | j¤Ž›d�S )NrŒ   r�   rŽ   r�   r:   )r’   r6   r5   rp  rŠ  r…   r:   r:   r;   r”     s   ÿÿzConnectionPool.__repr__c                 C   s   g | _ t ¡ | _d S rB   )r‹  r—   ÚWeakSetr�  r…   r:   r:   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.)r‹  rÉ   r�  rm  r…   r:   r:   r;   Úcan_get_connection  s   þz!ConnectionPool.can_get_connectionc                 Ï   sB   �|   ¡ }z|  |¡I dH  W |S  ty    |  |¡I dH  ‚ w )z(Get a connected connection from the poolN)Úget_available_connectionÚensure_connectionrê   Úrelease)rD   Úcommand_nameÚkeysÚoptionsr?   r:   r:   r;   Ú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�  rm  r"   Úmake_connectionÚaddrC   r:   r:   r;   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 settingsrg   re   rh   rf   ri   F)rg   rh   ri   )rŠ  rm   rÌ   rK  r:   r:   r;   Úget_encoder4  s   


ýzConnectionPool.get_encoderc                 C   s   | j di | j¤ŽS )z=Create a new connection.  Can be overridden by child classes.Nr:   )rp  rŠ  r…   r:   r:   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¤   rC   r:   r:   r;   r’  A  s   €
ÿ
ÿýz ConnectionPool.ensure_connectionc                 Ã   s   �| j  |¡ | j |¡ dS )z(Releases the connection back to the poolN)r�  rœ   r‹  rq   rC   r:   r:   r;   r“  Q  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 rB   r£   )rˆ   r?   r:   r:   r;   r‹   g  rÅ   z,ConnectionPool.disconnect.<locals>.<genexpr>Úreturn_exceptionsTNc                 s   s   � | ]
}t |tƒr|V  qd S rB   )rÇ   rê   )rˆ   Úrr:   r:   r;   r‹   j  s   € )r   r‹  r�  rs   ÚgatherÚnext)rD   r�  ÚconnectionsÚrespr²   r:   r:   r;   r¤   X  s   €ÿÿþÿzConnectionPool.disconnectc                 Ã   rÚ   )z-Close the pool, disconnecting all connectionsNr£   r…   r:   r:   r;   Úaclosen  rÜ   zConnectionPool.acloserl   r   c                 C   s(   | j D ]}||_q| jD ]}||_qd S rB   )r‹  rl   r�  )rD   rl   Úconnr:   r:   r;   Ú	set_retryr  s
   

ÿzConnectionPool.set_retryr  r  )rl   r   rž   N)r5   r6   r7   r  Úclassmethodr   rƒ  rå   r‰  r  r@   r
   rx   r|   r”   r�  r  r�  r—  r‘  rœ  rš  r’  r“  r¤   r¤  r¦  r:   r:   r:   r;   r„  ¾  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
    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   é   rm  r   rp  Úqueue_classc                    s,   t ƒ jd||dœ|¤Ž t ¡ | _|| _d S )N)rp  rm  r:   )r#  r|   rs   Ú	ConditionÚ
_conditionr   )rD   rm  r   rp  r«  rŠ  r$  r:   r;   r|   ›  s   þý

zBlockingConnectionPool.__init__c              
   �   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‘  rs   r&   r"   r’  rê   r“  )rD   r”  r•  r–  r?   Úerrr$  r:   r;   r—  «  s(   €*þ(ÿ€
€ÿþ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“  ÚnotifyrC   r$  r:   r;   r“  ½  s
   €.þzBlockingConnectionPool.release)r5   r6   r7   r  r  rs   Ú	LifoQueuerx   r
   r   r@   ÚQueuer|   r—  r“  r6  r:   r:   r$  r;   r¨  y  s"    #ûþýüûr¨  )drs   rt   Úenumr¯   rr   rJ  Úsysr  r—   Úabcr   Ú	itertoolsr   Útypesr   Útypingr   r   r   r   r	   r
   r   r   r   r   r   r   r   Úurllib.parser   r   r   r   Úutilsr   Úversion_infor   rÔ   Úredis.asyncio.retryr   Úredis.backoffr   Úredis.connectionr   Úredis.credentialsr   r   Úredis.exceptionsr    r!   r"   r#   r$   r%   r&   Úredis.typingr'   Úredis.utilsr(   r)   r*   Ú_parsersr+   r,   r-   r.   r/   rþ   r  rÿ   ÚSYM_LFrý   ÚEnumr4   r9   rp   rq  r<   r>   rI   r  r@   r  r7  rI  r_  rj  r  rl  rx   rú   rn  rå   r8   ro  r‚  rƒ  r„  r¨  r:   r:   r:   r;   Ú<module>   sŠ   
 <
$	    89@?÷ÿ
4 <