a
    xd                     @   s  d dl mZ d dlmZ d dlmZ d dlm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mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ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*m+Z+m,Z,m-Z-m.Z.m/Z/ d dl0m1Z1 zd dl2Z2d	Z3W n e4y(   d
Z3Y n0 eej5iZ6e3rfe7e2dr\de6e2j8< de6e2j9< n
de6e2j:< e
j;e6vr|de6e
j;< e<e6= Z>e1rd dl?Z?ee?j@ZAeAedkZBeAedkZCeAedkZDeCsde?j@ ZEeFeE d	ZGeCsd
ZGdZHdZIdZJdZKdZLeM ZNG dd deMZOG dd deMZPG dd deMZQG dd dePZRG dd  d ePZSe1rbeSZTneRZTG d!d" d"eMZUG d#d$ d$eUZVG d%d& d&eUZWd'ZXd(d) ZYeZeZeYeYe[e[eYd*Z\G d+d, d,eMZ]G d-d. d.e]Z^dS )/    )unicode_literals)StrictVersion)chain)timeN)xrangeimapunicodelong	nativestr
basestring	iteritems	LifoQueueEmptyFullurlparseparse_qsrecv	recv_intounquoteBlockingIOErrorsendallshutdownssl_wrap_socket)AuthenticationError$AuthenticationWrongNumberOfArgsErrorBusyLoadingErrorChildDeadlockedErrorConnectionError	DataErrorExecAbortErrorInvalidResponseNoPermissionErrorNoScriptErrorReadOnlyError
RedisErrorResponseErrorTimeoutError)HIREDIS_AVAILABLETFSSLWantReadError   iz0.1.3z0.1.4z1.0.0z`redis-py works best with hiredis >= 0.1.4. You're running hiredis %s. Please consider upgrading.   *   $s   
    zConnection closed by server.c                   @   s*   e Zd ZdZdd Zdd Zd
ddZd	S )Encoderz=Encode strings to bytes-like and decode bytes-like to stringsc                 C   s   || _ || _|| _d S Nencodingencoding_errorsdecode_responses)selfr0   r1   r2    r4   H/var/www/html/Ranjet/env/lib/python3.9/site-packages/redis/connection.py__init__b   s    zEncoder.__init__c                 C   s   t |ttfr|S t |tr&tdnTt |tr>t| }n<t |tt	frZt
| }n t |tszt|j}td| t |tr|| 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.zLInvalid input of type: '%s'. Convert to a bytes, string, int or float first.)
isinstancebytes
memoryviewboolr   floatreprencodeintr	   strr   type__name__r   r0   r1   )r3   valuetypenamer4   r4   r5   r=   g   s     





zEncoder.encodeFc                 C   s:   | j s
|r6t|tr| }t|tr6|| j| j}|S )z:Return a unicode string from the bytes-like representation)r2   r7   r9   tobytesr8   decoder0   r1   )r3   rB   forcer4   r4   r5   rE   }   s    


zEncoder.decodeN)F)rA   
__module____qualname____doc__r6   r=   rE   r4   r4   r4   r5   r-   _   s   r-   c                   @   s4   e Zd Zeeeeedeeee	ee
dZdd ZdS )
BaseParser)z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)ZERRZ	EXECABORTZLOADINGZNOSCRIPTZREADONLYZNOAUTHZNOPERMc                 C   s\   | dd }|| jv rT|t|d d }| j| }t|trL||t}||S t|S )zParse an error response r      N)splitEXCEPTION_CLASSESlenr7   dictgetr%   )r3   responseZ
error_codeZexception_classr4   r4   r5   parse_error   s    


zBaseParser.parse_errorN)rA   rG   rH   r   r   r   r   r   r"   r#   r!   rN   rS   r4   r4   r4   r5   rJ      s   rJ   c                   @   sX   e Zd Zdd Zedd ZdedfddZd	d
 Zdd Z	dd Z
dd Zdd ZdS )SocketBufferc                 C   s,   || _ || _|| _t | _d| _d| _d S Nr   )_socksocket_read_sizesocket_timeoutioBytesIO_bufferbytes_written
bytes_read)r3   socketrW   rX   r4   r4   r5   r6      s    
zSocketBuffer.__init__c                 C   s   | j | j S r.   )r\   r]   r3   r4   r4   r5   length   s    zSocketBuffer.lengthNTc              
   C   s  | j }| j}| j}|| j d}|tu}zLz|r>|| t| j |}	t|	t	rht
|	dkrhtt||	 t
|	}
|  j|
7  _||
7 }|d ur||krq>W W |r|| j dS  tjy   |rtdY W |r|| j dS  tyb } z^t|jd}|s>|j|kr>W Y d }~W |r:|| j dS td|jf W Y d }~n
d }~0 0 W |r|| j n|r|| j 0 d S Nr   TzTimeout reading from socketFz#Error while reading from socket: %s)rV   rW   r[   seekr\   SENTINEL
settimeoutr   r7   r8   rO   r   SERVER_CLOSED_CONNECTION_ERRORwriterX   r^   timeoutr&   NONBLOCKING_EXCEPTIONS#NONBLOCKING_EXCEPTION_ERROR_NUMBERSrQ   	__class__errnoargs)r3   r`   rh   raise_on_timeoutsockrW   bufmarkercustom_timeoutdataZdata_lengthexallowedr4   r4   r5   _read_from_socket   sV    

