o
    ݭh                  
   @   s  U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl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 d dlmZmZm Z m!Z! d dl"Z"ddl#m$Z$m%Z% dd	l&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 dd
l6m7Z7 e8ej9ej:dej;dej<diZ=e>e=? Z@zd dlAZAW n eBeCfy   dZDY nw dZDeeAjEZFeFedk re	GdeAjE d dZDdZHdZIdZJdZKdZLdZMG dd dejNZOeOjPZQdZRdZSdZTdZUeeVeWf ZXeeYeZe[f Z\eeXe\f Z]G dd de%ddZ^G d d! d!Z_eeYeee` eeYee` f f f ZaG d"d# d#ZbG d$d% d%ZcG d&d' d'ebZdG d(d) d)ebZeeeedeef  efd*< eDr\eeZgnedZgG d+d, d,e$ZhG d-d. d.e$Zieeheif ZjG d/d0 d0ZkG d1d2 d2ekZlG d3d4 d4ZmG d5d6 d6ekZnd7Zod8eep fd9d:ZqeeZe[e[eqeqeZeZeqd;ZreeYed<esf f efd=< G d>d? d?e%ddZtd@eYd8etfdAdBZuedCdDdEZvG dFdD dDZwG dGdH dHewZxdS )I    N)StrictVersion)chain)MappingProxyType)AnyCallableIterableListMappingOptionalSetTupleTypeTypeVarUnioncast)ParseResultparse_qsunquoteurlparse   )Protocol	TypedDict)AuthenticationError$AuthenticationWrongNumberOfArgsErrorBusyLoadingErrorChildDeadlockedErrorConnectionError	DataErrorExecAbortErrorInvalidResponseModuleErrorNoPermissionErrorNoScriptErrorReadOnlyError
RedisErrorResponseErrorTimeoutError)str_if_bytes   FTz1.0.0z@aioredis supports hiredis @ 1.0.0 or higher. You have hiredis @ z*. Pure-python parser will be used instead.   *   $s   
   
    zConnection closed by server.c                   @   s   e Zd Ze ZdS )	_SentinelN)__name__
__module____qualname__objectsentinel r3   r3   X/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/aioredis/connection.pyr-   V   s    
r-   z:Error loading the extension. Please check the server logs.z5Error unloading module: no such module with that namez/Error unloading module: operation not possible.z[Error unloading module: the module exports one or more module-side data types, can't unloadc                   @   sJ   e Zd ZU eegef ed< eegef ed< ee ed< ee ed< dS )_HiredisReaderArgsprotocolError
replyErrorencodingerrorsN)r.   r/   r0   r   str	Exception__annotations__r
   r3   r3   r3   r4   r5   i   s
   
 r5   )totalc                   @   sP   e Zd ZdZdZdededefddZded	e	fd
dZ
dded	efddZdS )Encoderz=Encode strings to bytes-like and decode bytes-like to stringsr8   encoding_errorsdecode_responsesr8   r@   rA   c                 C   s   || _ || _|| _d S Nr?   )selfr8   r@   rA   r3   r3   r4   __init__u      
zEncoder.__init__valuereturnc                 C   sp   t |ttfr	|S t |trtdt |ttfrt| S t |t	s0|j
j}td|d|| j| jS )z=Return a bytestring or bytes-like representation of the valuezNInvalid input of type: 'bool'. Convert to a bytes, string, int or float first.zInvalid input of type: z1. Convert to a bytes, string, int or float first.)
isinstancebytes
memoryviewboolr   intfloatreprencoder:   	__class__r.   r8   r@   )rC   rF   typenamer3   r3   r4   rO   z   s   


zEncoder.encodeFc                 C   sF   | j s|r!t|tr| | j| jS t|tr!|| j| jS |S )z:Return a unicode string from the bytes-like representation)rA   rH   rJ   tobytesdecoder8   r@   rI   )rC   rF   forcer3   r3   r4   rS      s   


zEncoder.decodeN)F)r.   r/   r0   __doc__	__slots__r:   rK   rD   
EncodableTEncodedTrO   rS   r3   r3   r3   r4   r>   p   s    r>   c                   @   s   e Zd ZU dZdZdededededeee	e
e	ee	ee	i	eeeeeedZeed	< d
efddZdd ZdedefddZdd ZdddZdedefddZde e!ede"e! f fddZ#dS ) 
BaseParserPlain Python parsing class_stream_buffer
_read_sizezmax number of clients reachedz(Client sent AUTH, but no password is setzinvalid passwordz,wrong number of arguments for 'auth' commandz,wrong number of arguments for 'AUTH' command)ERR	EXECABORTLOADINGNOSCRIPTREADONLYNOAUTHNOPERMEXCEPTION_CLASSESsocket_read_sizec                 C   s   d | _ d | _|| _d S rB   r[   rC   rg   r3   r3   r4   rD      rE   zBaseParser.__init__c                 C   s$   z|    W d S  ty   Y d S w rB   )on_disconnectr;   rC   r3   r3   r4   __del__   s
   zBaseParser.__del__responserG   c                 C   sh   | dd }|| jv r0|t|d d }| j| }t|tr*||t}||S |}||S t|S )zParse an error response r   r   N)splitrf   lenrH   dictgetr%   )rC   rl   
