
    <"ri                     *   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jr                  ejt                  dejv                  dejx                  diZ= e>e=j                               Z@	 d dlAZAdZB eeAj                        ZDeD ed      k  r# e	j                  deAj                   d       dZB	 dZHdZIdZJdZKdZLdZM G d dej                        ZOeOj                  ZQdZRdZSdZTdZUeeVeWf   ZXeeYeZe[f   Z\eeXe\f   Z] G d de%d      Z^ G d  d!      Z_eeYeee`   eeYee`   f   f   f   Za G d" d#      Zb G d$ d%      Zc G d& d'eb      Zd G d( d)eb      Zeeeedeef      efd*<   eBreeZgnedZg G d+ d,e$      Zh G d- d.e$      Zieeheif   Zj G d/ d0      Zk G d1 d2ek      Zl G d3 d4      Zm G d5 d6ek      Znd7Zod8eep   fd9Zq eeZe[e[eqeqeZeZeqd:      ZreeYed;esf   f   efd<<    G d= d>e%d      Ztd?eYd8etfd@Zu edAdBC      Zv G dD dB      Zw G dE dFew      Zxy# eFeGf$ r dZBY jw xY w)G    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   Tz1.0.0z@aioredis supports hiredis @ 1.0.0 or higher. You have hiredis @ z*. Pure-python parser will be used instead.F   *   $s   
   
    zConnection closed by server.c                       e Zd Z e       Zy)	_SentinelN)__name__
__module____qualname__objectsentinel r-   [/var/www/fortnox.pascalinesoft.com/venv/lib/python3.12/site-packages/aioredis/connection.pyr/   r/   V   s	    xHr-   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                   Z    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<   y)_HiredisReaderArgsprotocolError
replyErrorencodingerrorsN)r0   r1   r2   r   str	Exception__annotations__r   r5   r-   r6   r8   r8   i   s:    SE9,--#	)**smSMr-   r8   )totalc                   J    e Zd ZdZdZdededefdZdede	fd	Z
ddedefd
Zy)Encoderz=Encode strings to bytes-like and decode bytes-like to stringsr;   encoding_errorsdecode_responsesr;   rD   rE   c                 .    || _         || _        || _        y NrC   )selfr;   rD   rE   s       r6   __init__zEncoder.__init__u   s     . 0r-   valuereturnc                 |   t        |t        t        f      r|S t        |t              rt	        d      t        |t
        t        f      rt        |      j                         S t        |t              s%|j                  j                  }t	        d|d      |j                  | 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__r0   r;   rD   )rH   rJ   typenames      r6   rT   zEncoder.encodez   s    eeZ01LeT"B  ec5\*;%%''%%//H)( 6B B  ||DMM4+?+?@@r-   c                    | j                   s|rzt        |t              r4|j                         j	                  | j
                  | j                        S t        |t              r&|j	                  | j
                  | j                        S |S )z:Return a unicode string from the bytes-like representation)rE   rM   rO   tobytesdecoder;   rD   rN   )rH   rJ   forces      r6   rY   zEncoder.decode   sd      E%,}}--dmmT=Q=QRR%'||DMM43G3GHHr-   N)F)r0   r1   r2   __doc__	__slots__r=   rP   rI   
EncodableTEncodedTrT   rY   r5   r-   r6   rB   rB   p   sM    GAI1 1s 1d 1
AJ A8 A*J 
 r-   rB   c                       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Zd ZdedefdZd ZddZdedefdZde e!ede"e!   f   fdZ#y)
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                 .    d | _         d | _        || _        y rG   rb   )rH   rn   s     r6   rI   zBaseParser.__init__   s    7;/3*r-   c                 D    	 | j                          y # t        $ r Y y w xY wrG   )on_disconnectr>   rH   s    r6   __del__zBaseParser.__del__   s%    	  		s    	responserK   c                     |j                  d      d   }|| j                  v rQ|t        |      dz   d }| j                  |   }t        |t              r|j                  |t              }n|} ||      S t        |      S )zParse an error response r   r   N)splitrm   lenrM   dictgetr&   )rH   rt   
error_codeexception_class_or_dictexception_classs        r6   parse_errorzBaseParser.parse_error   s    ^^C(+
///J! 3 56H&*&<&<Z&H#148"9"="=h"V"9"8,,X&&r-   c                     t               rG   NotImplementedErrorrr   s    r6   rq   zBaseParser.on_disconnect       !##r-   c                     t               rG   r   rH   
connections     r6   
on_connectzBaseParser.on_connect   r   r-   timeoutc                    K   t               wrG   r   rH   r   s     r6   can_readzBaseParser.can_read   s     !##   Nc                    K   t               wrG   r   rr   s    r6   read_responsezBaseParser.read_response   s      "##r   r   
Connection)$r0   r1   r2   r[   r\   r   r   r   MODULE_LOAD_ERRORr!   MODULE_EXPORTS_DATA_TYPES_ERRORNO_SUCH_MODULE_ERROR MODULE_UNLOAD_NOT_POSSIBLE_ERRORr   r   r#   r$   r"   rm   ExceptionMappingTr?   rQ   rI   rs   r=   r&   r~   rq   r   rR   rP   r   r   r]   r	   r   r5   r-   r6   r`   r`      s    $2I ,_68K 3 ;<` ;<`{+[ +,k
 $#!!%#+,( 0+ +
'C 'M '$$$e $ $$	z=$Z0@@	A$r-   r`   c            	           e Zd ZdZdej
                  dedee   fdZ	e
d        Zdedfd	ee   d
eedef   dedefdZd
edefdZd	edefdZdefdZd Zd Zy)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_readerrn   socket_timeoutc                 |    || _         || _        || _        t        j                         | _        d| _        d| _        y Nr   )rc   rn   r   ioBytesIOrd   bytes_written
bytes_read)rH   r   rn   r   s       r6   rI   zSocketBuffer.__init__   s8     8E 0,-/ZZ\r-   c                 4    | j                   | j                  z
  S rG   )r   r   rr   s    r6   lengthzSocketBuffer.length   s    !!DOO33r-   NTr   r   raise_on_timeoutrK   c                   K   | j                   }|| j                  t        d      |j                  | j                         d}|t
        ur|n| j                  }	 	 t        j                  |      4 d {    | j                  j                  | j                         d {   }d d d       d {    t        t              rt        |      dk(  rt        t              |j!                  |       t        |      }| xj                  |z  c_        ||z  }|||kD  ry7 7 7 t# 1 d {  7  sw Y   xY w# t"        j                  t$        j&                  f$ r |rt'        d      Y yt(        $ rS}t*        j-                  |j.                  d      }	|s|j0                  |	k(  rY d }~yt        d|j2                         d }~ww xY ww)NBuffer is closed.r   TTimeout reading from socketF!Error while reading from socket: )rd   rc   r%   seekr   SENTINELr   async_timeoutr   readrn   rM   rN   rx   r   SERVER_CLOSED_CONNECTION_ERRORwritesocketasyncior'   NONBLOCKING_EXCEPTIONS#NONBLOCKING_EXCEPTION_ERROR_NUMBERSrz   rU   errnoargs)
rH   r   r   r   bufmarkerdatadata_lengthexalloweds
             r6   _read_from_socketzSocketBuffer._read_from_socket   s     ll;$,,.011##$$H4'$:M:M	Q(009 J J!%!2!243H3H!IIDJ J dE*s4yA~)*HII		$!$i""k1"+%%&6/JIJ J J J  4 45 	"#@AA% 	Q
 :==bllBOG#G(;!$EbggY"OPP	Qs   AGD? 6D$7D? :)D*#D&$D*(D? 3D(4A/D? #G$D? &D*(D? *D<0D31D<8D? ?0G/G1G91G*G/GGGc                 r   K   t        | j                        xs | j                  |d       d {   S 7 w)NFr   r   )rP   r   r   r   s     r6   r   zSocketBuffer.can_read%  s>     DKK  
$*@*@e +A +
 %
 	
 %
s   .757c                   K   |dz   }|| j                   kD  r&| j                  || j                   z
         d {    | j                  t        d      | j                  j	                  | j
                         | j                  j                  |      }| xj
                  t        |      z  c_        | j
                  | j                  k(  r| j                          |d d S 7 w)Nr)   r   )