zSocketBuffer._read_from_socketc                 C   s   t | jp| j|ddS )NFrh   rn   )r:   r`   rv   r3   rh   r4   r4   r5   can_read   s
    
zSocketBuffer.can_readc                 C   sn   |d }|| j kr"| || j   | j| j | j|}|  jt|7  _| j| jkrb|   |d d S )Nr)   )	r`   rv   r[   rc   r]   readrO   r\   purge)r3   r`   rs   r4   r4   r5   r{      s    
zSocketBuffer.readc                 C   st   | j }|| j | }|tsB|   || j | }q|  jt|7  _| j| jkrh| 	  |d d S )Nrz   )
r[   rc   r]   readlineendswithSYM_CRLFrv   rO   r\   r|   )r3   rp   rs   r4   r4   r5   r}      s    

zSocketBuffer.readlinec                 C   s&   | j d | j   d| _d| _d S rU   )r[   rc   truncater\   r]   r_   r4   r4   r5   r|     s    
zSocketBuffer.purgec                 C   s:   z|    | j  W n ty(   Y n0 d | _d | _d S r.   )r|   r[   close	ExceptionrV   r_   r4   r4   r5   r     s    zSocketBuffer.close)rA   rG   rH   r6   propertyr`   rd   rv   ry   r{   r}   r|   r   r4   r4   r4   r5   rT      s   


+rT   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )PythonParserzPlain Python parsing classc                 C   s   || _ d | _d | _d | _d S r.   )rW   encoderrV   r[   r3   rW   r4   r4   r5   r6   $  s    zPythonParser.__init__c                 C   s$   z|    W n ty   Y n0 d S r.   on_disconnectr   r_   r4   r4   r5   __del__*  s    zPythonParser.__del__c                 C   s(   |j | _ t| j | j|j| _|j| _dS )zCalled when the socket connectsN)rV   rT   rW   rX   r[   r   r3   
connectionr4   r4   r5   
on_connect0  s    zPythonParser.on_connectc                 C   s*   d| _ | jdur | j  d| _d| _dS )z"Called when the socket disconnectsN)rV   r[   r   r   r_   r4   r4   r5   r   8  s
    