error_codeexception_class_or_dictexception_classr3   r3   r4   parse_error   s   


zBaseParser.parse_errorc                 C      t  rB   NotImplementedErrorrj   r3   r3   r4   ri         zBaseParser.on_disconnect
connection
Connectionc                 C   rv   rB   rw   rC   rz   r3   r3   r4   
on_connect   ry   zBaseParser.on_connecttimeoutc                       t  rB   rw   rC   r~   r3   r3   r4   can_read   s   zBaseParser.can_readNc                    r   rB   rw   rj   r3   r3   r4   read_response   s   zBaseParser.read_responserz   r{   )$r.   r/   r0   rU   rV   r   r   r   MODULE_LOAD_ERRORr    MODULE_EXPORTS_DATA_TYPES_ERRORNO_SUCH_MODULE_ERROR MODULE_UNLOAD_NOT_POSSIBLE_ERRORr   r   r"   r#   r!   rf   ExceptionMappingTr<   rL   rD   rk   r:   r%   ru   ri   r}   rM   rK   r   r   rW   r   r   r3   r3   r3   r4   rY      s:   
 
rY   c                	   @   s   e Zd ZdZdejdedee fddZ	e
dd Zd	ed
fdee deed	ef dedefddZdedefddZdedefddZdefddZdd Zdd Zd	S )SocketBufferzAsync-friendly re-impl of redis-py's SocketBuffer.

    TODO: We're currently passing through two buffers,
        the asyncio.StreamReader and this. I imagine we can reduce the layers here
        while maintaining compliance with prior art.
    stream_readerrg   socket_timeoutc                 C   s,   || _ || _|| _t | _d| _d| _d S Nr   )r\   rg   r   ioBytesIOr]   bytes_written
bytes_read)rC   r   rg   r   r3   r3   r4   rD      s   

zSocketBuffer.__init__c                 C   s   | j | j S rB   )r   r   rj   r3   r3   r4   length   s   zSocketBuffer.lengthNTr   r~   raise_on_timeoutrG   c           
   
      sp  | j }|d u s| jd u rtd|| j d}|tur|n| j}zY	 t|4 I d H  | j	| j
I d H }W d   I d H  n1 I d H sHw   Y  t|tr\t|dkr\tt|| t|}|  j|7  _||7 }|d ury||kryq#W dS  tjtjfy   |rtdY dS  ty } zt|jd}	|s|j|	krW Y d }~dS td|j d }~ww )NBuffer is closed.r   TTimeout reading from socketF!Error while reading from socket: )r]   r\   r$   seekr   SENTINELr   async_timeoutr~   readrg   rH   rI   ro   r   SERVER_CLOSED_CONNECTION_ERRORwritesocketasyncior&   NONBLOCKING_EXCEPTIONS#NONBLOCKING_EXCEPTION_ERROR_NUMBERSrq   rP   errnoargs)
rC   r   r~   r   bufmarkerdatadata_lengthexallowedr3   r3   r4   _read_from_socket   s@   (
zSocketBuffer._read_from_socketc                    s    t | jp| j|ddI d H S )NFr~   r   )rK   r   r   r   r3   r3   r4   r   %  s   zSocketBuffer.can_readc                    s   |d }|| j kr| || j  I d H  | jd u rtd| j| j | j|}|  jt|7  _| j| jkr>| 	  |d d S )Nr(   r   )
r   r   r]   r$   r   r   r   ro   r   purge)rC   r   r   r3   r3   r4   r   *  s   

zSocketBuffer.readc                    s   | j }|d u rtd|| j | }|ts1|  I d H  || j | }|tr|  jt|7  _| j| j	krD| 
  |d d S )Nr   r   )r]   r$   r   r   readlineendswithSYM_CRLFr   ro   r   r   )rC   r   r   r3   r3   r4   r   >  s   

zSocketBuffer.readlinec                 C   s8   | j d u r	td| j d | j   d| _d| _d S )Nr   r   )r]   r$   r   truncater   r   rj   r3   r3   r4   r   T  s   


