
    )Jf\              
          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mZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZmZmZmZmZmZ d dlmZmZmZ dd	lmZmZmZmZ dd
l m!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- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 e2rd dl7Z7dZ8dZ9dZ:dZ;dZ< e=            Z>eeeeef                  e?d<   e2reZ@neZ@ G d d          ZA G d d          ZB G d d          ZC G d deC          ZD G d deD          ZE G d d eC          ZFd!ZGd" ZHeIeJeJeHeHeKeIeIeHd#	ZLd$ ZM G d% d&          ZN G d' d(eN          ZOdS ))    N)abstractmethod)chain)EmptyFull	LifoQueue)time)AnyCallableListOptionalTypeUnion)parse_qsunquoteurlparse   )Encoder_HiredisParser_RESP2Parser_RESP3Parser)	NoBackoff)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorChildDeadlockedErrorConnectionError	DataError
RedisErrorResponseErrorTimeoutError)Retry)CRYPTOGRAPHY_AVAILABLEHIREDIS_AVAILABLEHIREDIS_PACK_AVAILABLESSL_AVAILABLEget_lib_versionstr_if_bytes   *   $s   
       DefaultParserc                       e Zd ZdefdZdS )HiredisRespSerializerargsc                 "   g }t          |d         t                    rEt          |d                                                                                   |dd         z   }n<d|d         v r2t          |d                                                   |dd         z   }	 |                    t          j        |                     nG# t          $ r: t          j
                    \  }}}t          |                              |          w xY w|S 2Pack a series of arguments into the Redis protocolr   r   N    )
isinstancestrtupleencodesplitappendhiredispack_command	TypeErrorsysexc_infor   with_traceback)selfr0   output_value	tracebacks         S/home/alex/cs2snipeproduction/venv/lib/python3.11/site-packages/redis/connection.pypackzHiredisRespSerializer.pack:   s    d1gs## 	5a))//1122T!""X=DDT!W__a))DH4D	=MM'.t445555 	= 	= 	="%,..AuiE""11)<<<	= s    'C ADN)__name__
__module____qualname__r   rG    r+   rF   r/   r/   9   s/        $      r+   r/   c                       e Zd ZddZd ZdS )PythonRespSerializerreturnNc                 "    || _         || _        d S N)_buffer_cutoffr8   )rA   buffer_cutoffr8   s      rF   __init__zPythonRespSerializer.__init__L   s    +r+   c           	      \   g }t          |d         t                    rEt          |d                                                                                   |dd         z   }n<d|d         v r2t          |d                                                   |dd         z   }t
                              t          t          t          |                                                    t          f          }| j
        }t          | j        |          D ]}t          |          }t          |          |k    s||k    st          |t                    ryt
                              |t          t          |                                          t          f          }|                    |           |                    |           t          }t
                              |t          t          |                                          t          |t          f          }	|                    |           |S r2   )r5   r6   r7   r8   r9   	SYM_EMPTYjoinSYM_STARlenSYM_CRLFrQ   map
memoryview
SYM_DOLLARr:   )rA   r0   rB   buffrR   arg
arg_lengths          rF   rG   zPythonRespSerializer.packP   s    d1gs## 	5a))//1122T!""X=DDT!W__a))DH4D~~xSYY)>)>)@)@(KLL+t{D)) 	 	C SJD		M))--c:.. . !~~:s:'='='?'?J  d###c""" ~~"J..00  	 	 	dr+   rN   N)rH   rI   rJ   rS   rG   rK   r+   rF   rM   rM   K   s7           + + + + +r+   rM   c            *       *   e Zd ZdZdddddedddedddd e            ddddd	dfd
edee	         dee
         dee
         dede	de	dedededee	         dee	         dee	         dee	         deedf         deeg df                  dee         dee         deeg df                  f&dZd Zed             Zd  Zd! Zd" Zd# Zd$ Zd% Zed&             Zed'             Zed(             Zd) Zd* Zd+ Zd, Z d- Z!d6d/Z"d0 Z#d7d1Z$	 d8d.dd2d3Z%d4 Z&d5 Z'dS )9AbstractConnectionz0Manages communication to and from a Redis serverr   NFutf-8stricti   zredis-pyr,   dbpasswordsocket_timeoutsocket_connect_timeoutretry_on_timeoutencodingencoding_errorsdecode_responsessocket_read_sizehealth_check_intervalclient_namelib_namelib_versionusernameretryredis_connect_funccredential_providerprotocolcommand_packerc                 J   |s|r|t          d          t          j                    | _        || _        || _        || _        || _        || _        || _	        || _
        || _        ||}|| _        || _        |t          u rg }|r|                    t                      || _        |s|rX|"t%          t'                      d          | _        nt+          j        |          | _        | j                            |           n!t%          t'                      d          | _        || _        d| _        || _        t7          |||	          | _        d| _        || _        |                     |
           g | _         d| _!        	 tE          |          }n/# tF          $ r
 tH          }Y ntJ          $ r tM          d          w xY w|dk     s|dk    rtM          d	          || _'        n'# |dk     s|dk    rtM          d	          || _'        w xY w| (                    |          | _)        dS )