r   r   rd   r%   r   r   r   rx   r   purge)rH   r   r   s      r6   r   zSocketBuffer.read*  s     !DKK(($++)=>>><<011$//*||  (3t9$ ??d000JJLCRy ?s   6C"C B(C"c                 
  K   | j                   }|t        d      |j                  | j                         |j	                         }|j                  t              sY| j                          d {    |j                  | j                         |j	                         }|j                  t              sY| xj                  t        |      z  c_        | j                  | j                  k(  r| j                          |d d S 7 w)Nr   r   )rd   r%   r   r   readlineendswithSYM_CRLFr   rx   r   r   )rH   r   r   s      r6   r   zSocketBuffer.readline>  s     ll;011!||~--)((***HHT__%<<>D	 --) 	3t9$ ??d000JJLCRy +s   A-D/D0AD5ADc                     | j                   t        d      | j                   j                  d       | j                   j                          d| _        d| _        y )Nr   r   )rd   r%   r   truncater   r   rr   s    r6   r   zSocketBuffer.purgeT  sI    <<011!r-   c                     	 | j                          | j                  j                          d | _        d | _        y # t        $ r Y w xY wrG   )r   rd   closer>   rc   rr   s    r6   r   zSocketBuffer.close]  sF    		JJLLL    	 	s   *; 	AA)r0   r1   r2   r[   r   StreamReaderrQ   r   rR   rI   propertyr   r   r   r/   rP   r   r   rN   r   r   r   r   r5   r-   r6   r   r      s    ++  !	 4 4
 !%19!%	(Q(Q udI-.(Q 	(Q
 
(QT
e 
 

  ( ,r-   r   c                   x     e Zd ZdZej
                  dz   Zdef fdZddZd Z	de
fdZd	eeed
f   fdZ xZS )PythonParserra   )encoderrn   c                 2    t         |   |       d | _        y rG   )superrI   r   rH   rn   rU   s     r6   rI   zPythonParser.__init__q  s    )**.r-   c                     |j                   | _        | j                  t        d      t        | j                  | j                  |j
                        | _        |j                  | _        y)zCalled when the stream connectsNr   )_readerrc   r%   r   re   r   rd   r   r   s     r6   r   zPythonParser.on_connectu  sU    !))<<011#LL$//:+D+D
 "))r-   c                     | j                   d| _         | j                  !| j                  j                          d| _        d| _        y)z"Called when the stream disconnectsN)rc   rd   r   r   rr   s    r6   rq   zPythonParser.on_disconnect  s;    <<#DL<<#LL DLr-   r   c                    K   | j                   xr, t        | j                   j                  |       d {         S 7 wrG   )rd   rP   r   r   s     r6   r   zPythonParser.can_read  s/     ||J4<<+@+@+I%I JJ%Is   2?=	?rK   Nc                   K   | j                   r| j                  st        t              | j                   j	                          d {   }|st        t              |d d |dd  }}|dvrt        d|      |dk(  r8|j                  dd      }| j                  |      }t        |t              r||S |dk(  rn|d	k(  rt        |      }n~|d