zSocketBuffer.purgec                 C   s:   z|    | j  W n	 ty   Y nw d | _d | _d S rB   )r   r]   closer;   r\   rj   r3   r3   r4   r   ]  s   
zSocketBuffer.close)r.   r/   r0   rU   r   StreamReaderrL   r
   rM   rD   propertyr   r   r   r-   rK   r   r   rI   r   r   r   r   r3   r3   r3   r4   r      s8    


*	r   c                       sh   e Zd ZdZejd Zdef fddZddd	Zd
d Z	de
fddZdeeedf fddZ  ZS )PythonParserrZ   )encoderrg   c                    s   t  | d | _d S rB   )superrD   r   rh   rP   r3   r4   rD   q  s   
zPythonParser.__init__rz   r{   c                 C   s:   |j | _| jdu rtdt| j| j|j| _|j| _dS )zCalled when the stream connectsNr   )_readerr\   r$   r   r^   r   r]   r   r|   r3   r3   r4   r}   u  s   
zPythonParser.on_connectc                 C   s4   | j durd| _ | jdur| j  d| _d| _dS )z"Called when the stream disconnectsN)r\   r]   r   r   rj   r3   r3   r4   ri     s   



zPythonParser.on_disconnectr~   c                    s   | j ot| j |I d H S rB   )r]   rK   r   r   r3   r3   r4   r     s   zPythonParser.can_readrG   Nc                    s2   j r jstt j  I d H }|stt|d d |dd  }}|dvr1td||dkrJ|jddd} |}t|trH||S |dkrOn=|d	krXt	|}n4|d
krpt	|}|dkrfd S  j 
|I d H }n|dkrt	|}|dkr~d S  fddt|D I d H }t|tr j|}|S )Nr   )   -   +   :r*   r)   zProtocol Error: r   utf-8replace)r9   r   r   r*   r   r)   c                    s   g | ]	}   I d H qS rB   )r   ).0_rj   r3   r4   
<listcomp>  s    z.PythonParser.read_response.<locals>.<listcomp>)r]   r   r   r   r   r   rS   ru   rH   rL   r   rangerI   )rC   rawbyterl   errorr   r3   rj   r4   r     s@   



zPythonParser.read_responser   )r.   r/   r0   rU   rY   rV   rL   rD   r}   ri   rM   r   r   rW   r%   r   __classcell__r3   r3   r   r4   r   l  s    

	 r   c                       s   e Zd ZU dZejd Zeed< def fddZ	dd	d
Z
dd ZdefddZedfdeedef defddZdeeee f fddZ  ZS )HiredisParserz*Parser class for connections using Hiredis)_next_responser   _socket_timeoutr   rg   c                    s*   t stdt j|d d | _d | _d S )NzHiredis is not available.rg   )HIREDIS_AVAILABLEr$   r   rD   r   r   rh   r   r3   r4   rD     s
   
zHiredisParser.__init__rz   r{   c                 C   sX   |j | _t| jd}|jjr|jj|d< |jj|d< tj	di || _ d| _
|j| _d S )N)r6   r7   r8   r9   Fr3   )r   r\   r   ru   r   rA   r8   r@   hiredisReaderr   r   r   )rC   rz   kwargsr3   r3   r4   r}     s   zHiredisParser.on_connectc                 C   s   d | _ d | _d| _d S )NF)r\   r   r   rj   r3   r3   r4   ri     rE   zHiredisParser.on_disconnectr~   c                    sH   | j stt| jdu r| j  | _| jdu r"| j|ddI d H S dS )NFr   T)r   r   r   r   getsread_from_socketr   r3   r3   r4   r     s   

zHiredisParser.can_readTNr   c              
      s@  | j d u s| jd u rtd|tu r| jn|}zBt|4 I d H  | j | jI d H }W d   I d H  n1 I d H s=w   Y  t	|t
rMt|dkrRttd | j| W dS  tjyc     tjtjfyw   |rttdd Y dS  ty } zt|jd}|s|j|krW Y d }~dS td|j d }~ww )NzParser already closed.r   Tr   Fr   r   )r\   r   r$   r   r   r   r~   r   r^   rH   rI   ro   r   r   feedr   CancelledErrorr   r&   r   r   rq   rP   r   r   )rC   r~   r   bufferr   r   r3   r3   r4   r     s2   (

zHiredisParser.read_from_socketrG   c                    s   | j r| js|   ttd | jdur| j}d| _|S | j }|du r6|  I d H  | j }|du s&t|tr=|t|t	rO|rOt|d trO|d t
tttt f |S )NFr   )r\   r   ri   r   r   r   r   r   rH   listr   r   rW   r   )rC   rl   r3   r3   r4   r   	  s.   