a2  
        Initialize a new Connection.
        To specify a retry policy for specific errors, first set
        `retry_on_error` to a list of the error/s to retry on, then set
        `retry` to a valid `Retry` object.
        To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
        Nz'username' and 'password' cannot be passed along with 'credential_provider'. Please provide only one of the following arguments: 
1. 'password' and (optional) 'username'
2. 'credential_provider'r   r   ip  zprotocol must be an integerr,      zprotocol must be either 2 or 3)*r   osgetpidpidre   ro   rp   rq   ru   rf   rr   rg   rh   ri   SENTINELr:   r!   retry_on_errorr"   r   rs   copydeepcopyupdate_supported_errorsrn   next_health_checkrt   r   encoder_sock_socket_read_size
set_parser_connect_callbacksrQ   intr=   DEFAULT_RESP_VERSION
ValueErrorr   rv   _construct_command_packer_command_packer)rA   re   rf   rg   rh   ri   r~   rj   rk   rl   parser_classrm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   ps                          rF   rS   zAbstractConnection.__init__   sl   >  	 	&9&E+   9;;& &#6   ,!)%3"&<# 0X%%N 	0!!,///, 		/N 		/}"9;;22

 "]511
J..~>>>>y{{A..DJ%:"!""4x:JKK
!1%%%"$"
	HAA 	% 	% 	%$AAA 	A 	A 	A!"?@@@	A 1uuA%&FGGGDMM 1uuA%&FGGGDM#==nMMs*    F G" F<!G" #F<<G" "$Hc                     d                     d |                                 D                       }| j        j         d| dS )N,c                 "    g | ]\  }}| d | S )=rK   ).0kvs      rF   
<listcomp>z/AbstractConnection.__repr__.<locals>.<listcomp>   s&    HHHTQjjQjjHHHr+   <>)rV   repr_pieces	__class__rH   )rA   	repr_argss     rF   __repr__zAbstractConnection.__repr__   sJ    HHHHT5E5E5G5GHHHII	.)88I8888r+   c                     d S rP   rK   rA   s    rF   r   zAbstractConnection.repr_pieces       r+   c                 R    	 |                                   d S # t          $ r Y d S w xY wrP   )
disconnect	Exceptionr   s    rF   __del__zAbstractConnection.__del__   s?    	OO 	 	 	DD	s    
&&c                 r    ||S t           rt                      S t          | j        | j        j                  S rP   )r%   r/   rM   rQ   r   r8   )rA   packers     rF   r   z,AbstractConnection._construct_command_packer   s:    M# 	R(***'(;T\=PQQQr+   c                 x    t          j        |          }|| j        vr| j                            |           d S d S rP   )weakref
WeakMethodr   r:   )rA   callbackwms      rF   _register_connect_callbackz-AbstractConnection._register_connect_callback   sE    ))T,,,#**2..... -,r+   c                     	 | j                             t          j        |                     d S # t          $ r Y d S w xY wrP   )r   remover   r   r   )rA   r   s     rF   _deregister_connect_callbackz/AbstractConnection._deregister_connect_callback   sQ    	#**7+=h+G+GHHHHH 	 	 	DD	s   ,0 
>>c                 2     || j                   | _        dS )z
        Creates a new instance of parser_class with socket size:
        _socket_read_size and assigns it to the parser for the connection
        :param parser_class: The required parser class
        )rm   N)r   _parser)rA   r   s     rF   r   zAbstractConnection.set_parser   s     $|T5KLLLr+   c                 *     j         rdS 	  j                             fd fd          }nQ# t          j        $ r t          d          t          $ r'}t                               |                    d}~ww xY w| _         	  j	         
                                 n 	                                n## t          $ r                                    w xY wd  j        D              _         j        D ]} |            }|r |            dS )z5Connects to the Redis server if not already connectedNc                  ,                                      S rP   )_connectr   s   rF   <lambda>z,AbstractConnection.connect.<locals>.<lambda>	  s     r+   c                 .                         |           S rP   r   )errorrA   s    rF   r   z,AbstractConnection.connect.<locals>.<lambda>	  s    tu7M7M r+   zTimeout connecting to serverc                 &    g | ]} |            |S rK   rK   )r   refs     rF   r   z.AbstractConnection.connect.<locals>.<listcomp>   s#    "S"S"S3SSUU"S3"S"S"Sr+   )r   rs   call_with_retrysockettimeoutr!   OSErrorr   _error_messagert   