zPythonParser.on_disconnectc                 C   s   | j o| j |S r.   )r[   ry   rx   r4   r4   r5   ry   @  s    zPythonParser.can_readc                    s   j  }|stt|d d |dd   }}|dvrDtd| |dkrpt|} |}t|trl||S |dkrznn|dkrt|}n\|dkrt	|}|dkrd S  j 
|}n2|d	krt	|}|dkrd S  fd
dt|D }t|tr  j|}|S )NrL   )   -   +   :r+   r*   zProtocol Error: %rr   r   r   r+   rb   r*   c                    s   g | ]}   qS r4   )read_response).0ir_   r4   r5   
<listcomp>k  r,   z.PythonParser.read_response.<locals>.<listcomp>)r[   r}   r   rf   r    r
   rS   r7   r	   r>   r{   r   r8   r   rE   )r3   rawbyterR   errorr`   r4   r_   r5   r   C  s:    



zPythonParser.read_responseN)
rA   rG   rH   rI   r6   r   r   r   ry   r   r4   r4   r4   r5   r   "  s   r   c                   @   sN   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	dfddZ
dd ZdS )HiredisParserz*Parser class for connections using Hiredisc                 C   s$   t std|| _tr t|| _d S )NzHiredis is not installed)r'   r$   rW   HIREDIS_USE_BYTE_BUFFER	bytearrayr[   r   r4   r4   r5   r6   s  s
    zHiredisParser.__init__c                 C   s$   z|    W n ty   Y n0 d S r.   r   r_   r4   r4   r5   r   {  s    zHiredisParser.__del__c                 C   sh   |j | _ |j| _t| jd}ts(t|d< |jjr<|jj	|d< t
rL|jj|d< tjf i || _d| _d S )N)ZprotocolError
replyErrorr   r0   errorsF)rV   rX   _socket_timeoutr    rS    HIREDIS_SUPPORTS_CALLABLE_ERRORSr%   r   r2   r0    HIREDIS_SUPPORTS_ENCODING_ERRORSr1   hiredisReader_reader_next_response)r3   r   kwargsr4   r4   r5   r     s    zHiredisParser.on_connectc                 C   s   d | _ d | _d| _d S )NF)rV   r   r   r_   r4   r4   r5   r     s    zHiredisParser.on_disconnectc                 C   s@   | j stt| jdu r<| j  | _| jdu r<| j|ddS dS )NFrw   T)r   r   rf   r   getsread_from_socketrx   r4   r4   r5   ry     s    

zHiredisParser.can_readTc           	   
   C   s  | j }|tu}zVz|r"|| trXt| j | j}|dkrDtt| j	| jd| n8t
| j | j}t|tr|t|dkrtt| j	| W W |r|| j dS  tjy   |rtdY W |r|| j dS  tyP } z^t|jd}|s,|j|kr,W Y d }~W |r(|| j dS td|jf W Y d }~n
d }~0 0 W |r||| j n|rz|| j 0 d S ra   )rV   rd   re   r   r   r[   r   rf   r   feedr   rW   r7   r8   rO   r   r^   rh   r&   ri   rj   rQ   rk   rl   rm   )	r3   rh   rn   ro   rr   Zbufflenbufferrt   ru   r4   r4   r5   r     sN    
zHiredisParser.read_from_socketc                 C   s   | j stt| jdur(| j}d| _|S | j  }|du rN|   | j  }q2tst|trn| 	|j
d }n4t|tr|rt|d tr| 	|d j
d |d< t|tr|n$t|tr|rt|d tr|d |S )NFr   )r   r   rf   r   r   r   r   r7   r%   rS   rm   list)r3   rR   r4   r4   r5   r     s0    



zHiredisParser.read_responseN)rA   rG   rH   rI   r6   r   r   r   ry   rd   r   r   r4   r4   r4   r5   r   q  s   &r   c                   @   s   e Zd ZdZddddddddddddded	dddfd
dZdd Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zd d! Zd/d#d$Zd%d& Zd0d'd(Zd)d* Zd+d, Zd-d. ZdS )1
Connectionz4Manages TCP communication to and from a Redis server	localhost  r   NFutf-8strict   c                 C   s   t  | _|| _t|| _|| _|| _|| _|| _	|| _
|p>|| _|| _|pNi | _|	| _|
| _|| _d| _t|||| _d | _||d| _g | _d| _d S Nr   )rW   ip  )osgetpidpidhostr>   portdbusernameclient_namepasswordrX   socket_connect_timeoutsocket_keepalivesocket_keepalive_optionssocket_typeretry_on_timeouthealth_check_intervalnext_health_checkr-   r   rV   _parser_connect_callbacks_buffer_cutoff)r3   r   r   r   r   rX   r   r   r   r   r   r0   r1   r2   parser_classrW   r   r   r   r4   r4   r5   r6     s(    



zConnection.__init__c                 C   s(   d dd |  D }d| jj|f S )N,c                 S   s   g | ]\}}d ||f qS )z%s=%sr4   )r   kvr4   r4   r5   r     r,   z'Connection.__repr__.<locals>.<listcomp>%s<%s>)joinrepr_piecesrk   rA   )r3   Z	repr_argsr4   r4   r5   __repr__  s    zConnection.__repr__c                 C   s6   d| j fd| jfd| jfg}| jr2|d| jf |S )Nr   r   r   r   )r   r   r   r   appendr3   piecesr4   r4   r5   r     s    zConnection.repr_piecesc                 C   s$   z|    W n ty   Y n0 d S r.   )
disconnectr   r_   r4   r4   r5   r     s    zConnection.__del__c                 C   s   | j | d S r.   )r   r   )r3   callbackr4   r4   r5   register_connect_callback$  s    z$Connection.register_connect_callbackc                 C   s
   g | _ d S r.   )r   r_   r4   r4   r5   clear_connect_callbacks'  s    z"Connection.clear_connect_callbacksc              
   C   s   | j r
dS z|  }W nN tjy2   tdY n4 tjyd } zt| |W Y d}~n
d}~0 0 || _ z|   W n t	y   | 
   Y n0 | jD ]}||  qdS )z5Connects to the Redis server if not already connectedNzTimeout connecting to server)rV   _connectr^   rh   r&   r   r   _error_messager   r$   r   r   )r3   ro   er   r4   r4   r5   connect*  s     $
zConnection.connectc                 C   s  d}t | j| j| jt jD ]}|\}}}}}d}zt  |||}|t jt jd | j	r|t j
t jd t| jD ]\}	}
|t j|	|
 qv|| j || || j |W   S  t jy } z |}|dur|  W Y d}~qd}~0 0 q|dur|t ddS )zCreate a TCP socket connectionNrL   z)socket.getaddrinfo returned an empty list)r^   getaddrinfor   r   r   SOCK_STREAM
setsockoptIPPROTO_TCPTCP_NODELAYr   
SOL_SOCKETSO_KEEPALIVEr   r   re   r   r   rX   r   r   )r3   errresfamilysocktypeproto	canonnameZsocket_addressro   r   r   _r4   r4   r5   r   B  s0    

 
zConnection._connectc                 C   sJ   t |jdkr&d| j| j|jd f S d|jd | j| j|jd f S d S )NrL   zError connecting to %s:%s. %s.r   z!Error %s connecting to %s:%s. %s.)rO   rm   r   r   r3   	exceptionr4   r4   r5   r   j  s    zConnection._error_messagec                 C   s   | j |  | js| jr| jr0| j| jp*df}n| jf}| jdg|R ddi z|  }W n, ty   | jd| jdd |  }Y n0 t|dkrtd| j	r| dd	| j	 t|  dkrt
d
| jr| d| j t|  dkrt
ddS )z=Initialize the connection, authenticate and select a database ZAUTHcheck_healthFr   OKzInvalid Username or PasswordZCLIENTZSETNAMEzError setting client nameZSELECTzInvalid DatabaseN)r   r   r   r   send_commandr   r   r
   r   r   r   r   )r3   Z	auth_argsZauth_responser4   r4   r5   r   t  s*    zConnection.on_connectc                 C   sb   | j   | jdu rdS z*t | jkr6t| jtj | j	  W n tj
yV   Y n0 d| _dS )z!Disconnects from the Redis serverN)r   r   rV   r   r   r   r   r^   	SHUT_RDWRr   r   r_   r4   r4   r5   r     s    

zConnection.disconnectc              	   C   s   | j rt | jkrz*| jddd t|  dkr:tdW nD ttfy   |   | jddd t|  dkr|tdY n0 dS )z3Check the health of the connection with a PING/PONGZPINGFr   ZPONGz#Bad response from PING health checkN)	r   r   r   r   r
   r   r   r&   r   r_   r4   r4   r5   r     s    zConnection.check_healthTc              
   C   s   | j s|   |r|   z*t|tr,|g}|D ]}t| j | q0W n tjyh   |   t	dY n tj
y } zX|   t|jdkrd|jd  }}n|jd }|jd }td||f W Y d}~n$d}~0  ty   |    Y n0 dS )z2Send an already packed command to the Redis serverzTimeout writing to socketrL   UNKNOWNr   z%Error %s while writing to socket. %s.N)rV   r   r   r7   r?   r   r^   rh   r   r&   r   rO   rm   r   BaseException)r3   commandr   itemr   rl   errmsgr4   r4   r5   send_packed_command  s0    


zConnection.send_packed_commandc                 O   s    | j | j| |ddd dS )z+Pack and send a command to the Redis serverr   Tr   N)r   pack_commandrQ   )r3   rm   r   r4   r4   r5   r     s    
zConnection.send_commandc                 C   s$   | j }|s|   | j }| j|S )z8Poll the socket to see if there's data that can be read.)rV   r   r   ry   )r3   rh   ro   r4   r4   r5   ry     s
    zConnection.can_readc              
   C   s   z| j  }W n tjy>   |   td| j| jf Y n` tjy } z,|   t	d| j| j|j