zHiredisParser.read_responser   )r.   r/   r0   rU   rY   rV   rK   r<   rL   rD   r}   ri   rM   r   r   r   r-   r   rW   r   r   r   r3   r3   r   r4   r     s    
 


""r   DefaultParserc                   @      e Zd ZdddZdS )ConnectCallbackProtocolrz   r{   c                 C   s   d S rB   r3   r|   r3   r3   r4   __call__3  s   z ConnectCallbackProtocol.__call__Nr   r.   r/   r0   r   r3   r3   r3   r4   r   2      r   c                   @   r   )AsyncConnectCallbackProtocolrz   r{   c                    s   d S rB   r3   r|   r3   r3   r4   r   8  s   z%AsyncConnectCallbackProtocol.__call__Nr   r   r3   r3   r3   r4   r   7  r   r   c                (   @   s  e Zd ZdZdZdddddddddddd	ded
dddeddedeee	f deee	f de
e de
e de
e dede
ee	ee	ef f  de	dededededee de	dede
e de
e dee f&dd Zd!d" Zd#d$ Zd%d& Zed'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9ee d:dfd;d<Z 	=dNd9eeeee f d>efd?d@Z!dAdB Z"dOdCefdDdEZ#dFdG Z$dHe%d:e&e fdIdJZ'dKeee%  d:e&e fdLdMZ(dS )Pr{   z4Manages TCP communication to and from a Redis server)pidhostportdbusernameclient_namepasswordr   socket_connect_timeoutsocket_keepalivesocket_keepalive_optionssocket_typeretry_on_timeouthealth_check_intervalnext_health_checklast_active_atr   ssl_contextr   _writer_parser_connect_callbacks_buffer_cutoff_lock__dict__	localhosti  r   NFr   strict   )r   r   r   r   r   r   r   r   r   r   r8   r@   rA   parser_classrg   r   r   r   encoder_classr   r   r   r   r   r   r   r   r   r   r8   r@   rA   r   rg   r   r   r   r   c                C   s   t  | _|| _t|| _|| _|| _|| _|| _	|| _
|p!|p!d | _|| _|p)i | _|	| _|
| _|| _d| _d | _||||| _d | _d | _||d| _g | _d| _t | _d S Nr   r   ip  )osgetpidr   r   rL   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Lockr   )rC   r   r   r   r   r   r   r   r   r   r   r8   r@   rA   r   rg   r   r   r   r   r3   r3   r4   rD   ^  s2   


zConnection.__init__c                 C   s,   d dd |  D }| jj d| dS )N,c                 s   s"    | ]\}}| d | V  qdS )=Nr3   )r   kvr3   r3   r4   	<genexpr>  s     z&Connection.__repr__.<locals>.<genexpr><>)joinrepr_piecesrP   r.   )rC   	repr_argsr3   r3   r4   __repr__  s   zConnection.__repr__c                 C   s6   d| j fd| jfd| jfg}| jr|d| jf |S )Nr   r   r   r   )r   r   r   r   appendrC   piecesr3   r3   r4   r    s   zConnection.repr_piecesc                 C   sZ   z"| j r t }|  }| r|| W d S || W d S W d S  ty,   Y d S w rB   )is_connectedr   get_event_loop
disconnect
is_runningcreate_taskrun_until_completer;   )rC   loopcoror3   r3   r4   rk     s   zConnection.__del__c                 C   s   t | jo| jS rB   )rK   r   r   rj   r3   r3   r4   r    s   zConnection.is_connectedc                 C   s   | j | d S rB   )r   r  )rC   callbackr3   r3   r4   register_connect_callback  s   z$Connection.register_connect_callbackc                 C   s
   g | _ d S rB   )r   rj   r3   r3   r4   clear_connect_callbacks  s   
z"Connection.clear_connect_callbacksc              
      s   | j rdS z	|  I dH  W n9 tjy     tjtjfy&   td ty8 } zt| 	|d}~w t
yH } zt||d}~ww z	|  I dH  W n tya   |  I dH   w | jD ]}|| }|rwt|rw|I dH  qedS )z5Connects to the Redis server if not already connectedNzTimeout connecting to server)r  _connectr   r   r   r~   r&   OSErrorr   _error_messager;   r}   r$   r
  r   inspectisawaitable)rC   eexcr  taskr3   r3   r4   connect  s8   