on_connectr   r   r   )rA   socker   r   s   `    rF   connectzAbstractConnection.connect  sp   : 	F	::--'''')M)M)M)M DD ~ 	? 	? 	?=>>> 	: 	: 	:!$"5"5a"8"8999	: 

	&.!!!! ''--- 	 	 	OO	 #T"S$2I"S"S"S* 	 	CsuuH 	 	s!   !. 'A<"A77A<1B9 9 Cc                     d S rP   rK   r   s    rF   r   zAbstractConnection._connect&  r   r+   c                     d S rP   rK   r   s    rF   _host_errorzAbstractConnection._host_error*  r   r+   c                     d S rP   rK   )rA   	exceptions     rF   r   z!AbstractConnection._error_message.  r   r+   c                    | j                             |            | j         }d}| j        s| j        s| j        r5| j        pt          | j        | j                  }|                                }|r| j        dvrt          | j         t                    rE| 
                    t                     |j        | j         _        | j                             |            t          |          dk    r
d|d         g} | j        d| j        dg|R   |                                 }np|r | j        dg|R dd	i 	 |                                 }nB# t           $ r5 |                     d|d
         d	           |                                 }Y nw xY wt#          |          dk    rt%          d          n| j        dvrt          | j         t                    rE| 
                    t                     |j        | j         _        | j                             |            |                     d| j                   |                                 }|                    d          | j        k    r-|                    d          | j        k    rt)          d          | j        rP|                     dd| j                   t#          |                                           dk    rt)          d          	 | j        r1|                     ddd| j                   |                                  n# t.          $ r Y nw xY w	 | j        r1|                     ddd| j                   |                                  n# t.          $ r Y nw xY w| j        rO|                     d| j                   t#          |                                           dk    rt)          d          dS dS )z=Initialize the connection, authenticate and select a databaseN)r,   2r   defaultr   HELLOAUTHcheck_healthFr   OKzInvalid Username or Passwords   protoprotozInvalid RESP versionCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTzInvalid Database)r   r   ru   rr   rf   r   get_credentialsrv   r5   r   r   r   EXCEPTION_CLASSESrX   send_commandread_responser   r(   r   getr   ro   rp   r    rq   re   )rA   parser	auth_argscred_providerresponseauth_responses         rF   r   zAbstractConnection.on_connect2  s"   %%%	# 	8 	8 	8( T5dmT]SS  &5577I  -	>h66$,55 .---171I.''---9~~""&	!5	Dgt}fIyIIII))++HH
  	> DfEyEEEuEEE5 $ 2 2 4 47 5 5 5
 !!&)B-e!LLL $ 2 2 4 45 M**d22)*HIII 3 ](**$,55 .---171I.''---gt}555))++HX&&$-77LL))T]::%&<===  	Ch	43CDDDD..0011T99%&ABBB	} %!!(Iz4=QQQ""$$$ 	 	 	D		 %!!(Iy$BRSSS""$$$ 	 	 	D	 7 	:h000D..0011T99%&8999	: 	:99s6   4E	 	<FF(8L! !
L.-L.28M+ +
M87M8c                 B   | j                                          | j        }d| _        |dS t          j                    | j        k    r1	 |                    t          j                   n# t          $ r Y nw xY w	 |
                                 dS # t          $ r Y dS w xY w)z!Disconnects from the Redis serverN)r   on_disconnectr   rz   r{   r|   shutdownr   	SHUT_RDWRr   close)rA   r0   	conn_socks      rF   r   zAbstractConnection.disconnect  s    ""$$$J	
F9;;$(""""6#34444   	OO 	 	 	DD	s$   	A) )
A65A6:B 
BBc                     |                      dd           t          |                                           dk    rt          d          dS )z Send PING, expect PONG in returnPINGFr   PONGz#Bad response from PING health checkN)r   r(   r   r   r   s    rF   
_send_pingzAbstractConnection._send_ping  sQ    &u555**,,--77!"GHHH 87r+   c                 .    |                                   dS )z Function to call when PING failsNr   )rA   r   s     rF   _ping_failedzAbstractConnection._ping_failed      r+   c                     | j         r>t                      | j        k    r)| j                            | j        | j                   dS dS dS )z3Check the health of the connection with a PING/PONGN)rn   r   r   rs   r   r   r   r   s    rF   r   zAbstractConnection.check_health  sT    % 	K$&&43I*I*IJ&&t8IJJJJJ	K 	K*I*Ir+   Tc                 r   | j         s|                                  |r|                                  	 t          |t                    r|g}|D ]}| j                             |           dS # t          j        $ r$ |                                  t          d          t          $ rq}|                                  t          |j                  dk    rd|j        d         }}n|j        d         }|j        d         }t          d| d| d          d}~wt          $ r |                                   w xY w)	z2Send an already packed command to the Redis serverzTimeout writing to socketr   UNKNOWNr   Error z while writing to socket. .N)r   r   r   r5   r6   sendallr   r   r   r!   r   rX   r0   r   BaseException)rA   commandr   itemr   errnoerrmsgs          rF   send_packed_commandz&AbstractConnection.send_packed_command  sk   z 	LLNNN 	 	'3'' $") ) )
""4(((() )~ 	< 	< 	<OO:;;; 	W 	W 	WOO16{{a )16!9vq	!"U5"U"UF"U"U"UVVV 	 	 	
 OO	s   7A, ,;D6'A,D#D6c                 v    |                       | j        j        | |                    dd                     dS )z+Pack and send a command to the Redis serverr   Tr   N)r   r   rG   r   )rA   r0   kwargss      rF   r   zAbstractConnection.send_command  sJ      %D %t,ND99 	! 	
 	
 	
 	
 	
r+   c                    | j         }|s|                                  |                                 }	 | j                            |          S # t
          $ r3}|                                  t          d| d|j                   d}~ww xY w)z8Poll the socket to see if there's data that can be read.Error while reading from z: N)	r   r   r   r   can_readr   r   r   r0   )rA   r   r   
host_errorr   s        rF   r   zAbstractConnection.can_read  s    z 	LLNNN%%''
	V<((111 	V 	V 	VOO!"Tj"T"TAF"T"TUUU	Vs   A 
B
.BB
)disconnect_on_errorpush_requestc                r   |                                  }	 | j        dv r$t          s| j                            ||          }n| j                            |          }n# t
          j        $ r) |r|                                  t          d|           t          $ r5}|r|                                  t          d| d|j                   d}~wt          $ r |r|                                   w xY w| j        rt                      | j        z   | _        t!          |t"                    r		 |# ~w xY w|S )z0Read the response from a previously sent command)3ry   )disable_decodingr   )r  zTimeout reading from r   z : N)r   rv   r$   r   r   r   r   r   r!   r   r   r0   r   rn   r   r   r5   r    )rA   r  r   r   r   r   r   s          rF   r   z AbstractConnection.read_response  s    %%''
	}((1B(<55%5L 6    <55GW5XX~ 	E 	E 	E" "!!!CzCCDDD 	 	 	" "!!!!GJGGqvGG    	 	 	 # "!!!	 % 	I%)VVd.H%HD"h.. 	s%   AA A C40C%C4/D1 1D4c                       | j         j        | S )r3   )r   rG   )rA   r0   s     rF   r<   zAbstractConnection.pack_command  s    (t#($//r+   c                    g }g }d}| j         }|D ]} | j        j        | D ]}t          |          }||k    s||k    st	          |t
                    r3|r-|                    t                              |                     d}g }||k    st	          |t
                    r|                    |           |                    |           ||z  }|r-|                    t                              |                     |S )z.Pack multiple commands into the Redis protocolr   )	rQ   r   rG   rX   r5   r[   r:   rU   rV   )	rA   commandsrB   piecesbuffer_lengthrR   cmdchunkchunklens	            rF   pack_commandsz AbstractConnection.pack_commands  s(   + 	. 	.C2-2C8 . .u::!M11-//!%44 0  >innV&<&<===$%MFm++z%/L/L+MM%((((MM%(((!X-MM!.$  	2MM)..00111r+   T)r   )F)(rH   rI   rJ   __doc__r}   r-   r'   r   r   r6   floatboolr   r	   r
   r   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   r  rK   r+   rF   rb   rb   ~   sj       66 "&*.26!&'!&" %%&%)",%4_%6%6"&"&;?<@"#7;-WN WNWN 3-WN !	WN
 !)WN WN WN WN WN WN  #WN c]WN 3-WN  c]!WN" 3-#WN$ S$Y%WN& %Xb$h%78'WN( &&89)WN* 3-+WN, !"d(!34-WN WN WN WNr9 9 9   ^  R R R/ / /
  M M M! ! !F   ^   ^   ^X: X: X:t  (I I I  K K K
   >
 
 
V V V V  , !, , , , ,\0 0 0    r+   rb   c                   F     e Zd ZdZ	 	 	 	 	 d fd	Zd Zd	 Zd
 Zd Z xZ	S )
Connectionz4Manages TCP communication to and from a Redis server	localhost  FNr   c                     || _         t          |          | _        || _        |pi | _        || _         t                      j        di | d S NrK   )hostr   portsocket_keepalivesocket_keepalive_optionssocket_typesuperrS   )rA   r  r  r  r  r  r   r   s          rF   rS   zConnection.__init__7  sY     	II	 0(@(FB%&""6"""""r+   c                     d| j         fd| j        fd| j        fg}| j        r|                    d| j        f           |S )Nr  r  re   ro   )r  r  re   ro   r:   rA   r  s     rF   r   zConnection.repr_piecesG  sL    49%	':T47OL 	=MM=$*:;<<<r+   c                    d}t          j        | j        | j        | j        t           j                  D ]<}|\  }}}}}d}	 t          j         |||          }|                    t           j        t           j        d           | j	        rk|                    t           j
        t           j        d           | j                                        D ]&\  }	}
|                    t           j        |	|
           '|                    | j                   |                    |           |                    | j                   |c S # t$          $ r#}|}||                                 Y d}~6d}~ww xY w||t%          d          )zCreate a TCP socket connectionNr   z)socket.getaddrinfo returned an empty list)r   getaddrinfor  r  r  SOCK_STREAM
setsockoptIPPROTO_TCPTCP_NODELAYr  
SOL_SOCKETSO_KEEPALIVEr  items
settimeoutrh   r   rg   r   r   )rA   errresfamilysocktyper   	canonnamesocket_addressr   r   r   rC   s               rF   r   zConnection._connectM  s   
 %Ity$"2F4F
 
 	! 	!C BE>FHeYD!}VXu== 2F4FJJJ ( BOOF$5v7JANNN $ = C C E E B B1(:AqAAAA  ;<<< ^,,,  3444 ! ! !#JJLLL!
 ?IABBBs   C=E
E.E))E.c                 $    | j          d| j         S )N:)r  r  r   s    rF   r   zConnection._host_errorv  s    )))di)))r+   c                 J   |                                  }t          |j                  dk    r5	 d| d|j        d          dS # t          $ r d|j        d          cY S w xY w	 d|j        d          d| d	|j        d          dS # t          $ r d|j        d          cY S w xY w)
Nr   zError connecting to z.                         r   r   zConnection Error: r   z connecting to . )r   rX   r0   AttributeErrorrA   r   r   s      rF   r   zConnection._error_messagey  s    %%''
y~!##@.j . ."*. . . .! @ @ @?IN1,=?????@@:Y^A. : :!: :%.^A%6: : : " @ @ @?IN1,=?????@s#   A AA#!B B"!B")r  r  FNr   
rH   rI   rJ   r  rS   r   r   r   r   __classcell__r   s   @rF   r  r  4  s        :: !%# # # # # #   'C 'C 'CR* * *@ @ @ @ @ @ @r+   r  c                   F     e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 d fd	Z fdZ xZS )SSLConnectionzManages SSL connections to and from the Redis server(s).
    This class extends the Connection class, adding SSL functionality, and making
    use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext)
    NrequiredFc                    t           st          d          || _        || _        |t          j        }nWt          |t                    rBt          j        t          j        t          j	        d}||vrt          d|           ||         }|| _
        || _        || _        || _        || _        || _        |	| _        |
| _        || _        || _         t)                      j        di | dS )ae  Constructor

        Args:
            ssl_keyfile: Path to an ssl private key. Defaults to None.
            ssl_certfile: Path to an ssl certificate. Defaults to None.
            ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required). Defaults to "required".
            ssl_ca_certs: The path to a file of concatenated CA certificates in PEM format. Defaults to None.
            ssl_ca_data: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates.
            ssl_check_hostname: If set, match the hostname during the SSL handshake. Defaults to False.
            ssl_ca_path: The path to a directory containing several CA certificates in PEM format. Defaults to None.
            ssl_password: Password for unlocking an encrypted private key. Defaults to None.

            ssl_validate_ocsp: If set, perform a full ocsp validation (i.e not a stapled verification)
            ssl_validate_ocsp_stapled: If set, perform a validation on a stapled ocsp response
            ssl_ocsp_context: A fully initialized OpenSSL.SSL.Context object to be used in verifying the ssl_ocsp_expected_cert
            ssl_ocsp_expected_cert: A PEM armoured string containing the expected certificate to be returned from the ocsp verification service.

        Raises:
            RedisError
        z$Python wasn't built with SSL supportN)noneoptionalr:  z+Invalid SSL Certificate Requirements Flag: rK   )r&   r   keyfilecertfilessl	CERT_NONEr5   r6   CERT_OPTIONALCERT_REQUIRED	cert_reqsca_certsca_dataca_pathcheck_hostnamecertificate_passwordssl_validate_ocspssl_validate_ocsp_stapledssl_ocsp_contextssl_ocsp_expected_certr  rS   )rA   ssl_keyfilessl_certfilessl_cert_reqsssl_ca_certsssl_ca_datassl_check_hostnamessl_ca_pathssl_passwordrJ  rK  rL  rM  r   	CERT_REQSr   s                  rF   rS   zSSLConnection.__init__  s   H  	ECDDD"$ MMMs++ 
	5-- I
 I-- Q-QQ   &m4M&$""0$0!!2)B& 0&<#""6"""""r+   c                 "   t                                                      }t          j                    }| j        |_        | j        |_        | j        s| j        r'|	                    | j        | j        | j
                   | j        | j        | j        '|                    | j        | j        | j                   |                    || j                  }| j        du rt$          du rt'          d          | j        r| j        rt'          d          | j        rd	dl}d
dlm} | j        Y|j                            |j        j                  }|                    | j                   |                    | j                   n| j        }|                    || j                   |j                             |tC          j!                              }|"                                 |#                    | j        | j$        f           |%                                 |&                                 |S | j        du rOt$          rHd
dlm'}  ||| j        | j$        | j                  }	|	(                                r|S tS          d          |S )z Wrap the socket with SSL support)r?  r>  rf   N)cafilecapathcadata)server_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.r   r   )ocsp_staple_verifier)OCSPVerifierzocsp validation error)*r  r   r@  create_default_contextrH  rD  verify_moder?  r>  load_cert_chainrI  rE  rG  rF  load_verify_locationswrap_socketr  rJ  r#   r   rK  OpenSSLocspr\  rL  SSLContextSSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackrM  r  r   request_ocspr   r  do_handshaker   r]  is_validr   )rA   r   contextsslsockrc  r\  
staple_ctxconr]  or   s             rF   r   zSSLConnection._connect  s   ww!!,..!%!4"n= 	DL 	##2 $    M%|'|'))}T\$, *    %%dDI%FF!T)).D.M.M=>>>) 	d.D 	   ) 	NNN222222 $,$[001JKK
//>>>..t|<<<<!2
//$d&A  
 +((V]__EECKKDI.///LLNNNN !T)).D)******WdiDMJJAzz|| ?%&=>>>r+   )NNr:  NNFNNFFNN)rH   rI   rJ   r  rS   r   r6  r7  s   @rF   r9  r9    s            "'#@# @# @# @# @# @#DA A A A A A A A Ar+   r9  c                   <     e Zd ZdZd	 fd	Zd Zd Zd Zd Z xZ	S )
UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis server Nc                 V    || _         || _         t                      j        di | d S r  )pathrg   r  rS   )rA   rw  rg   r   r   s       rF   rS   z#UnixDomainSocketConnection.__init__  s5    	,""6"""""r+   c                 p    d| j         fd| j        fg}| j        r|                    d| j        f           |S )Nrw  re   ro   )rw  re   ro   r:   r  s     rF   r   z&UnixDomainSocketConnection.repr_pieces#  sC    49%dg7 	=MM=$*:;<<<r+   c                     t          j         t           j        t           j                  }|                    | j                   |                    | j                   |                    | j                   |S )z&Create a Unix domain socket connection)r   AF_UNIXr!  r(  rh   r   rw  rg   )rA   r   s     rF   r   z#UnixDomainSocketConnection._connect)  s[    }V^V-?@@3444TY+,,,r+   c                     | j         S rP   )rw  r   s    rF   r   z&UnixDomainSocketConnection._host_error1  s
    yr+   c                     |                                  }t          |j                  dk    rd| d|j        d          dS d|j        d          d| d|j        d          dS )Nr   z!Error connecting to unix socket: r2  r   r   r   z connecting to unix socket: )r   rX   r0   r4  s      rF   r   z)UnixDomainSocketConnection._error_message4  s     %%''
y~!##VJVV).QRBSVVV
6* 6 66 6!*!26 6 6r+   )ru  Nr5  r7  s   @rF   rt  rt    s        ::# # # # # #
            r+   rt  )0FFALSENNOc                     | | dk    rd S t          | t                    r|                                 t          v rdS t	          |           S )Nru  F)r5   r6   upperFALSE_STRINGSr  )rD   s    rF   to_boolr  F  sI    }t% %++--="@"@u;;r+   )	re   rg   rh   r  ri   r~   max_connectionsrn   rS  c                 \   |                      d          s9|                      d          s$|                      d          st          d          t          |           } i }t          | j                                                  D ]\  }}|rt          |          dk    rnt          |d                   }t          	                    |          }|r8	  ||          ||<   [# t          t          f$ r t          d| d          w xY w|||<   | j        rt          | j                  |d<   | j        rt          | j                  |d	<   | j        d
k    r)| j        rt          | j                  |d<   t          |d<   n| j        rt          | j                  |d<   | j        rt%          | j                  |d<   | j        rUd|vrQ	 t%          t          | j                                      dd                    |d<   n# t(          t          f$ r Y nw xY w| j        dk    r
t*          |d<   |S )Nzredis://z	rediss://zunix://zRRedis URL must specify one of the following schemes (redis://, rediss://, unix://)r   zInvalid value for `z` in connection URL.rr   rf   unixrw  connection_classr  r  re   /ru  rediss)
startswithr   r   r   queryr'  rX   r   URL_QUERY_ARGUMENT_PARSERSr   r=   rr   rf   schemerw  rt  hostnamer  r   replacer3  r9  )urlr   namerD   r   s        rF   	parse_urlr  [  su   z""
>>+&&
 >>)$$

 5
 
 	

 3--CF	**0022 
% 
%e 		%SZZ!^^E!H%%E/33D99F %W#)6%==F4LL!:. W W W$%U4%U%U%UVVVW  %t
| 3$S\22z
| 3$S\22z zV8 	/$SX..F6N%?!"" < 	3$S\22F6N8 	+ ]]F6N 8 	F**"738#4#4#<#<S"#E#EFFt"J/    :!!)6F%&Ms   C!!%D8H   HHc                       e Zd ZdZed             Zedfdee         fdZ	de
e
ffdZddZdd	Zd
e
ddfdZdefdZddZddZdddefdZddeddfdZddZddZdS )ConnectionPoola  
    Create a connection pool. ``If max_connections`` is set, then this
    object raises :py:class:`~redis.exceptions.ConnectionError` when the pool's
    limit is reached.

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

    Any additional keyword arguments are passed to the constructor of
    ``connection_class``.
    c                 x    t          |          }d|v r|d         |d<   |                    |            | di |S )a  
        Return a connection pool configured from the given URL.

        For example::

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

        Three URL schemes are supported:

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

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

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

            1. A ``db`` querystring option, e.g. redis://localhost?db=0
            2. If using the redis:// or rediss:// schemes, the path argument
               of the url, e.g. redis://localhost/0
            3. A ``db`` keyword argument to this function.

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

        All querystring options are cast to their appropriate Python types.
        Boolean arguments can be specified with string values "True"/"False"
        or "Yes"/"No". Values that cannot be properly cast cause a
        ``ValueError`` to be raised. Once parsed, the querystring arguments
        and keyword arguments are passed to the ``ConnectionPool``'s
        class initializer. In the case of conflicting arguments, querystring
        arguments always win.
        r  rK   )r  update)clsr  r   url_optionss       rF   from_urlzConnectionPool.from_url  sP    R  nn''.45G.HK*+k"""s}}V}}r+   Nr  c                     |pd}t          |t                    r|dk     rt          d          || _        || _        || _        t          j                    | _        | 	                                 d S )Nl        r   z,"max_connections" must be a positive integer)
r5   r   r   r  connection_kwargsr  	threadingLock
_fork_lockreset)rA   r  r  r  s       rF   rS   zConnectionPool.__init__  st     *2U/3// 	M?Q3F3FKLLL 0!2. $.**

r+   rN   c           	      p    t          |           j         dt           | j        di | j                   dS )Nr   r   rK   )typerH   reprr  r  r   s    rF   r   zConnectionPool.__repr__  sS    Dzz" I I*T*DDT-CDDEEI I I	
r+   c                     t          j                    | _        d| _        g | _        t                      | _        t          j                    | _	        d S )Nr   )
r  r  _lock_created_connections_available_connectionsset_in_use_connectionsrz   r{   r|   r   s    rF   r  zConnectionPool.reset  s@    ^%%
$%!&(##&55  9;;r+   c                 Z   | j         t          j                    k    r| j                            d          }|st
          	 | j         t          j                    k    r|                                  | j                                         d S # | j                                         w xY wd S )N   )r   )r|   rz   r{   r  acquirer   r  release)rA   acquireds     rF   	_checkpidzConnectionPool._checkpid  s    F 8ry{{""..q.99H +***8ry{{**JJLLL'')))))'')))) #"s   0B B(command_namer  c                    |                                   | j        5  	 | j                                        }n$# t          $ r |                                 }Y nw xY w| j                            |           ddd           n# 1 swxY w Y   	 |                                 	 |	                                rt          d          nb# t          t          f$ rN |                                 |                                 |	                                rt          d          Y nw xY wn$# t          $ r |                     |            w xY w|S )zGet a connection from the poolNConnection has dataConnection not ready)r  r  r  pop
IndexErrormake_connectionr  addr   r   r   r   r   r   r  rA   r  keysoptions
connections        rF   get_connectionzConnectionPool.get_connection2  s   Z 	5 	54!8<<>>

 4 4 4!1133


4$((444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5	   
B&&(( A)*?@@@A#W- B B B%%'''""$$$&&(( B)*@AAAB BB
  	 	 	 LL$$$		 sb   B8BABABB	BD* ##C D* AD&#D* %D&&D* *!Ec                     | j         }t          |                    dd          |                    dd          |                    dd                    S )z,Return an encoder based on encoding settingsrj   rc   rk   rd   rl   F)rj   rk   rl   )r  r   r   )rA   r   s     rF   get_encoderzConnectionPool.get_encoderS  sV    'ZZ
G44"JJ'8(CC#ZZ(:EB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   rK   )r  r  r   r  r  r   s    rF   r  zConnectionPool.make_connection\  sR    $(<<<!"8999!!Q&!!$t$>>t'=>>>r+   r  c                    |                                   | j        5  	 | j                            |           n# t          $ r Y nw xY w|                     |          r| j                            |           n2| xj        dz  c_        |	                                 	 ddd           dS 	 ddd           dS # 1 swxY w Y   dS )z(Releases the connection back to the poolr   N)
r  r  r  r   KeyErrorowns_connectionr  r:   r  r   rA   r  s     rF   r  zConnectionPool.releasec  sI   Z 	 	(//
;;;;    
 ##J// +22:>>>>
 ))Q.))%%'''!	 	 	 	 	 	 	 	 ?	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s2   B99B9
AB9AAB99B= B=c                 "    |j         | j         k    S rP   )r|   r  s     rF   r  zConnectionPool.owns_connectionx  s    ~))r+   Tinuse_connectionsc                     |                                   | j        5  |rt          | j        | j                  }n| j        }|D ]}|                                 	 ddd           dS # 1 swxY w 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)r  r  r   r  r  r   )rA   r  connectionsr  s       rF   r   zConnectionPool.disconnect{  s     	Z 		( 		(  :#/1I  #9) ( (
%%''''(		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		( 		(s   >A((A,/A,c                 .    |                                   dS )z-Close the pool, disconnecting all connectionsNr   r   s    rF   r   zConnectionPool.close  r   r+   rs   r"   c                     | j                             d|i           | j        D ]	}||_        
| j        D ]	}||_        
d S )Nrs   )r  r  r  rs   r  )rA   rs   conns      rF   	set_retryzConnectionPool.set_retry  s^    %%w&6777/ 	 	DDJJ, 	 	DDJJ	 	r+   r`   )rN   r  )r  r  rN   Nr  )rs   r"   rN   N)rH   rI   rJ   r  classmethodr  r  r   r   rS   r6   r   r  r  r  r   r  r  r  r  r  r   r   r  rK   r+   rF   r  r    s         . . [.d $)-  "#   2
3* 
 
 
 
   "-* -* -* -*^3 \    B