f W Y d}~n$d}~0  ty   |    Y n0 | jrt | j | _t|tr||S )z0Read the response from a previously sent commandzTimeout reading from %s:%sz#Error while reading from %s:%s : %sN)r   r   r^   rh   r   r&   r   r   r   r   rm   r   r   r   r   r7   r%   )r3   rR   r   r4   r4   r5   r     s(    


zConnection.read_responsec              	   G   s  g }t |d tr4t|d   |dd  }n(d|d v r\t|d  |dd  }tttt	| t
f}| j}t| jj|D ]|}t	|}t	||ks||kst |trt|tt| t
f}|| || t
}qt|tt| t
|t
f}q|| |S )z2Pack a series of arguments into the Redis protocolr   rL   N    )r7   r   tupler=   rM   	SYM_EMPTYr   SYM_STARr?   rO   r   r   r   r   r9   
SYM_DOLLARr   )r3   rm   outputZbuffbuffer_cutoffargZ
arg_lengthr4   r4   r5   r     s2    "


zConnection.pack_commandc           	      C   s   g }g }d}| j }|D ]~}| j| D ]n}t|}||ksJ||ksJt|trb|t| d}g }||kstt|tr|| q$|| ||7 }q$q|r|t| |S )z.Pack multiple commands into the Redis protocolr   )r   r   rO   r7   r9   r   r   r   )	r3   commandsr   r   Zbuffer_lengthr   cmdchunkZchunklenr4   r4   r5   pack_commands  s(    
zConnection.pack_commands)T)r   )rA   rG   rH   rI   DefaultParserr6   r   r   r   r   r   r   r   r   r   r   r   r   r   ry   r   r   r   r4   r4   r4   r5   r     s4   