zConnection.connectc              	      s  t | j4 I dH " tj| j| j| jr| j nddI dH \}}W d  I dH  n1 I dH s3w   Y  || _	|| _
|jd}|dur|tjtjd z$| jrp|tjtjd | j D ]\}}|tj|| qcW dS W dS  ttfy   |   w dS )zCreate a TCP socket connectionN)r   r   sslr   r   )r   r~   r   r   open_connectionr   r   r   rq   r   r   	transportget_extra_info
setsockoptr   IPPROTO_TCPTCP_NODELAYr   
SOL_SOCKETSO_KEEPALIVEr   itemsSOL_TCPr  	TypeErrorr   )rC   readerwritersockr   r   r3   r3   r4   r    s2   (zConnection._connectc              	   C   s^   t |jdkrd| j d| j d|jd  dS d|jd  d| j d| j d|jd  d	S )	Nr   zError connecting to :. r   .Error z connecting to )ro   r   r   r   rC   	exceptionr3   r3   r4   r    s   "zConnection._error_messagec                    s6  | j |  | js| jr^| jr| j| jpdf}n| jpdf}| jdg|R ddiI dH  z	|  I dH }W n tyS   | jd| jddI dH  |  I dH }Y nw t|dkr^td| j	r{| d	d
| j	I dH  t|  I dH dkr{t
d| jr| d| jI dH  t|  I dH dkrt
ddS dS )z=Initialize the connection, authenticate and select a database AUTHcheck_healthFNr3  OKzInvalid Username or PasswordCLIENTSETNAMEzError setting client nameSELECTzInvalid Database)r   r}   r   r   send_commandr   r   r'   r   r   r   r   )rC   	auth_argsauth_responser3   r3   r4   r}     s2   zConnection.on_connectc              	      s   zft | j4 I dH N | j  | js"	 W d  I dH  W dS zt | jkr=| j	
  t| j	dr=| j	 I dH  W n	 tyG   Y nw d| _d| _	W d  I dH  W dS 1 I dH s`w   Y  W dS  tjyx   td| j dw )z!Disconnects from the Redis serverNwait_closedz#Timed out closing connection after )r   r~   r   r   ri   r  r   r   r   r   r   hasattrr<  r  r   r   r&   rj   r3   r3   r4   r
    s4   

2
zConnection.disconnectc                    s   | j rrt  | jkrtz| jdddI dH  t|  I dH dkr'tdW dS  tt	fyq } z:| 
 I dH  z| jdddI dH  t|  I dH dkrUtddW n tye } z||d}~ww W Y d}~dS d}~ww dS dS )z3Check the health of the connection with a PING/PONGPINGFr4  NPONGz#Bad response from PING health check)r   r   r	  timer   r9  r'   r   r   r&   r
  BaseException)rC   errerr2r3   r3   r4   r3  0  s:   zConnection.check_healthcommandrG   c                    s4   | j d u r
td| j | | j  I d H  d S )NzConnection already closed.)r   r$   
writelinesdrain)rC   rD  r3   r3   r4   _send_packed_commandE  s
   
zConnection._send_packed_commandTr3  c              
      s   | j s|  I dH  |r|  I dH  z!t|tr| }t|tr&|g}t| 	|| j
I dH  W dS  tjyI   |  I dH  tdd ty } z-|  I dH  t|jdkrgd|jd }}n
|jd }|jd }td| d| d|d}~w ty   |  I dH   w )	z2Send an already packed command to the Redis serverNzTimeout writing to socketr   UNKNOWNr   r.  z while writing to socket. r-  )r   r  r3  rH   r:   rO   rI   r   wait_forrG  r   r&   r
  r  ro   r   r   rA  )rC   rD  r3  r  err_noerrmsgr3   r3   r4   send_packed_commandL  sB   




zConnection.send_packed_commandc                    s<   | j s|  I dH  | j| j| |dddI dH  dS )z+Pack and send a command to the Redis serverNr3  Tr4  )r  r  rL  pack_commandrq   )rC   r   r   r3   r3   r4   r9  q  s   zConnection.send_commandr~   c                    s(   | j s|  I dH  | j|I dH S )z8Poll the socket to see if there's data that can be read.N)r  r  r   r   r   r3   r3   r4   r   y  s   zConnection.can_readc              
      sV  zG| j 4 I dH 3 t| j4 I dH  | j I dH }W d  I dH  n1 I dH s-w   Y  W d  I dH  n1 I dH sBw   Y  W nK tjyc   |  I dH  td| j	 d| j
  ty } z|  I dH  td| j	 d| j
 d|j d}~w ty   |  I dH   w | jrt  | j | _t|tr|d|S )z0Read the response from a previously sent commandNzTimeout reading from r+  zError while reading from z : )r   r   r~   r   r   r   r   r&   r
  r   r   r  r   r   rA  r   r	  r@  r   rH   r%   )rC   rl   r  r3   r3   r4   r     s6   *(
zConnection.read_responser   c              	   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   r   N    )rH   rM   r:   tuplerO   rn   	SYM_EMPTYr  SYM_STARro   r   r   mapr   rJ   
SYM_DOLLARr  )rC   r   outputbuffbuffer_cutoffarg
arg_lengthr3   r3   r4   rM    sB   "





zConnection.pack_commandcommandsc           	      C   s   g }g }d}| j }|D ]?}| j| D ]7}t|}||ks%||ks%t|tr1|t| d}g }||ks:t|tr@|| q|| ||7 }qq|rU|t| |S )z.Pack multiple commands into the Redis protocolr   )r   rM  ro   rH   rJ   r  rP  r  )	rC   rY  rT  r  buffer_lengthrV  cmdchunkchunklenr3   r3   r4   pack_commands  s0   

zConnection.pack_commandsT)r   ))r.   r/   r0   rU   rV   r   r>   r:   r   rL   r
   rM   rK   r	   rI   r   rY   rD   r  r  rk   r   r  r  r  r  r  r  r}   r
  r3  r   rG  rL  r9  r   r   rW   r   rM  r^  r3   r3   r3   r4   r{   ?  s    

	

1
)

%".r{   c                       s   e Zd Z					ddee dee dedee 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  ZS )SSLConnectionNrequiredFssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_check_hostnamec                    s*   t  jdi | t|||||d| _d S )N)keyfilecertfile	cert_reqsca_certscheck_hostnamer3   )r   rD   RedisSSLContextr   )rC   rb  rc  rd  re  rf  r   r   r3   r4   rD     s   	zSSLConnection.__init__c                 C      | j jS rB   )r   rg  rj   r3   r3   r4   rg       zSSLConnection.keyfilec                 C   rm  rB   )r   rh  rj   r3   r3   r4   rh    rn  zSSLConnection.certfilec                 C   rm  rB   )r   ri  rj   r3   r3   r4   ri    rn  zSSLConnection.cert_reqsc                 C   rm  rB   )r   rj  rj   r3   r3   r4   rj    rn  zSSLConnection.ca_certsc                 C   rm  rB   )r   rk  rj   r3   r3   r4   rk  	  rn  zSSLConnection.check_hostname)NNra  NF)r.   r/   r0   r
   r:   rK   rD   r   rg  rh  ri  rj  rk  r   r3   r3   r   r4   r`    s6    