W 
 
 
 
? ? ? ?   **, *3 * * * *( (D (D ( ( ( ((        r+   r  c                   J     e Zd ZdZddeef fd	Zd Zd Zd Z	d Z
d	 Z xZS )
BlockingConnectionPoola  
    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.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      c                 \    || _         || _         t                      j        d||d| d S )N)r  r  rK   )queue_classr   r  rS   )rA   r  r   r  r  r  r   s         rF   rS   zBlockingConnectionPool.__init__  sS     ' 	
-+	
 	
  	
 	
 	
 	
 	
r+   c                     |                      | j                  | _        	 	 | j                            d            n# t          $ r Y nw xY w-g | _        t          j                    | _        d S rP   )	r  r  pool
put_nowaitr   _connectionsrz   r{   r|   r   s    rF   r  zBlockingConnectionPool.reset  s    $$T%9::			$$T****   	  9;;s   = 
A
	A
c                 ^     | j         di | j        }| j                            |           |S )zMake a fresh connection.rK   )r  r  r  r:   r  s     rF   r  z&BlockingConnectionPool.make_connection  s:    *T*DDT-CDD
  ,,,r+   c                 `   |                                   d}	 | j                            d| j                  }n# t          $ r t          d          w xY w||                                 }	 |                                 	 |                                rt          d          nb# t
          t          f$ rN |
                                 |                                 |                                rt          d          Y nw xY wn$# t          $ r |                     |            w xY w|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)blockr   zNo connection available.r  r  )r  r  r   r   r   r   r  r   r   r   r   r   r  r  s        rF   r  z%BlockingConnectionPool.get_connection  sz    	 
	>T4<HHJJ 	> 	> 	> ""<===	> --//J	   
B&&(( A)*?@@@A#W- B B B%%'''""$$$&&(( B)*@AAAB BB
  	 	 	LL$$$	
 s:   !: A.D
 #B' &D
 'ADD
 DD
 
!D+c                    |                                   |                     |          s0|                                 | j                            d           dS 	 | j                            |           dS # t
          $ r Y dS w xY w)z)Releases the connection back to the pool.N)r  r  r   r  r  r   r  s     rF   r  zBlockingConnectionPool.release  s     	##J// 	
 !!###I  &&&F	I  ,,,,, 	 	 	 DD	s   A7 7
BBc                 j    |                                   | j        D ]}|                                 dS )z(Disconnects all connections in the pool.N)r  r  r   r  s     rF   r   z!BlockingConnectionPool.disconnect4  sC    + 	$ 	$J!!####	$ 	$r+   )rH   rI   rJ   r  r  r   rS   r  r  r  r  r   r6  r7  s   @rF   r  r    s         F #
 
 
 
 
 
   0  2 2 2h  *$ $ $ $ $ $ $r+   r  )Pr   rz   r   r@  r>   r  r   abcr   	itertoolsr   queuer   r   r   r   typingr	   r
   r   r   r   r   urllib.parser   r   r   _parsersr   r   r   r   backoffr   credentialsr   r   
exceptionsr   r   r   r   r   r   r    r!   rs   r"   utilsr#   r$   r%   r&   r'   r(   r;   rW   r\   rY   rU   r   objectr}   __annotations__r-   r/   rM   rb   r  r9  rt  r  r  r   r  listr  r  r  r  rK   r+   rF   <module>r     sF    				  



 



                  ( ( ( ( ( ( ( ( ( (       = = = = = = = = = = = = = = = = 4 4 4 4 4 4 4 4 4 4 I I I I I I I I I I I I       O O O O O O O O	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	                       NNN
	 688E,nDEF F F F !"MM M       $0 0 0 0 0 0 0 0fs s s s s s s slX@ X@ X@ X@ X@# X@ X@ X@vI I I I IJ I I IX% % % % %!3 % % %P /   # !
 
 6 6 6rD D D D D D D DN]$ ]$ ]$ ]$ ]$^ ]$ ]$ ]$ ]$ ]$r+   