(
'

"r   c                       s*   e Zd Zd fdd	Z fddZ  ZS )	SSLConnectionNrequiredFc                    s   t stdtt| jf i | || _|| _|d u r>tj}n8t	|t
rvtjtjtjd}||vrntd| || }|| _|| _|| _d S )Nz$Python wasn't built with SSL support)noneoptionalr  z-Invalid SSL Certificate Requirements Flag: %s)ssl_availabler$   superr   r6   keyfilecertfilessl	CERT_NONEr7   r   CERT_OPTIONALCERT_REQUIRED	cert_reqsca_certscheck_hostname)r3   Zssl_keyfileZssl_certfileZssl_cert_reqsZssl_ca_certsssl_check_hostnamer   Z	CERT_REQSrk   r4   r5   r6   6  s,    
zSSLConnection.__init__c                    s   t t|  }ttdrrt }| j|_| j|_| j	rN| j
rN|j| j	| j
d | jr`|| j t||| jd}ntt|| j| j
| j	| jd}|S )z Wrap the socket with SSL supportcreate_default_context)r  r  )server_hostname)r  r  r  r  )r  r   r   hasattrr  r  r  r  verify_moder  r  load_cert_chainr  load_verify_locationsr   r   )r3   ro   contextr  r4   r5   r   Q  s(    
zSSLConnection._connect)NNr  NF)rA   rG   rH   r6   r   __classcell__r4   r4   r  r5   r   4  s
      r   c                   @   sH   e Zd Zdddddddddedddfdd	Zd
d Zdd Zdd ZdS )UnixDomainSocketConnectionr   r   Nr   r   Fr   c                 C   sp   t  | _|| _|| _|| _|| _|| _|| _|	| _	|| _
d| _t|||| _d | _|
|d| _g | _d| _d S r   )r   r   r   pathr   r   r   r   rX   r   r   r   r-   r   rV   r   r   r   )r3   r  r   r   r   rX   r0   r1   r2   r   r   rW   r   r   r4   r4   r5   r6   l  s    
z#UnixDomainSocketConnection.__init__c                 C   s.   d| j fd| jfg}| jr*|d| jf |S )Nr  r   r   )r  r   r   r   r   r4   r4   r5   r     s    z&UnixDomainSocketConnection.repr_piecesc                 C   s,   t  t jt j}|| j || j |S )z&Create a Unix domain socket connection)r^   AF_UNIXr   re   rX   r   r  )r3   ro   r4   r4   r5   r     s    z#UnixDomainSocketConnection._connectc                 C   sB   t |jdkr"d| j|jd f S d|jd | j|jd f S d S )NrL   z(Error connecting to unix socket: %s. %s.r   z+Error %s connecting to unix socket: %s. %s.)rO   rm   r  r   r4   r4   r5   r     s    z)UnixDomainSocketConnection._error_message)rA   rG   rH   r   r6   r   r   r   r4   r4   r4   r5   r  j  s   
	r  )0FFALSENNOc                 C   s6   | d u s| dkrd S t | tr.|  tv r.dS t| S )Nr   F)r7   r   upperFALSE_STRINGSr:   )rB   r4   r4   r5   to_bool  s
    r#  )rX   r   r   r   max_connectionsr   r  c                   @   sv   e Zd ZdZedddZedfddZdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd ZdddZdS )ConnectionPoolzGeneric connection poolNFc              
   K   s>  t |}i }tt|jD ]r\}}|rt|dkrt|}|rz||d ||< W q ttfy|   t	
td|  Y q0 q|d ||< q|r|jrt|jnd}	|jrt|jnd}
|jrt|jnd}|jrt|jnd}n |jpd}	|jpd}
|j}|j}|jdkr&||	|
|td n|jdv r||t|jpDd|	|
d d	|vr|rzt|d
d|d	< W n ttfy   Y n0 |jdkrt|d< ndd}td| t|d	|pd|d	< || d|v r
t	
td |d|d< d|v r0t	
td |d|d< | f 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://``
          <https://www.iana.org/assignments/uri-schemes/prov/redis>`_ creates a
          normal TCP socket connection
        - ```rediss://``
          <https://www.iana.org/assignments/uri-schemes/prov/rediss>`_ creates
          a SSL wrapped TCP socket connection
        - ``unix://`` creates a Unix Domain Socket connection

        There are several ways to specify a database number. The parse function
        will return the first specified option:
            1. A ``db`` querystring option, e.g. redis://localhost?db=0
            2. If using the redis:// scheme, the path argument of the url, e.g.
               redis://localhost/0
            3. The ``db`` argument to this function.

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

        The ``decode_components`` argument allows this function to work with
        percent-encoded URLs. If this argument is set to ``True`` all ``%xx``
        escapes will be replaced by their single-character equivalents after
        the URL has been parsed. This only applies to the ``hostname``,
        ``path``, ``username`` and ``password`` components.

        Any additional querystring arguments and keyword arguments will be
        passed along to the ConnectionPool class's initializer. The querystring
        arguments ``socket_connect_timeout`` and ``socket_timeout`` if supplied
        are parsed as float values. The arguments ``socket_keepalive`` and
        ``retry_on_timeout`` are parsed to boolean values that accept
        True/False, Yes/No values to indicate state. Invalid types cause a
        ``UserWarning`` to be raised. In the case of conflicting arguments,
        querystring arguments always win.

        r   z)Invalid value for `%s` in connection URL.Nunix)r   r   r  connection_class)Zredisredissr   )r   r   r   r   r   /r   r(  r'  z, )zredis://z	rediss://zunix://z8Redis URL must specify one of the following schemes (%s)charsetz/"charset" is deprecated. Use "encoding" insteadr0   r   z5"errors" is deprecated. Use "encoding_errors" insteadr1   )r   r   r   queryrO   URL_QUERY_ARGUMENT_PARSERSrQ   	TypeError
ValueErrorwarningswarnUserWarningr   r   r   r  hostnameschemeupdater  r>   r   replaceAttributeErrorr   r   DeprecationWarningpop)clsurlr   Zdecode_componentsr   Zurl_optionsnamerB   parserr   r   r  r2  Zvalid_schemesr4   r4   r5   from_url  sx    .



	