r`  c                   @   sZ   e Zd ZdZ					d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 )rl  )rg  rh  ri  rj  contextrk  NFrg  rh  ri  rj  rk  c                 C   sp   || _ || _|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optionalra  z+Invalid SSL Certificate Requirements Flag: )rg  rh  r  	CERT_NONEri  rH   r:   CERT_OPTIONALCERT_REQUIREDr$   rj  rk  ro  )rC   rg  rh  ri  rj  rk  	CERT_REQSr3   r3   r4   rD     s"   



zRedisSSLContext.__init__rG   c                 C   sZ   | j s*t }| j|_| j|_| jr| jr|j| j| jd | j	r'|
| j	 || _ | j S )N)rh  rg  )ro  r  create_default_contextrk  ri  verify_moderh  rg  load_cert_chainrj  load_verify_locations)rC   ro  r3   r3   r4   rq   3  s   zRedisSSLContext.get)NNNNF)r.   r/   r0   rV   r
   r:   rK   rD   r  
SSLContextrq   r3   r3   r3   r4   rl    s&    
rl  c                   @   s   e Zd Zddddddddddedddd	d
edeeef dee dee dee dee dedede	de	de
e dedefddZdeeeeeef f  fddZdd Zdd ZdS ) UnixDomainSocketConnectionr1  r   Nr   r   Fr   g        )pathr   r   r   r   r   r8   r@   rA   r   r   rg   r   r   r|  r   r   r   r   r   r8   r@   rA   r   r   rg   r   c                C   s   t  | _|| _|| _|| _|| _|| _|| _|p|pd | _	|
| _
|| _d| _t|||	| _d | _d | _d | _||d| _g | _d| _t | _d S r   )r   r   r   r|  r   r   r   r   r   r   r   r   r   r>   r   _sockr   r   r   r   r   r   r   r   )rC   r|  r   r   r   r   r   r8   r@   rA   r   r   rg   r   r   r3   r3   r4   rD   A  s&   
z#UnixDomainSocketConnection.__init__rG   c                 C   s.   d| j fd| jfg}| jr|d| jf |S )Nr|  r   r   )r|  r   r   r  r  r3   r3   r4   r  g  s   z&UnixDomainSocketConnection.repr_piecesc              	      sx   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 )N)r|  )	r   r~   r   r   open_unix_connectionr|  r   r   r}   )rC   r(  r)  r3   r3   r4   r  p  s   (z#UnixDomainSocketConnection._connectc                 C   sN   t |jdkrd| j d|jd  dS d|jd  d| j d|jd  dS )Nr   z!Error connecting to unix socket: r,  r   r-  r.  z connecting to unix socket: )ro   r   r|  r/  r3   r3   r4   r  w  s   z)UnixDomainSocketConnection._error_message)r.   r/   r0   r   r:   r   rL   r
   rM   rK   r   rY   rD   r   r   r  r  r  r3   r3   r3   r4   r{  @  sZ    
	

"&	r{  )0FFALSENNOrG   c                 C   s6   | d u s| dkr
d S t | tr|  tv rdS t| S )Nr1  F)rH   r:   upperFALSE_STRINGSrK   )rF   r3   r3   r4   to_bool  s
   r  )r   r   r   r   r   max_connectionsr   rf  .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 )	ConnectKwargsr   r   connection_classr   r   r   r|  N)r.   r/   r0   r:   r<   r   r{   rL   r3   r3   r3   r4   r    s   
 r  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.r   r   unixr|  r  )redisredissr   r   r   /r1  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryr%  ro   r   r  rq   r'  
ValueErrorr   r   schemer|  r{  hostnamer   rL   r   AttributeErrorr`  )r  parsedr   name
value_listrF   parservalid_schemesr3   r3   r4   	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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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``.
    clsr  rG   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]:[password]]@/path/to/socket.sock?db=0

        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.
        Nr3   )r  update)r  r  r   url_optionsr3   r3   r4   from_url  s   (
zConnectionPool.from_urlNr  r  c                 K   sp   |pd}t |tr|dk rtd|| _|| _|| _t | _t	 | _
|  |  |  |   | jdt| _d S )Nl        r   z,"max_connections" must be a positive integerr   )rH   rL   r  r  connection_kwargsr  	threadingr   
_fork_lockr   r   resetrq   r>   r   )rC   r  r  r  r3   r3   r4   rD     s   