k(  r5t        |      }|dk(  ry | j                   j                  |       d {   }nD|dk(  r?t        |      }|dk(  ry t        |      D cg c]  }| j                          d {    }}t        |t              r| j                  j                  |      }|S 7 17 y7 :c c}w w)Nr   )   -   +   :r+   r*   zProtocol Error: r   utf-8replace)r<   r   r   r+   r   r*   )rd   r   r   r   r   r    rY   r~   rM   rQ   r   ranger   rN   )rH   rawbytert   errorr   _s          r6   r   zPythonParser.read_response  s{    ||4<<!"@AALL))++!"@AARa#ab'h55!$4SG"<== 4<wyAH$$X.E %1
 LT\T\8}HT\]F|!\\..v66HT\]F|>CFmLt11333LHLh&||**84HU ,B 7 4LsI   AFE8B9FE;(F*E?E=
E?	0F;F=E??Fr   )r0   r1   r2   r[   r`   r\   rQ   rI   r   rq   rR   r   r   r]   r&   r   __classcell__rU   s   @r6   r   r   l  sR    $$$|3I/ /	*Ke K-U:}d+J%K -r-   r   c                        e Zd ZU dZej
                  dz   Zeed<   def fdZ	ddZ
d Zdefd	Zed
fdeedef   defdZdeeee   f   fdZ xZS )HiredisParserz*Parser class for connections using Hiredis)_next_responser   _socket_timeoutr   rn   c                 d    t         st        d      t        |   |       d | _        d | _        y )NzHiredis is not available.rn   )HIREDIS_AVAILABLEr%   r   rI   r   r   r   s     r6   rI   zHiredisParser.__init__  s2     899*:;1504r-   c                 @   |j                   | _        t        | j                  d}|j                  j
                  r2|j                  j                  |d<   |j                  j                  |d<   t        j                  di || _         d| _
        |j                  | _        y )N)r9   r:   r;   r<   Fr5   )r   rc   r    r~   r   rE   r;   rD   hiredisReaderr   r   r   )rH   r   kwargss      r6   r   zHiredisParser.on_connect  s    !)),**&
 ..!+!3!3!<!<F:)11AAF8~~//#)88r-   c                 .    d | _         d | _        d| _        y )NF)rc   r   r   rr   s    r6   rq   zHiredisParser.on_disconnect  s    #r-   r   c                    K   | j                   st        t              | j                  du r| j                   j	                         | _        | j                  du r| j                  |d       d {   S y7 w)NFr   T)r   r   r   r   getsread_from_socketr   s     r6   r   zHiredisParser.can_read  sm     ||!"@AA%'"&,,"3"3"5D%'..wQV.WWW Xs   A-A7/A50A7TNr   c                 F  K   | j                   | j                  t        d      |t        u r| j                  n|}	 t        j                  |      4 d {    | j                   j                  | j                         d {   }d d d       d {    t        t              rt        |      dk(  rt        t              d | j                  j                  |       y7 7 `7 R# 1 d {  7  sw Y   bxY w# t        j                   $ r  t"        j                  t        j$                  f$ r |rt%        d      d Y yt&        $ rS}t(        j+                  |j,                  d      }|s|j.                  |k(  rY d }~yt        d|j0                         d }~ww xY ww)NzParser already closed.r   Tr   Fr   r   )rc   r   r%   r   r   r   r   r   re   rM   rN   rx   r   r   feedr   CancelledErrorr   r'   r   r   rz   rU   r   r   )rH   r   r   bufferr   r   s         r6   r   zHiredisParser.read_from_socket  so    
 <<4<<#7566*1X*=$&&7	Q$,,W5 B B#||00AAB Bfe,Fq0@%&DE4OLLf% BAB B B B %% 	 4 45 	"#@AtK% 	Q
 :==bllBOG#G(;!$EbggY"OPP	Qs   :F!C= C"C= )C(C$C(C= C&AC= !F!"C= $C(&C= (C:.C1/C:6C= =AFF!F1F<F!FFF!rK   c                 .  K   | j                   r| j                  s | j                          t        t              d | j
                  dur| j
                  }d| _        |S | j                  j                         }|du r7| j                          d {    | j                  j                         }|du r7t        |t              r|t        |t              r|rt        |d   t              r|d   t        t        t        t        t           f   |      S 7 w)NFr   )rc   r   rq   r   r   r   r   r   rM   listr   r   r]   r	   )rH   rt   s     r6   r   zHiredisParser.read_response	  s     ||4<< !"@AtK e+**H"'DO<<$$&%'')))||((*H % h0Nx&8A;81+E*d:&667BB *s   BDD"D3A!Dr   )r0   r1   r2   r[   r`   r\   rP   r?   rQ   rI   r   rq   rR   r   r   r   r/   r   r]   r	   r   r   r   s   @r6   r   r     s    4$$'WWI5 59$
e  2:!% QudI-. Q  QDCU:tJ7G+G%H Cr-   r   DefaultParserc                       e Zd ZddZy)ConnectCallbackProtocolc                      y rG   r5   r   s     r6   __call__z ConnectCallbackProtocol.__call__3  s    r-   Nr   r0   r1   r2   r   r5   r-   r6   r   r   2      r-   r   c                       e Zd ZddZy)AsyncConnectCallbackProtocolc                    K   y wrG   r5   r   s     r6   r   z%AsyncConnectCallbackProtocol.__call__8  s	     s   Nr   r   r5   r-   r6   r   r   7  r   r-   r   c            (          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Zd  Zd! Zd" Zed#        Zd$ Zd% Zd& Zd' Zd( Zd) Zd* Zd+ Zd,ee   d-dfd.Z 	 d9d,eeeee   f   d/efd0Z!d1 Z"d:d2efd3Z#d4 Z$d5e%d-e&e   fd6Z'd7eee%      d-e&e   fd8Z(y);r   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  r;   rD   rE   parser_classrn   r  r  r  encoder_classr  r  r  r  r   r  r  r	  r
  r  r;   rD   rE   r  rn   r  r  r  r  c                   t        j                         | _        || _        t	        |      | _        || _        || _        || _        || _	        || _
        |xs |xs d | _        || _        |xs i | _        |	| _        |
| _        || _        d| _        d | _         ||||      | _        d | _        d | _         ||      | _        g | _        d| _        t3        j4                         | _        y Nr   r   ip  )osgetpidr   r  rQ   r  r  r  r  r  r   r  r  r	  r
  r  r  r  r  r   r   r  r  r  r  r   Lockr  )rH   r  r  r  r  r   r  r  r	  r
  r  r;   rD   rE   r  rn   r  r  r  r  s                       r6   rI   zConnection.__init__^  s    . 99;	I	 & ,&<&V&VRV# 0(@(FB%& 0%:"(*6:$X@PQ7;7;#-
 ;="\\^