zConnectionPool.from_urlc                 K   sN   |pd}t |ttfr|dk r&td|| _|| _|| _t | _	| 
  dS )a  
        Create a connection pool. If max_connections is set, then this
        object raises redis.ConnectionError when the pool's limit is reached.

        By default, TCP connections are created unless connection_class is
        specified. Use redis.UnixDomainSocketConnection for unix sockets.

        Any additional keyword arguments are passed to the constructor of
        connection_class.
        l        r   z,"max_connections" must be a positive integerN)r7   r>   r	   r.  r'  connection_kwargsr$  	threadingLock
_fork_lockreset)r3   r'  r$  r>  r4   r4   r5   r6   0  s    

zConnectionPool.__init__c                 C   s$   dt | jt| jf i | jf S )Nr   )r@   rA   r<   r'  r>  r_   r4   r4   r5   r   O  s    zConnectionPool.__repr__c                 C   s,   t  | _d| _g | _t | _t | _	d S rU   )
r?  r@  _lock_created_connections_available_connectionsset_in_use_connectionsr   r   r   r_   r4   r4   r5   rB  U  s
    
zConnectionPool.resetc                 C   sx   | j t krtt d }d}t |k r:| jd}|rq:q|sBtz$| j t krZ|   W | j  n| j  0 d S )N   F)	r   r   r   r   rA  acquirer   rB  release)r3   Z
timeout_atZacquiredr4   r4   r5   	_checkpidf  s    #