zConnectionPool.__init__c                 C   s"   | j j d| jdi | jdS )Nr   r   r3   )rP   r.   r  r  rj   r3   r3   r4   r  6  s   
zConnectionPool.__repr__c                 C   s,   t  | _d| _g | _t | _t | _	d S r   )
r   r   r   _created_connections_available_connectionsset_in_use_connectionsr   r   r   rj   r3   r3   r4   r  <  s
   
zConnectionPool.resetc                 C   sl   | j t kr4| jjdd}|stz| j t kr&|   W | j  d S W | j  d S | j  w d S )N   )r~   )r   r   r   r  acquirer   r  release)rC   acquiredr3   r3   r4   	_checkpidM  s   #
zConnectionPool._checkpidc              	      s  |    | j4 I dH & z| j }W n ty!   |  }Y nw | j| W d  I dH  n1 I dH s8w   Y  z=| I dH  z|	 I dH rRt
ddW W |S  t
yz   | I dH  | I dH  |	 I dH rvt
ddY W |S w  ty   | |I dH   w )zGet a connection from the poolNConnection has dataConnection not ready)r  r   r  pop
IndexErrormake_connectionr  addr  r   r   r
  rA  r  rC   command_namekeysoptionsrz   r3   r3   r4   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 settingsr8   r   r@   r   rA   Fr?   )r  r   rq   )rC   r   r3   r3   r4   get_encoder  s   