r-   c                     dj                  d | j                         D              }| j                  j                   d| dS )N,c              3   0   K   | ]  \  }}| d |   yw)=Nr5   ).0kvs      r6   	<genexpr>z&Connection.__repr__.<locals>.<genexpr>  s     HTQ1QCjHs   <>)joinrepr_piecesrU   r0   )rH   	repr_argss     r6   __repr__zConnection.__repr__  s=    HHHT5E5E5GHI	..))*!I;a88r-   c                     d| j                   fd| j                  fd| j                  fg}| j                  r|j	                  d| j                  f       |S )Nr  r  r  r  )r  r  r  r  appendrH   piecess     r6   r+  zConnection.repr_pieces  sM    499%		':T477OLMM=$*:*:;<r-   c                     	 | j                   rXt        j                         }| j                         }|j	                         r|j                  |       y |j                  |       y y # t        $ r Y y w xY wrG   )is_connectedr   get_event_loop
disconnect
is_runningcreate_taskrun_until_completer>   )rH   loopcoros      r6   rs   zConnection.__del__  si    		  --/(??$$$T*++D1 !  		s   AA' A' '	A32A3c                 H    t        | j                  xr | j                        S rG   )rP   r   r  rr   s    r6   r3  zConnection.is_connected  s    DLL1T\\22r-   c                 :    | j                   j                  |       y rG   )r  r/  )rH   callbacks     r6   register_connect_callbackz$Connection.register_connect_callback  s    &&x0r-   c                     g | _         y rG   )r  rr   s    r6   clear_connect_callbacksz"Connection.clear_connect_callbacks  s
    "$r-   c                 b  K   | j                   ry	 | j                          d{    	 | j                          d{    | j                  D ]-  } ||       }|st        j                   |      s$| d{    / y7 Z# t        j                  $ r  t        j
                  t        j                  f$ r t        d      t        $ r}t        | j                  |            d}~wt        $ r}t        |      |d}~ww xY w7 # t        $ r | j                          d{  7    w xY w7 w)z5Connects to the Redis server if not already connectedNzTimeout connecting to server)r3  _connectr   r   r   r   r'   OSErrorr   _error_messager>   r   r%   r5  r  inspectisawaitable)rH   eexcr=  tasks        r6   connectzConnection.connect  s    		0--/!!	//### // 	HD>D++D1

	' "%% 	 4 45 	?=>> 	:!$"5"5a"899 	0!#&C/	0 $ 	//###	 s   D/B A?B D DD D/D/2D/7D-8D/?B A	D
C$$D0C<<DD/D D*"D%#D**D/c                 l  K   t        j                  | j                        4 d{    t        j                  | j
                  | j                  | j                  r| j                  j                         nd       d{   \  }}ddd      d{    | _	        | _
        |j                  j                  d      }||j                  t        j                  t        j                   d       	 | j"                  rs|j                  t        j$                  t        j&                  d       | j(                  j+                         D ]&  \  }}|j                  t        j,                  ||       ( yyy7 N7 7 # 1 d{  7  sw Y   xY w# t.        t0        f$ r |j3                           w xY ww)zCreate a TCP socket connectionN)r  r  sslr   r   )r   r   r  r   open_connectionr  r  r  rz   r   r  	transportget_extra_info