zConnectionPool._checkpidc              	   O   s   |    | jF z| j }W n ty8   |  }Y n0 | j| W d   n1 sZ0    Y  zT|  z|	 rt
dW n2 t
y   |  |  |	 rt
dY n0 W n ty   | |  Y n0 |S )zGet a connection from the poolNConnection has dataConnection not ready)rK  rC  rE  r8  
IndexErrormake_connectionrG  addr   ry   r   r   r   rJ  r3   command_namekeysoptionsr   r4   r4   r5   get_connection  s*    *
zConnectionPool.get_connectionc                 C   s,   | j }t|dd|dd|dddS )z,Return an encoder based on encoding settingsr0   r   r1   r   r2   Fr/   )r>  r-   rQ   )r3   r   r4   r4   r5   get_encoder  s    


zConnectionPool.get_encoderc                 C   s4   | j | jkrtd|  j d7  _ | jf i | jS )zCreate a new connectionzToo many connectionsrL   )rD  r$  r   r'  r>  r_   r4   r4   r5   rO    s    zConnectionPool.make_connectionc              	   C   s   |    | jr z| j| W n ty2   Y n0 | |rL| j| n&|  jd8  _|	  W d   dS W d   n1 s0    Y  dS )z(Releases the connection back to the poolrL   N)
rK  rC  rG  removeKeyErrorowns_connectionrE  r   rD  r   r   r4   r4   r5   rJ    s    
zConnectionPool.releasec                 C   s   |j | j kS r.   )r   r   r4   r4   r5   rY    s    zConnectionPool.owns_connectionTc                 C   s^   |    | j< |r$t| j| j}n| j}|D ]}|  q.W d   n1 sP0    Y  dS )z
        Disconnects connections in the pool

        If ``inuse_connections`` is True, disconnect connections that are
        current in use, potentially by other threads. Otherwise only disconnect
        connections that are idle in the pool.
        N)rK  rC  r   rE  rG  r   )r3   Zinuse_connectionsconnectionsr   r4   r4   r5   r     s    zConnectionPool.disconnect)NF)T)rA   rG   rH   rI   classmethodr=  r   r6   r   rB  rK  rU  rV  rO  rJ  rY  r   r4   r4   r4   r5   r%    s   z6!	r%  c                       sR   e Zd ZdZddeef fdd	Zdd Zdd	 Zd