zConnectionPool.get_encoderc                 C   s4   | j | jkr
td|  j d7  _ | jdi | jS )zCreate a new connectionzToo many connectionsr   Nr3   )r  r  r   r  r  rj   r3   r3   r4   r    s   zConnectionPool.make_connectionrz   c              	      s   |    | j4 I dH D z| j| W n	 ty   Y nw | |r+| j| n|  jd8  _|	 I dH  	 W d  I dH  dS W d  I dH  dS 1 I dH sVw   Y  dS )z(Releases the connection back to the poolNr   )
r  r   r  removeKeyErrorowns_connectionr  r  r  r
  r|   r3   r3   r4   r    s    
	.zConnectionPool.releasec                 C   s   |j | j kS rB   )r   r|   r3   r3   r4   r    s   zConnectionPool.owns_connectionTinuse_connectionsc              	      s   |    | j4 I dH 7 |rt| j| j}n| j}tjdd |D ddiI dH }tdd |D d}|r8|W d  I dH  dS 1 I dH sIw   Y  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.
        Nc                 s       | ]}|  V  qd S rB   r
  r   rz   r3   r3   r4   r         z,ConnectionPool.disconnect.<locals>.<genexpr>return_exceptionsTc                 s       | ]
}t |tr|V  qd S rB   rH   rA  r   rr3   r3   r4   r         )r  r   r   r  r  r   gathernext)rC   r  connectionsrespr  r3   r3   r4   r
    s"   .zConnectionPool.disconnectr_  )r.   r/   r0   rU   classmethodr   r  r:   r  r{   r
   rL   rD   r  r  r  r  r  r  r  r  rK   r
  r3   r3   r3   r4   r    s(    -
/!	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d
d Zdd Zdd ZdefddZddefddZ  ZS )BlockingConnectionPoola  
    Thread-safe blocking connection pool::

        >>> from aioredis.client import Redis
        >>> client = Redis(connection_pool=BlockingConnectionPool())

    It performs the same function as the default
    :py:class:`~redis.ConnectionPool` implementation, in that,
    it maintains a pool of reusable connections that can be shared by
    multiple redis clients (safely across threads if required).

    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.ConnectionPool` implementation does), it
    makes the client wait ("blocks") 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| d S )N)r  r  r3   )r  r~   r   rD   )rC   r  r~   r  r  r  r   r3   r4   rD      s   	
zBlockingConnectionPool.__init__c                 C   sL   |  | j| _	 z| jd  W n
 tjy   Y nw qg | _t | _	d S rB   )
r  r  pool
put_nowaitr   	QueueFull_connectionsr   r   r   rj   r3   r3   r4   r    s   zBlockingConnectionPool.resetc                 C   s"   | j di | j}| j| |S )zMake a fresh connection.Nr3   )r  r  r  r  r|   r3   r3   r4   r  *  s   z&BlockingConnectionPool.make_connectionc              	      s.  |    d}z*t| j4 I dH  | j I dH }W d  I dH  n1 I dH s+w   Y  W n tjtjfy@   tdw |du rI| 	 }z=|
 I dH  z| I dH r^tddW W |S  ty   | I dH  |
 I dH  | I dH rtddY W |S w  ty   | |I dH   w )a7  
        Get a connection, blocking for ``self.timeout`` until a connection
        is available from the pool.

        If the connection returned is ``None`` then creates a new connection.
        Because we use a last-in first-out queue, the existing connections
        (having been returned to the pool after the initial ``None`` values
        were added) will be returned before ``None`` values. This means we only
        create new connections when we need to, i.e.: the actual number of
        connections will only increase in response to demand.
        NzNo connection available.r  r  )r  r   r~   r  rq   r   
QueueEmptyr&   r   r  r  r   r
  rA  r  r  r3   r3   r4   r  0  s@   (

z%BlockingConnectionPool.get_connectionrz   c                    s\   |    | |s| I dH  | jd dS z	| j| W dS  tjy-   Y dS w )z)Releases the connection back to the pool.N)r  r  r
  r  r  r   r  r|   r3   r3   r4   r  e  s   
zBlockingConnectionPool.releaseTr  c              	      s   |    | j4 I dH + tjdd | jD ddiI dH }tdd |D d}|r,|W d  I dH  dS 1 I dH s=w   Y  dS )z(Disconnects all connections in the pool.Nc                 s   r  rB   r  r  r3   r3   r4   r     r  z4BlockingConnectionPool.disconnect.<locals>.<genexpr>r  Tc                 s   r  rB   r  r  r3   r3   r4   r     r  )r  r   r   r  r  r  )rC   r  r  r  r3   r3   r4   r
  z  s   .z!BlockingConnectionPool.disconnectr_  )r.   r/   r0   rU   r{   r   	LifoQueuerL   r
   r   QueuerD   r  r  r  r  rK   r
  r   r3   r3   r   r4   r    s(    #5r  )yr   enumr   r  r   r   r   r  r  warningsdistutils.versionr   	itertoolsr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   urllib.parser   r   r   r   r   compatr   r   
exceptionsr   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   utilsr'   BlockingIOErrorEWOULDBLOCKSSLWantReadErrorSSLWantWriteErrorSSLErrorr   rO  r  r   r   ImportErrorModuleNotFoundErrorr   __version__hiredis_versionwarnrQ  rS  r   SYM_LFrP  r   Enumr-   r2   r   r   r   r   r   rI   rJ   rX   r:   rL   rM   DecodedTrW   r5   r>   r;   r   rY   r   r   r   r<   r   r   r   ConnectCallbackTr{   r`  rl  r{  r  rK   r  r  r1   r  r  r  r  r  r3   r3   r3   r4   <module>   s   
 8D
$)D Po   *(2C
5  