setsockoptr   IPPROTO_TCPTCP_NODELAYr  
SOL_SOCKETSO_KEEPALIVEr	  itemsSOL_TCPrC  	TypeErrorr   )rH   readerwritersockr%  r&  s         r6   rB  zConnection._connect  sg     (()D)DE 	 	#*#:#:YYYY.2.>.>D$$((*D$ NFF	 	 ..x8OOF..0B0BAF((OOF$5$5v7J7JAN $ = = C C E >11=> )	 		 	 	 	$ Y'  	sq   $F4E4F4AE; E7E;F4E9AF43A>F 1F47E;9F4;FFF	F4!F11F4c           	         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 )rx   r   r  r  rH   	exceptions     r6   rD  zConnection._error_message  s     y~~!#)$))Adii[9>>RSCTBUUVWW *+?499+QtyykQS>>!$%Q(r-   c                   K   | j                   j                  |        | j                  s| j                  r| j                  r| j                  | j                  xs df}n| j                  xs df} | j                  dg|ddi d{    	 | j                          d{   }t        |      dk7  rt        d      | j                  rT| j	                  d	d
| j                         d{    t        | j                          d{         dk7  rt        d      | j                  rT| j	                  d| j                         d{    t        | j                          d{         dk7  rt        d      yy7 7 # t        $ rD | j	                  d| j                  d       d{  7   | j                          d{  7  }Y *w xY w7 7 7 7 rw)z=Initialize the connection, authenticate and select a database AUTHcheck_healthFNre  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  )rH   	auth_argsauth_responses      r6   r   zConnection.on_connect  s    % ==DMM}}!]]DMM,?R@	 "]]0b2	 $$##FKYKUKKK;&*&8&8&: : M*d2)*HII ##Hi9I9IJJJ$"4"4"6674?%&ABB 77##Hdgg666$"4"4"6674?%&899 @ - L !;7 ;
 ''E'RRR&*&8&8&: : :; K6
 76s   BG	F
GF "F#F 'AG,G-G	G
AGGG(G)GF *G/F20GG	GGGGGGGc                   K   	 t        j                  | j                        4 d{    | j                  j	                          | j
                  s	 ddd      d{    y	 t        j                         | j                  k(  rR| j                  j                          t        | j                  d      r"| j                  j                          d{    d| _        d| _	        ddd      d{    y7 7 7 '# t        $ r Y 0w xY w7 # 1 d{  7  sw Y   yxY w# t        j                   $ r t!        d| j                         dw xY ww)z!Disconnects from the Redis serverNwait_closedz#Timed out closing connection after )r   r   r  r  rq   r3  r  r  r   r  r   hasattrro  rC  r   r   r'   rr   s    r6   r5  zConnection.disconnect  s(    	$,,T-H-HI $ $**,(($ $ $yy{dhh.**,"4<<?"&,,":":"<<<  $#$ $ $ $ = $ $ $ $ ## 	5d6Q6Q5RS	s   E#D# C7D# (DD# C9D# #E%A.C=C;C=D&D# 1D2D# 6E7D# 9D# ;C==	D	DD		DD# D DD D# E D# #-EEc                 T  K   | j                   r|t        j                         j                         | j                  kD  rL	 | j                  dd       d{    t        | j                          d{         dk7  rt        d      yyy7 67 # t        t        f$ r}| j                          d{  7   	 | j                  dd       d{  7   t        | j                          d{  7        dk7  rt        d      dn# t        $ r}||d}~ww xY wY d}~yd}~ww xY ww)z3Check the health of the connection with a PING/PONGPINGFrf  NPONGz#Bad response from PING health check)r  r   r4  timer  rk  r(   r   r   r'   r5  BaseException)rH   errerr2s      r6   re  zConnection.check_health0  s&     &&&&(--/$2H2HH(''U'CCCd&8&8&: :;vE)*OPP F	 I ' D :#\2 	(oo'''(++F+GGG#$*<*<*>$>$>?6I-A#$ J % (C'(	 J		(s   <D(B BB 2B3B 	D(B B D%D 2B53D 9DCD-C0
.DD 	DDDD D( D%%D(commandrK   c                    K   | j                   t        d      | j                   j                  |       | j                   j                          d {    y 7 w)NzConnection already closed.)r  r%   
writelinesdrain)rH   rx  s     r6   _send_packed_commandzConnection._send_packed_commandE  sD     <<9::(ll  """s   AAAAre  c                 &  K   | j                   s| j                          d{    |r| j                          d{    	 t        |t              r|j                         }t        |t              r|g}t        j                  | j                  |      | j                         d{    y7 7 r7 	# t        j                  $ r& | j                          d{  7   t        d      dt        $ ry}| j                          d{  7   t        |j                        dk(  rd|j                  d   }}n|j                  d   }|j                  d   }t!        d| d| d      |d}~wt"        $ r | j                          d{  7    w xY ww)	z2Send an already packed command to the Redis serverNzTimeout writing to socketr   UNKNOWNr   r_  z while writing to socket. r^  )r  rJ  re  rM   r=   rT   rN   r   wait_forr|  r   r'   r5  rC  rx   r   r   ru  )rH   rx  re  rG  err_noerrmsgs         r6   send_packed_commandzConnection.send_packed_commandL  sh     ||,,.  ##%%%	'3'!..*'5)")""))'2##   ! & ## 	F//###:;E 		//###166{a!*AFF1I! :6(!D  	//###	s{    FB-FB/FA%B3 'B1(B3 ,F/F1B3 3&FCF3E'D	A E''FF	FFc                    K   | j                   s| j                          d{    | j                   | j                  | |j	                  dd             d{    y7 =7 w)z+Pack and send a command to the Redis serverNre  Trf  )r3  rJ  r  pack_commandrz   )rH   r   r   s      r6   rk  zConnection.send_commandq  sc       ,,.  &&Dt$6::nd3S ' 
 	
 	
 !	
s!    A$A 7A$A"A$"A$r   c                    K   | j                   s| j                          d{    | j                  j                  |       d{   S 7 '7 w)z8Poll the socket to see if there's data that can be read.N)r3  rJ  r  r   r   s     r6   r   zConnection.can_ready  s?       ,,.  \\**7333 !3s!    AA
"AAAAc           	        K   	 | j                   4 d{    t        j                  | j                        4 d{    | j                  j                          d{   }ddd      d{    ddd      d{    | j                  r4t        j                          j#                         | j                  z   | _        t'        t(              r|d|S 7 7 7 }7 o# 1 d{  7  sw Y   xY w7 v# 1 d{  7  sw Y   xY w# t        j                  $ r? | j                          d{  7   t        d| j                   d| j                         t        $ rP}| j                          d{  7   t        d| j                   d| j                   d|j                         d}~wt        $ r | j                          d{  7    w xY ww)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'   r5  r  r  rC  r   r   ru  r  r4  rt  r  rM   r&   )rH   rt   rG  s      r6   r   zConnection.read_response  s    	zz B B(001D1DE B B%)\\%?%?%AAHB BB B %%&&(--/$2L2LL " h.$-BBAB B B BB B B B ## 	P//###!6tyyk499+NOO 	//###!+DII;a		{#affXN   	//###	s   GD CD $C7CC7 C CC #C7.C/C73D >C5?D AGD C7C C7 C2	&C)'C2	.C75D 7D	=D >D	D &G2D532G%F08E;97F00GGGGr   c           	         g }t        |d   t              rJ t        |d   t              r1t        |d   j	                         j                               |dd z   }n)d|d   v r"t        |d   j                               |dd z   }t        j                  t        t        t        |            j	                         t        f      }| j                  }t        | j                  j                  |      D ]  }t        |      }t        |      |kD  s||kD  st        |t              rat        j                  |t        t        |      j	                         t        f      }|j!                  |       |j!                  |       t        }t        j                  |t        t        |      j	                         t        |t        f      } |j!                  |       |S )z2Pack a series of arguments into the Redis protocolr   r   N    )rM   rR   r=   tuplerT   rw   	SYM_EMPTYr*  SYM_STARrx   r   r  mapr   rO   
SYM_DOLLARr/  )rH   r   outputbuffbuffer_cutoffarg
arg_lengths          r6   r  zConnection.pack_command  s    d1gu---d1gs#a)//12T!"X=DT!W_a)DH4D~~xSY)>)>)@(KL++t||**D1 	C SJD	M)-c:. ~~:s:'='='?J d#c" ~~"J..0  	!	4 	dr-   commandsc                    g }g }d}| j                   }|D ]  } | j                  | D ]  }t        |      }||kD  s||kD  st        |t              r(|j                  t        j                  |             d}g }||kD  st        |t              r|j                  |       w|j                  |       ||z  }  |r$|j                  t        j                  |             |S )z.Pack multiple commands into the Redis protocolr   )r  r  rx   rM   rO   r/  r  r*  )	rH   r  r  r1  buffer_lengthr  cmdchunkchunklens	            r6   pack_commandszConnection.pack_commands  s      ++ 	.C***C0 .u:!M1-/!%4MM).."89$%MFm+z%/LMM%(MM%(!X-M.	.$ MM)..01r-   T)r   ))r0   r1   r2   r[   r\   r   rB   r=   r   rQ   r   rR   rP   r
   rN   r   r`   rI   r-  r+  rs   r   r3  r>  r@  rJ  rB  rD  r   r5  re  r   r|  r  rk  r   r   r]   r	   r  r  r5   r-   r6   r   r   ?  s/   >I>   $"&*.26!&NR!&'!&)6 %'(%)"&'.+/$ /$ CHo	/$
 #s(O/$ 3-/$ !/$ !)/$ /$ #+73c5j8I3I+J"K/$ /$ /$ /$ /$ /$  :&!/$" #/$$  %%/$& c]'/$( 3-)/$* G}+/$b9
 3 31%:4	':R,(*#(5/ #d # "#uc8E?23# #J
4e 46,* ,e ,\hx
/C&D e r-   r   c                        e Zd Z	 	 	 	 	 ddee   dee   dedee   def
 fdZed        Zed        Z	ed	        Z
ed
        Zed        Z xZS )SSLConnectionssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_check_hostnamec                 N    t        |   di | t        |||||      | _        y )N)keyfilecertfile	cert_reqsca_certscheck_hostnamer5   )r   rI   RedisSSLContextr  )rH   r  r  r  r  r  r   rU   s          r6   rI   zSSLConnection.__init__  s1     	"6",;!#!--
r-   c                 .    | j                   j                  S rG   )r  r  rr   s    r6   r  zSSLConnection.keyfile  s    '''r-   c                 .    | j                   j                  S rG   )r  r  rr   s    r6   r  zSSLConnection.certfile      (((r-   c                 .    | j                   j                  S rG   )r  r  rr   s    r6   r  zSSLConnection.cert_reqs  s    )))r-   c                 .    | j                   j                  S rG   )r  r  rr   s    r6   r  zSSLConnection.ca_certs  r  r-   c                 .    | j                   j                  S rG   )r  r  rr   s    r6   r  zSSLConnection.check_hostname	  s    ...r-   )NNrequiredNF)r0   r1   r2   r   r=   rP   rI   r   r  r  r  r  r  r   r   s   @r6   r  r    s     &*&*'&*#(
c]
 sm
 	

 sm
 !
$ ( ( ) ) * * ) ) / /r-   r  c                   p    e Zd ZdZ	 	 	 	 	 ddee   dee   dee   dee   def
dZd	ej                  fd
Z
y)r  )r  r  r  r  contextr  Nr  r  r  r  r  c                 2   || _         || _        |t        j                  | _        n\t        |t              rLt        j                  t        j                  t        j                  d}||vrt        d|       ||   | _        || _
        || _        d | _        y )N)noneoptionalr  z+Invalid SSL Certificate Requirements Flag: )r  r  rL  	CERT_NONEr  rM   r=   CERT_OPTIONALCERT_REQUIREDr%   r  r  r  )rH   r  r  r  r  r  	CERT_REQSs          r6   rI   zRedisSSLContext.__init__  s       ]]DN	3'----I
 	) A)M  'y1DN ,15r-   rK   c                 x   | j                   st        j                         }| j                  |_        | j                  |_        | j                  r3| j                  r'|j                  | j                  | j                         | j                  r|j                  | j                         || _         | j                   S )N)r  r  )r  rL  create_default_contextr  r  verify_moder  r  load_cert_chainr  load_verify_locations)rH   r  s     r6   rz   zRedisSSLContext.get3  s    ||002G%)%8%8G""&..G}}'''U}}--dmm<"DL||r-   )NNNNF)r0   r1   r2   r\   r   r=   rP   rI   rL  
SSLContextrz   r5   r-   r6   r  r    so    I "&"&#'"&$6#6 3-6 C=	6
 3-6 66
S^^ 
r-   r  c                       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Zdeeeeeef   f      fdZd Zd Zy)UnixDomainSocketConnectionrc  r   Nr   r  Fr  g        )pathr  r  r  r   r  r;   rD   rE   r  r  rn   r  r  r  r  r  r  r   r  r;   rD   rE   r  r  rn   r  c                   t        j                         | _        || _        || _        || _        || _        || _        || _        |xs |xs d | _	        |
| _
        || _        d| _        t        |||	      | _        d | _        d | _        d | _         ||      | _        g | _        d| _        t+        j,                         | _        y r  )r  r  r   r  r  r  r  r  r   r  r  r  r  rB   r   _sockr   r  r  r  r  r   r  r  )rH   r  r  r  r  r   r  r;   rD   rE   r  r  rn   r  r  s                  r6   rI   z#UnixDomainSocketConnection.__init__A  s    $ 99;	 & ,&<&V&VRV# 0%:"!#x:JK
#5EF"$"\\^
r-   rK   c                     d| j                   fd| j                  fg}| j                  r|j                  d| j                  f       |S )Nr  r  r  )r  r  r  r/  r0  s     r6   r+  z&UnixDomainSocketConnection.repr_piecesg  sG    TYY477O
 MM=$*:*:;<r-   c                 X  K   t        j                  | j                        4 d {    t        j                  | j
                         d {   \  }}d d d       d {    | _        | _        | j                          d {    y 7 f7 @7 /# 1 d {  7  sw Y   ?xY w7  w)N)r  )	r   r   r  r   open_unix_connectionr  r   r  r   )rH   rX  rY  s      r6   rB  z#UnixDomainSocketConnection._connectp  s      (()D)DE 	P 	P#*#?#?TYY#OONFF	P 	Poo		PO	P 	P 	P 	P 	 sb   $B*BB*$BBBB*!B"%B*B(B*BB*B%BB%!B*c                     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: )rx   r   r  r`  s     r6   rD  z)UnixDomainSocketConnection._error_messagew  su     y~~!#6tyykINNSTDUCVVWXX *++G99+R	q 12!5r-   )r0   r1   r2   r   r=   r   rQ   r   rR   rP   r   r`   rI   r   r   r+  rB  rD  r5   r-   r6   r  r  @  s     "&"&*.26'!&!&)6 %'*!$$ $$ #s(O	$$
 3-$$ 3-$$ !$$ !)$$ $$ $$ $$ $$ :&$$ $$  %$$LXeCsCx,@&AB  	r-   r  )0FFALSENNOrK   c                 v    | | dk(  ry t        | t              r| j                         t        v ryt	        |       S )Nrc  F)rM   r=   upperFALSE_STRINGSrP   )rJ   s    r6   to_boolr    s4    }%%++-="@;r-   )r  r   r  r  r  max_connectionsr  r  .URL_QUERY_ARGUMENT_PARSERSc                   Z    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<   y)	ConnectKwargsr  r  connection_classr  r  r  r  N)r0   r1   r2   r=   r?   r   r   rQ   r5   r-   r6   r  r    s+    MM:&&
I
IG
Ir-   r  urlc                    t        |       }i }t        |j                        j                         D ]N  \  }}|s	t	        |      dkD  st        |d         }t        j                  |      }|r	  ||      ||<   J|||<   P |j                  rt        |j                        |d<   |j                  rt        |j                        |d<   |j                  dk(  r/|j                  rt        |j                        |d<   t        |d<   |S |j                  d	v r|j                  rt        |j                        |d
<   |j                   rt#        |j                         |d<   |j                  r6d|vr2	 t#        t        |j                        j%                  dd            |d<   |j                  dk(  r	t(        |d<   |S d}t        d| d      # t        t        f$ r t        d| d      w xY w# t&        t        f$ r Y ^w xY w)Nr   zInvalid value for `z` in connection URL.r  r  unixr  r  )redisredissr  r  r  /rc  r  zredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())r   r   queryrU  rx   r   r  rz   rW  
ValueErrorr  r  schemer  r  hostnamer  rQ   r   AttributeErrorr  )r  parsedr   name
value_listrJ   parservalid_schemess           r6   	parse_urlr    s   "3-FF$V\\288: %j#j/A-JqM*E/33D9FW#)%=F4L  %t% $V__5z$V__5z }};;$V[[1F6N%?!"0 M- 
-	-??$V__5F6N;; -F6N ;;4v-"76;;#7#?#?R#HIt ==H$)6F%& M 7CM?RST
 	
E ":. W$':4&@T%UVVW6 #J/ s   /G/1G- G*-G?>G?_CPConnectionPool)boundc                       e Zd ZdZedee   dedefd       Ze	dfdee	   de
e   fd	Zd
 Zd Zd Zd Zd Zd Zde	fdZde	fdZddefdZy)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  rK   c                 J    t        |      }|j                  |        | 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.
        r5   )r  update)r  r  r   url_optionss       r6   from_urlzConnectionPool.from_url  s&    P  nk"}V}r-   Nr  r  c                 T   |xs d}t        |t              r|dk  rt        d      || _        || _        || _        t        j                         | _        t        j                         | _
        |  |  |  | j                          | j                  j                  dt              | _        y )Nl        r   z,"max_connections" must be a positive integerr  )rM   rQ   r  r  connection_kwargsr  	threadingr  
_fork_lockr   r  resetrz   rB   r  )rH   r  r  r  s       r6   rI   zConnectionPool.__init__  s     *4W/3/?Q3FKLL 0!2. $..*\\^


!3377Qr-   c                 n    | j                   j                   d | j                  di | j                  dS )Nr(  r)  r5   )rU   r0   r  r  rr   s    r6   r-  zConnectionPool.__repr__6  s>    ~~&&'%%%?(>(>?B!E	
r-   c                     t        j                         | _        d| _        g | _        t               | _        t        j                         | _	        y r   )
r   r  r  _created_connections_available_connectionsset_in_use_connectionsr  r  r   rr   s    r6   r  zConnectionPool.reset<  s8    \\^
$%!&(##&5  99;r-   c                 f   | j                   t        j                         k7  rq| j                  j	                  d      }|st
        	 | j                   t        j                         k7  r| j                          | j                  j                          y y # | j                  j                          w xY w)N   )r   )r   r  r  r  acquirer   r  release)rH   acquireds     r6   	_checkpidzConnectionPool._checkpidM  s    F 88ryy{"..q.9H***88ryy{*JJL'') # '')s   1B B0c                   K   | j                          | j                  4 d{    	 | j                  j                         }| j                  j                  |       ddd      d{    	 j                          d{    	 |j                          d{   rt        d      d	 |S 7 # t        $ r | j                         }Y w xY w7 f# 1 d{  7  sw Y   vxY w7 d7 M# t        $ r[ |j                          d{  7   |j                          d{  7   |j                          d{  7  rt        d      dY |S w xY w# t        $ r | j                         d{  7    w xY ww)zGet a connection from the poolNConnection has dataConnection not ready)r  r  r  pop
IndexErrormake_connectionr  addrJ  r   r   r5  ru  r  rH   command_namekeysoptionsr   s        r6   get_connectionzConnectionPool.get_connection|  sq    :: 	5 	54!88<<>
 $$((4	5 	5	$$&&&
L#,,...)*?@dJ / 9	5  4!113
4	5 	5 	5 	5 ' /" L ++--- ((***#,,...)*@AtK / L
  	 ,,z***		s   !E:B/E:CB1CE:)C*E:/E C'E C+ C)C+ -E:1C
CCCE:C$CC$ E:'E )C+ +ED
E D#!E9D<:EE E:EE E7/E20E77E:c                     | j                   }| j                  |j                  dd      |j                  dd      |j                  dd            S )z,Return an encoder based on encoding settingsr;   r   rD   r  rE   FrC   )r  r  rz   )rH   r   s     r6   get_encoderzConnectionPool.get_encoder  sQ    ''!!ZZ
G4"JJ'8(C#ZZ(:EB " 
 	
r-   c                     | j                   | j                  k\  rt        d      | xj                   dz  c_          | j                  di | j                  S )zCreate a new connectionzToo many connectionsr   r5   )r  r  r   r  r  rr   s    r6   r  zConnectionPool.make_connection  sO    $$(<(<<!"899!!Q&!$t$$>t'='=>>r-   r   c                   K   | j                          | j                  4 d{    	 | j                  j                  |       | j                  |      r| j                  j                  |       n?| xj                  dz  c_        |j                          d{    	 ddd      d{    yddd      d{    y7 # t        $ r Y w xY w7 87 )7 # 1 d{  7  sw Y   yxY ww)z(Releases the connection back to the poolNr   )
r  r  r  removeKeyErrorowns_connectionr  r/  r  r5  r   s     r6   r  zConnectionPool.release  s     :: 	 	((//
; ##J/++22:>
 ))Q.) ++---!	 	 	 	 	    .	 	 	 	 	s   !C-CC-CCACCCC-*C+C-;C<C-	CCCCC-C-C*C!C*&C-c                 4    |j                   | j                   k(  S rG   )r   r   s     r6   r  zConnectionPool.owns_connection  s    ~~))r-   inuse_connectionsc                   K   | j                          | j                  4 d{    |r!t        | j                  | j                        }n| j                  }t        j                  d |D        ddi d{   }t        d |D        d      }|r|ddd      d{    y7 7 .7 	# 1 d{  7  sw Y   yxY ww)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              3   <   K   | ]  }|j                           y wrG   r5  r$  r   s     r6   r'  z,ConnectionPool.disconnect.<locals>.<genexpr>  s     Hj*'')H   return_exceptionsTc              3   B   K   | ]  }t        |t              s|  y wrG   rM   ru  r$  rs     r6   r'  z,ConnectionPool.disconnect.<locals>.<genexpr>       Ha:a+GH   )r  r  r   r  r  r   gathernext)rH   r  connectionsresprH  s        r6   r5  zConnectionPool.disconnect  s      	:: 	 	 49//1I1I5 #99 HKH"& D H4H$OC		 	 		 	 	 	sW   !B>B#B>AB)6B%7B)B>B'B>%B)'B>)B;/B20B;7B>r  )r0   r1   r2   r[   classmethodr   r  r=   r  r   r   rQ   rI   r-  r  r  r  r  r  r  r  rP   r5  r5   r-   r6   r  r    s     )d3i )c ) ) )Z .8)-Rz*R "#R<
"-*^B
?
 *** *$ r-   c            
            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Zd	 Zd
 Zd ZdefdZddefdZ x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                 J    || _         || _        |  t        |   d||d| y )N)r  r  r5   )r,  r   r   rI   )rH   r  r   r  r,  r  rU   s         r6   rI   zBlockingConnectionPool.__init__   s9     ' 	
-+	
  	
r-   c                     | j                  | j                        | _        	 	 | j                  j                  d        # t        j
                  $ r Y nw xY wg | _        t        j                         | _	        y rG   )
r,  r  pool
put_nowaitr   	QueueFull_connectionsr  r  r   rr   s    r6   r  zBlockingConnectionPool.reset  sl    $$T%9%9:			$$T*  $$ 
  99;s   ? AAc                 t     | j                   di | j                  }| j                  j                  |       |S )zMake a fresh connection.r5   )r  r  r2  r/  r   s     r6   r  z&BlockingConnectionPool.make_connection*  s7    *T**DT-C-CD
  ,r-   c                 J  K   | j                          d}	 t        j                  | j                        4 d{    | j                  j	                          d{   }ddd      d{    || j                         }	 |j                          d{    	 |j                          d{   rt        d      d	 |S 7 7 i7 [# 1 d{  7  sw Y   kxY w# t
        j                  t
        j                  f$ r t        d      w xY w7 y7 b# t        $ r[ |j                          d{  7   |j                          d{  7   |j                          d{  7  rt        d      dY |S w xY w# t        $ r | j                  |       d{  7    w xY w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/  rz   r   
QueueEmptyr'   r   r  rJ  r   r5  ru  r  r	  s        r6   r  z%BlockingConnectionPool.get_connection0  s     	 
	>$,,T\\: 3 3#'99==?2
3 3 --/J	$$&&&
L#,,...)*?@dJ / A323 3 3 3""G$8$89 	> ""<==	> ' /" L ++--- ((***#,,...)*@AtK / L
  	,,z***	s  F##C CC C	CC	 C +C,C 0F#E; DE; D /D0D F#C C	C 	CCCC /DF#E; D E80D31E8	E
E8"E%#E84E; 5F#7E88E; ;F FF  F#r   c                 $  K   | j                          | j                  |      s4|j                          d{    | j                  j	                  d       y	 | j                  j	                  |       y7 =# t
        j                  $ r Y yw xY ww)z)Releases the connection back to the pool.N)r  r  r5  r/  r0  r   r1  r   s     r6   r  zBlockingConnectionPool.releasee  s      	##J/
 '')))II  &	II  , *    	 	s3   5BA5 BA7 4B7B
BBBr  c                 6  K   | j                          | j                  4 d{    t        j                  d | j                  D        ddi d{   }t        d |D        d      }|r|ddd      d{    y7 Z7 .7 	# 1 d{  7  sw Y   yxY ww)z(Disconnects all connections in the pool.Nc              3   <   K   | ]  }|j                           y wrG   r  r  s     r6   r'  z4BlockingConnectionPool.disconnect.<locals>.<genexpr>  s     Nj*'')Nr  r  Tc              3   B   K   | ]  }t        |t              s|  y wrG   r  r  s     r6   r'  z4BlockingConnectionPool.disconnect.<locals>.<genexpr>  r!  r"  )r  r  r   r#  r2  r$  )rH   r  r&  rH  s       r6   r5  z!BlockingConnectionPool.disconnectz  s     :: 	 	 ND<M<MN"& D H4H$OC		 	 		 	 	 	sV   !BA>B*BB B-B8B9B BBB
BBBr  )r0   r1   r2   r[   r   r   	LifoQueuerQ   r   r   QueuerI   r  r  r  r  rP   r5  r   r   s   @r6   r)  r)    s    F  "!#-7+2+<+<

 #
 z*	

 '--(
$03j
 *
$ 
r-   r)  )yr   enumr   rE  r   r  r   rL  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   r  r  r   r   r   __version__hiredis_versionwarnImportErrorModuleNotFoundErrorr  r  r   SYM_LFr  r   Enumr/   r4   r   r   r   r   r   rN   rO   r^   r=   rQ   rR   DecodedTr]   r8   rB   r>   r   r`   r   r   r   r?   r   r   r   ConnectCallbackTr   r  r  r  r  rP   r  r  r3   r  r  r  r  r)  r5   r-   r6   <module>rT     sk       	 	  
   +  "    B A  '    "   U&&!1LL!	' # BGGIJ "
 #G$7$78Ow//"")"5"5!6 777	

 "
		!? 		  P N #T     
"#c5!8X%&
% & &R CtIT)_@T8U'U!VVW A$ A$HI IXM: M`lCJ lC^ E,567 7!M Mh 
8 
 02NNO d dN%/J %/P/ /d@ @F /htn  CS"'##!$%	C GC#v+)>$>? IU 23 2= 2j e+,} }@f^ f}, 	() s   !J 	JJ