d Z	dd Z
dd Z  ZS )BlockingConnectionPoola6  
    Thread-safe blocking connection pool::

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

    It performs the same function as the default
    ``:py:class: ~redis.connection.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.exceptions.ConnectionError`` (as the default
    ``:py:class: ~redis.connection.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      c                    s,   || _ || _tt| jf ||d| d S )N)r'  r$  )queue_classrh   r  r\  r6   )r3   r$  rh   r'  r_  r>  r  r4   r5   r6     s    zBlockingConnectionPool.__init__c                 C   sL   |  | j| _z| jd  W q ty4   Y q8Y q0 qg | _t | _d S r.   )	r_  r$  pool
put_nowaitr   _connectionsr   r   r   r_   r4   r4   r5   rB  %  s    zBlockingConnectionPool.resetc                 C   s"   | j f i | j}| j| |S )zMake a fresh connection.)r'  r>  rb  r   r   r4   r4   r5   rO  =  s    z&BlockingConnectionPool.make_connectionc                 O   s   |    d}z| jjd| jd}W n ty<   tdY n0 |du rN|  }zT|  z| rjtdW n2 ty   |	  |  | rtdY n0 W n t
y   | |  Y n0 |S )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.
        NT)blockrh   zNo connection available.rL  rM  )rK  r`  rQ   rh   r   r   rO  r   ry   r   r   rJ  rQ  r4   r4   r5   rU  C  s,    
z%BlockingConnectionPool.get_connectionc                 C   sR   |    | |s*|  | jd dS z| j| W n tyL   Y n0 dS )z)Releases the connection back to the pool.N)rK  rY  r   r`  ra  r   r   r4   r4   r5   rJ  w  s    
zBlockingConnectionPool.releasec                 C   s    |    | jD ]}|  qdS )z(Disconnects all connections in the pool.N)rK  rb  r   r   r4   r4   r5   r     s    
z!BlockingConnectionPool.disconnect)rA   rG   rH   rI   r   r   r6   rB  rO  rU  rJ  r   r  r4   r4   r  r5   r\    s    4r\  )_
__future__r   Zdistutils.versionr   	itertoolsr   r   rl   rY   r   r^   r?  r/  Zredis._compatr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zredis.exceptionsr   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   Zredis.utilsr'   r  r  ImportErrorEWOULDBLOCKrj   r  r(   SSLWantWriteErrorSSLErrorr   r   rS  ri   r   __version__Zhiredis_versionr   ZHIREDIS_SUPPORTS_BYTE_BUFFERr   msgr0  r   r   r   r   r   rf   objectrd   r-   rJ   rT   r   r   r   r   r   r  r"  r#  r;   r>   r,  r%  r\  r4   r4   r4   r5   <module>   s   T@


	





(#xOz  E63	  H