bJ UddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddlmZddlmZmZmZmZmZmZmZmZmZmZmZddlmZmZmZm Z ddl!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'm(Z(dd l)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8dd l9m:Z:m;Z;dd lZ>dZ?e=rddl?Z?e@ejejd ejd ejd iZEeFeEjZHd ZIdZJdZKdZLdZMdZNGddejZPePjZRdZSdZTdZUdZVGdde(dZWGddZXeeYeeeZeeYeeZfffZ[Gdd Z\Gd!d"Z]Gd#d$e\Z^Gd%d&e\Z_eee^e_fe`d'<e=re_Zane^ZaGd(d)e'ZbGd*d+e'ZceebecfZdGd,d-ZeGd.d/eeZfGd0d1ZgGd2d3eeZhd4Zid5eejfd6Zkeelememekekelelekd7ZneeYed8eoffe`d9<Gd:d;e(dZpdd?@ZrGdAd?ZsGdBdCesZty)DN)chain)MappingProxyType) AnyCallableIterableListMappingOptionalSetTupleTypeTypeVarUnion) ParseResultparse_qsunquoteurlparse)Retry) NoBackoff)Protocol TypedDict)AuthenticationError$AuthenticationWrongNumberOfArgsErrorBusyLoadingErrorChildDeadlockedErrorConnectionError DataErrorExecAbortErrorInvalidResponse ModuleErrorNoPermissionError NoScriptError ReadOnlyError RedisError ResponseError TimeoutError) EncodableTEncodedT)HIREDIS_AVAILABLE str_if_bytes*$s  zConnection closed by server.ceZdZeZy) _SentinelN)__name__ __module__ __qualname__objectsentinelr/:/usr/lib/python3/dist-packages/redis/asyncio/connection.pyr1r1Ns xHr/r1z: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 unloadcZeZdZUeegefed<eegefed<eeed<eeed<y)_HiredisReaderArgs protocolError replyErrorencodingerrorsN)r2r3r4rstr Exception__annotations__r r7r/r8r:r:]s:SE9,--# )**sm SMr/r:F)totalcJeZdZdZdZdededefdZdede fd Z d dedefd Z y ) Encoderz=Encode strings to bytes-like and decode bytes-like to stringsr=encoding_errorsdecode_responsesr=rFrGc.||_||_||_yNrE)selfr=rFrGs r8__init__zEncoder.__init__is  . 0r/valuereturnc|t|tr&|j|j|jSt|t t fr|St|ttfr4t|tr tdt|jS|jj}td|d)z=Return a bytestring or bytes-like representation of the valuezNInvalid input of type: 'bool'. Convert to a bytes, string, int or float first.zInvalid input of type: z1. Convert to a bytes, string, int or float first.) isinstancer?encoder=rFbytes memoryviewintfloatboolrrepr __class__r2)rJrLtypenames r8rPzEncoder.encodens eS !<< t/C/CD D eeZ0 1L ec5\ *%&F;%%' '??++%h\2> >  r/c|js|rzt|tr&|j|j|j St|t r4|jj|j|j S|S)z:Return a unicode string from the bytes-like representation)rGrOrQdecoder=rFrRtobytes)rJrLforces r8rZzEncoder.decodesd  E%'||DMM43G3GHH%,}}--dmmT=Q=QRR r/NF) r2r3r4__doc__ __slots__r?rUrKr'r(rPrZr7r/r8rDrDdsJGAI11s1d1  J 8 *J r/rDceZdZUdZdZdededededeee e e e e e e i e eeeeedZeed <d efd Zd Zd edefdZdZddZdedefdZ ddede e!ede"e!ffdZ#y) BaseParserPlain Python parsing class_stream_buffer _read_sizezmax number of clients reachedz(Client sent AUTH, but no password is setzinvalid passwordz,wrong number of arguments for 'auth' commandz,wrong number of arguments for 'AUTH' command)ERR EXECABORTLOADINGNOSCRIPTREADONLYNOAUTHNOPERMEXCEPTION_CLASSESsocket_read_sizec.d|_d|_||_yrIrc)rJros r8rKzBaseParser.__init__s7; /3 *r/cD |jy#t$rYywxYwrI) on_disconnectr@rJs r8__del__zBaseParser.__del__s%        s  responserMc|jdd}||jvrN|t|dzd}|j|}t|tr|j |t }||St |S)zParse an error response rN)splitrnlenrOdictgetr%)rJru error_codeexception_classs r8 parse_errorzBaseParser.parse_errors{^^C(+ // /J! 3 56H"44Z@O/40"1"5"5h "N"8, ,X&&r/ctrINotImplementedErrorrss r8rrzBaseParser.on_disconnect !##r/ctrIrrJ connections r8 on_connectzBaseParser.on_connectrr/timeoutcKtwrIrrJrs r8can_readzBaseParser.can_reads!## disable_decodingNcKtwrIr)rJrs r8 read_responsezBaseParser.read_responses"##rr Connectionr])$r2r3r4r^r_rrrMODULE_LOAD_ERRORr MODULE_EXPORTS_DATA_TYPES_ERRORNO_SUCH_MODULE_ERROR MODULE_UNLOAD_NOT_POSSIBLE_ERRORrrr"r#r!rnExceptionMappingTrArSrKrtr?r%rrrrrTrUrrr'rrr7r/r8raras$2I ,_ 68K  3 ;<` ;<` { +[ + ,k $#!!%#+,(0++  'C 'M '$$$e$$(-$ $$ z=$Z0@@ A$r/rac eZdZdZdej dedeefdZ e dZ de dfd eed e edefd ed efd Zd ed efdZd ed efdZd efdZdZdZy) 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_readerrosocket_timeoutc|||_||_||_tj|_d|_d|_yNr)rdrorioBytesIOre bytes_written bytes_read)rJrrors r8rKzSocketBuffer.__init__s8 8E 0,-/ZZ\ r/c4|j|jz SrI)rrrss r8lengthzSocketBuffer.lengths!!DOO33r/NTrrraise_on_timeoutrMcK|j}| |j td|j|jd}|t ur|n |j } tj|4d{|jj|jd{}dddd{ttrt|dk(rtt|j!|t|}|xj|z c_||z }|||kDry777t#1d{7swYxYw#t"jt$j&f$r|r t'dYyt($rS}t*j-|j.d} |s|j0| k(rYd}~ytd|j2d}~wwxYww)NBuffer is closed.rTTimeout reading from socketF!Error while reading from socket: )rerdr$seekrSENTINELr async_timeoutrreadrorOrQrzrSERVER_CLOSED_CONNECTION_ERRORwritesocketasyncior&NONBLOCKING_EXCEPTIONS#NONBLOCKING_EXCEPTION_ERROR_NUMBERSr|rWerrnoargs) rJrrrbufmarkerdata data_lengthexalloweds r8_read_from_socketzSocketBuffer._read_from_sockets ll ;$,,.01 1 ##$$H4'$:M:M Q(009JJ!%!2!243H3H!IIDJJdE*s4yA~)*HII $!$i ""k1"+%%&6/JIJJJJ 4 45 "#@AA% Q :==bllBOG#G(;!$EbggY"OP P QsAGD?6D$7D?:)D*#D&$D*( D?3D(4A/D?#G$D?&D*(D?*D<0D3 1D<8D??0G /G1G 91G*G/GG  GcrKt|jxs|j|dd{S7w)NFrr)rUrrrs r8rzSocketBuffer.can_reads>DKK  $*@*@e+A+ %  % s .757cK|dz}||jkDr&|j||jz d{|j td|jj |j |jj |}|xj t|z c_|j |jk(r|j|ddS7w)Nr+r) rrrer$rrrrzrpurge)rJrrs r8rzSocketBuffer.reads! DKK (($++)=> > > << 01 1 $//*||  ( 3t9$ ??d00 0 JJLCRy ?s6C"C B(C"c K|j}| td|j|j|j }|j t sY|jd{|j|j|j }|j t sY|xjt|z c_|j|jk(r|j|ddS7w)Nrr) rer$rrreadlineendswithSYM_CRLFrrzrr)rJrrs r8rzSocketBuffer.readline0sll ;01 1 !||~--)((* * * HHT__ %<<>D --) 3t9$ ??d00 0 JJLCRy +sA-D/D0AD5A Dc|j td|jjd|jjd|_d|_y)Nrr)rer$rtruncaterrrss r8rzSocketBuffer.purgeFsI << 01 1 ! r/c |j|jjd|_d|_y#t$rYwxYwrI)rrecloser@rdrss r8rzSocketBuffer.closeOsF  JJL LL         s*; AA)r2r3r4r^r StreamReaderrSr rTrKpropertyrrrr1rUrrrQrrrrr7r/r8rrs ++  ! 44 !%19!% (Q (QudI-.(Q (Q  (QT e  (, r/rceZdZdZej dzZdeffd Zd dZdZ de fdZ dd e d e eed ffd ZxZS) PythonParserrb)encoderroc2t||d|_yrI)superrKrrJrorWs r8rKzPythonParser.__init__cs )**. r/c|j|_|j tdt|j|j|j |_|j|_y)zCalled when the stream connectsNr)_readerrdr$rrfrrerrs r8rzPythonParser.on_connectgsU!)) << 01 1# LL$//:+D+D  ")) r/c|jd|_|j!|jjd|_d|_y)z"Called when the stream disconnectsN)rdrerrrss r8rrzPythonParser.on_disconnectrs; << #DL << # LL   DL r/rcK|jxr,t|jj|d{S7wrI)rerUrrs r8rzPythonParser.can_read{s/||J4<<+@+@+I%I JJ%Is 2?= ?rrMNcK|jr |jstt|jj d{}|stt|dd|dd}}|dvrt d||dk(r8|j dd}|j|}t|tr||S|dk(rn|d k(r t|}n|d k(r5t|}|d k(ry|jj|d{}nE|d k(r@t|}|d k(ryt|Dcgc]}|j|d{}}t|tr|d ur|jj |}|S767~7>cc}ww)Nrx)-+:r-r,zProtocol Error: rutf-8replace)r>rrr-rr,F)rerrrrrrZrrOrSrrangerrQ)rJrrawbyteruerrorr_s r8rzPythonParser.read_response~s||4<<!"@A ALL))++!"@A ARa#ab'h 5 5!$4SG"<= = 4<wyAH$$X.E%1 L T\  T\8}H T\]F|!\\..v66H T\]F|FKFmABt))*:;;;H h &+;u+D||**84HY,B7<sIAF E=B9F F(F *FF F 4F F FF rr])r2r3r4r^rar_rSrKrrrrTrrUrr'r%r __classcell__rWs@r8rr^s`$$$|3I// *KeK(-1 $1 z=$. /1r/rceZdZUdZej dzZeed<deffd Z ddZ dZ de fd Z ed fdee d efd efd Z ddedeeeeffdZxZS) HiredisParserz*Parser class for connections using Hiredis)_next_responser_socket_timeoutrrocdts tdt| |d|_d|_y)NzHiredis is not available.ro)r)r$rrKrrrs r8rKzHiredisParser.__init__s2 89 9 *:;15 04r/c@|j|_t|jd}|jj r2|jj |d<|jj|d<tjdi||_d|_ |j|_ y)N)r;r<r=r>Fr7) rrdrrrrGr=rFhiredisReaderrrr)rJrkwargss r8rzHiredisParser.on_connects!)) ,**&     . .!+!3!3!Z.d7e/d)e0efd?Z1d@e'e'e/d)e0efdAZ2y)Frz4Manages TCP communication to and from a Redis server)pidhostportdbusername client_namepasswordrsocket_connect_timeoutsocket_keepalivesocket_keepalive_options socket_typeredis_connect_funcretry_on_timeoutretry_on_errorhealth_check_intervalnext_health_checklast_active_atr ssl_contextr_writer_parser_connect_callbacks_buffer_cutoff_lock_socket_read_size__dict__ localhostirNFrstrict)rrrrrrr r r r rr=rFrG parser_classrorrrretryr  encoder_classrrrrrrr r r r rr=rFrGrrorrrrr rc"tj|_||_t ||_||_||_||_||_ ||_ |xs|xsd|_ ||_ |xsi|_ | |_| |_| t urg} | r| j#t$| |_| rR|st)t+d|_nt/j0||_|j,j3| nt)t+d|_||_d|_d|_|| | ||_||_d|_d|_ ||_!|jE|g|_#d|_$tKjL|_'y)Nrxrrp)(osgetpidrrrSrrrrrrrr r r r rappendr&rrrrcopydeepcopyupdate_supported_errorsrrrrr rrr set_parserrrrLockr)rJrrrrrrr r r r rr=rFrGrrorrrrr rs r8rKzConnection.__init__Us`499; I   &  ,&<&V&VRV# 0(@(FB%& 0 X %N   ! !, /, "9;2 "]]51 JJ . .~ >y{A.DJ%:"(*6:$X@PQ "47; 7; !1  %NP"\\^ r/cdjd|jD}|jjd|dS)N,c30K|]\}}|d|yw)=Nr7).0kvs r8 z&Connection.__repr__..sHTQ1QCjHs<>)join repr_piecesrWr2)rJ repr_argss r8__repr__zConnection.__repr__s=HHHT5E5E5GHI ..))*!I;a88r/cd|jfd|jfd|jfg}|jr|j d|jf|S)Nrrrr)rrrrr$rJpiecess r8r5zConnection.repr_piecessM499% ':T477OL    MM=$*:*:; < r/c |jrXtj}|j}|j r|j |y|j |yy#t$rYywxYwrI) is_connectedrget_event_loop disconnect is_running create_taskrun_until_completer@)rJloopcoros r8rtzConnection.__del__si   --/(??$$$T*++D1 !   sAA'A'' A32A3c6|jxr |jSrI)rrrss r8r<zConnection.is_connecteds||, ,r/c`|jjtj|yrI)rr$weakref WeakMethod)rJcallbacks r8register_connect_callbackz$Connection.register_connect_callbacks! &&w'9'9('CDr/cg|_yrI)rrss r8clear_connect_callbacksz"Connection.clear_connect_callbackss "$r/rMc4||j|_y)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 rN)rr)rJrs r8r(zConnection.set_parsers $T5K5KL r/c"K|jry |jd{ |js|jd{nItj|jr|j|d{n|j||j D]4}|}||}|st#j$|s+|d{6y7#tj$rtj tj f$r t dt$r}t|j|d}~wt$r}t||d}~wwxYw77#t$r|jd{7wxYw7w)z5Connects to the Redis server if not already connectedNzTimeout connecting to server)r<_connectrrrrr&OSErrorr_error_messager@r riscoroutinefunctionr$r>rinspect isawaitable)rJeexcrefrHtasks r8connectzConnection.connectsf     0--/ ! ! **oo'''8?7R7R++8d--d333..t4** CuHD>D++D1  5 "%%   4 45 ?=> > :!$"5"5a"89 9 0!#&C / 0 (4 //# # #  sFCCCE& E! 8E&E$E& F9FFF FCA E'E E EEF!E&$E&&F FF  FclKtj|j4d{tj|j |j |jr|jjndd{\}}dddd{|_ |_ |jjd}|r|jtjtj d |j"rs|jtj$tj&d|j(j+D]&\}}|jtj,||(yyy7N77#1d{7swYxYw#t.t0f$r|j3wxYww)zCreate a TCP socket connectionN)rrsslrrx)rrrropen_connectionrrrr|rr transportget_extra_info setsockoptr IPPROTO_TCP TCP_NODELAYr  SOL_SOCKET SO_KEEPALIVEr itemsSOL_TCPrO TypeErrorr)rJreaderwritersockr/r0s r8rNzConnection._connectsd (()D)DE  #*#:#:YYYY.2.>.>D$$((*D$NFF     ..x8  OOF..0B0BA F ((OOF$5$5v7J7JAN $ = = C C E>11=>)      $Y'    sq$F4E4F4AE;E7E; F4E9AF43A>F1F47E;9F4;F F F  F4!F11F4c t|jdk(r-d|jd|jd|jddSd|jdd|jd|jd|jdd S) NrxzError connecting to :. r.Error z connecting to )rzrrrrJ exceptions r8rPzConnection._error_messages y~~ ! #)$))Adii[9>>RSCTBUUVW W*+?499+QtyykQS>>!$%Q( r/cK|jj||js |jr|jr|j|jxsdf}n|jxsdf}|jdg|ddid{ |j d{}t|dk7r td|jrT|j d d |jd{t|j d{dk7r td |jrT|j d |jd{t|j d{dk7r td yy77#t $rD|j d|jdd{7|j d{7}Y*wxYw7777rw)z=Initialize the connection, authenticate and select a databaseAUTH check_healthFNrsOKzInvalid Username or PasswordCLIENTSETNAMEzError setting client nameSELECTzInvalid Database) rrrr send_commandrrr*rrrr)rJ auth_args auth_responses r8rzConnection.on_connect s % ==DMM}}!]]DMM,?R@ "]]0b2 $$##FKYKUK K K ;&*&8&8&: : M*d2)*HII   ##Hi9I9IJ J J$"4"4"6674?%&ABB 77##Hdgg6 6 6$"4"4"6674?%&899@ - L!;7 ; '' E'RRR&*&8&8&: : :  ; K6 76sBG F GF"F#F'AG,G-G G AG G G(G)GF*G/F20GG  GGGGGGGcK tj|j4d{|jj |j s dddd{y t j|jk(rR|jjt|jdr"|jjd{d|_d|_ dddd{y777'#t$rY0wxYw#d|_d|_ wxYw7-#1d{7swYyxYw#tj $rt!d|jdwxYww)z!Disconnects from the Redis serverN wait_closedz#Timed out closing connection after )rrrrrrr<r"r#rrrhasattrr}rOrrr&rss r8r>zConnection.disconnect3s9 $,,T-H-HI ( ( **,(( ( ( ( (yy{dhh. **,"4<<?"&,,":":"<<<$(DL#'DL ( ( ( (=$(DL#'DL ( ( ( (## 5d6Q6Q5RS  sE&#D6C7D6(D! D6C9D6#E&%A.C=C;C=D!& D61D2D66E&7D69D6;C== D D D  D  DD!D6!D3'D* (D3/D62E&3D66-E##E&cK|jddd{t|jd{dk7r tdy747w)z Send PING, expect PONG in returnPINGFrtNPONGz#Bad response from PING health check)ryr*rrrss r8 _send_pingzConnection._send_pingJsRU;;; d0022 3v =!"GH H > <2sAAAAAAc@K|jd{y7w)z Function to call when PING failsNr>)rJrs r8 _ping_failedzConnection._ping_failedPsoos cNKtjdddk(rtj}ntj}|j r\|j |jkDr9|jj|j|jd{yyy7w)z3Check the health of the connection with a PING/PONGrr+N) sys version_inforr=get_running_looprtimerrcall_with_retryrr)rJfuncs r8rszConnection.check_healthTs   Aa F *))D++D  % %$&++-$:P:P*P**,,T__d>O>OP P P+Q % PsBB%B#B%commandcK|jj||jjd{y7wrI)r writelinesdrain)rJrs r8_send_packed_commandzConnection._send_packed_command^s. (ll  """s9AAArscK|js|jd{n|r|jd{ t|tr|j }t|t r|g}|jr8tj|j||jd{y|jj||jjd{y777G7 #tj$r&|jd{7tddt $ry}|jd{7t#|j$dk(rd|j$d}}n|j$d}|j$d}t'd|d|d|d}~wt($r|jd{7wxYww)NzTimeout writing to socketrxUNKNOWNrrmz while writing to socket. rl)r<rXrsrOr?rPrQrrwait_forrrrrr&r>rOrzrr BaseException)rJrrsrTerr_noerrmsgs r8send_packed_commandzConnection.send_packed_commandbs  ,,. ##% % % '3'!..*'5)")""&&--g68K8K ''0ll((*** ! % +## F//# # #:; E //# # #166{a!*AFF1I! :6(!D  //# # #  s GC8GC:GA1D4C<5D9G:8D2C>3D7G:G<D>D&G&D)'GF4EA F44GGGGrrcK|j|j||jddd{y7w)z+Pack and send a command to the Redis serverrsTrtN)r pack_commandr|)rJrrs r8ryzConnection.send_commands@&& D  t $6::nd3S'   s 4><>rc ZK|js|jd{ |jj|d{S7(7#t$rP}|j d{7t d|jd|jd|jd}~wwxYww)z8Poll the socket to see if there's data that can be read.NError while reading from rjz: ) r<rXrrrOr>rrrr)rJrrTs r8rzConnection.can_reads  ,,.  ..w77 7 !7 //# # #!+DII;a {"QVVHM  sP B+A B+AA A B+ A B(B#+A.,7B##B((B+rc xK |j4d{|jr]tj|j4d{|jj |d{}dddd{n$|jj |d{}dddd{|jr^t j"ddd k(rt j$}nt j&}|j)|jz|_t-t.r|d|S7!777#1d{7swYxYw77#1d{7swYxYw#t j$r?|jd{7td|jd|jt$rP}|jd{7td|jd|jd|jd}~wt$r|jd{7wxYww z0Read the response from a previously sent commandN)rzTimeout reading from rjrz : rr+r)rrrrrrrr&r>rrrOrrrrrrr=rrrrOr%rJrrurTrs r8rzConnection.read_responses zz  &&,44T5H5HI)-)C)C-=*D*$ &*\\%?%?)9&@& H  ,  % %!$.--//%)V[[]T5O5O%OD " h . $? $      ## P//# # #!6tyyk499+NO O //# # #!+DII;a {#affXN  //# # #  sH:E,D5E,0ED8 E D>,D:-D>1 E<D<=$E!E"E& E,1E2E,6A?H:5E,8E:D><E>E EE EE,E)E E)%E,,&H7F2H7HG7HH7/H20H77H:c K |jr]tj|j4d{|jj |d{}dddd{n$|jj |d{}|jr^tj ddd k(rt j"}nt j$}|j'|jz|_t+t,r|d|S777#1d{7swYxYw7#t j $r?|jd{7t d|jd|jt$rP}|jd{7td|jd|jd|jd}~wt$r|jd{7wxYwwr)rrrrrrr&r>rrrOrrrrrrr=rrrrOr%rs r8read_response_without_lockz%Connection.read_response_without_locks ""(001D1DE%)\\%?%?)9&@& H "&!;!;%5"<"  % %!$.--//%)V[[]T5O5O%OD " h . $;  ## P//# # #!6tyyk499+NO O //# # #!+DII;a {#affXN  //# # #  sG;/D-DD- DDD D-'D($D- D+ D-A?G;D-DD-D(D D($D--&G8E2G8GF7GG80G31G88G;c g}t|dtrJt|dtr1t|dj j |ddz}n)d|dvr"t|dj |ddz}t jttt|j tf}|j}t|jj|D]}t|}t||kDs||kDst|trat j|tt|j tf}|j!||j!|t}t j|tt|j t|tf}|j!||S)z2Pack a series of arguments into the Redis protocolrrxN )rOrTr?tuplerPry SYM_EMPTYr4SYM_STARrzrrmaprrR SYM_DOLLARr$)rJroutputbuff buffer_cutoffarg arg_lengths r8rzConnection.pack_commands d1gu--- d1gs #a)//12T!"X=D T!W_a)DH4D~~xSY)>)>)@(KL++ t||**D1 CSJD M) -c:. ~~:s:'='='?J d# c" ~~"J..0   ! 4  d r/commandscg}g}d}|j}|D]}|j|D]}t|}||kDs||kDst|tr(|j t j|d}g}||kDst|tr|j |w|j |||z }|r$|j t j||S)z.Pack multiple commands into the Redis protocolr)rrrzrOrRr$rr4) rJrrr: buffer_lengthrcmdchunkchunklens r8 pack_commandszConnection.pack_commandss   ++  .C***C0 .u:!M1-/!%4MM).."89$%MFm+z%/LMM%(MM%(!X-M . .$  MM)..0 1 r/)rMNT)rr])3r2r3r4r^r_rrrDr?rrSr rTrUr rQrr1r rarConnectCallbackTrKr7r5rtrr<rIrKr(rXrNrPrr>rrrsrrrrryrrrr'rrrr7r/r8rr3s>ID $"&*.26!&NR!&19'!&)6 %'(%)"&!%9='.1A$A$CHo A$ #s(O A$ 3- A$!A$!)A$A$#+73c5j8I3I+J"KA$A$A$dIo.A$A$A$ !A$":&#A$$%A$& %'A$(c])A$*3-+A$,-A$.%%56/A$0G}1A$F9 --E%MtJ'7MDM#J4 ':R.I  Q#(5/#d# QU#UC%89#IM# #J  s t e "D"H!!F,*,e,\hx /C&Der/rc eZdZ ddeedeededeedeedef fd ZedZed Z ed Z ed Z ed Z ed Z xZS) SSLConnection ssl_keyfile ssl_certfile ssl_cert_reqs ssl_ca_certs ssl_ca_datassl_check_hostnamec Pt|di|t|||||||_y)N)keyfilecertfile cert_reqsca_certsca_datacheck_hostnamer7)rrKRedisSSLContextr) rJrrrrrrrrWs r8rKzSSLConnection.__init__-s4 "6",;!#!- - r/c.|jjSrI)rrrss r8rzSSLConnection.keyfileA'''r/c.|jjSrI)rrrss r8rzSSLConnection.certfileE(((r/c.|jjSrI)rrrss r8rzSSLConnection.cert_reqsIs)))r/c.|jjSrI)rrrss r8rzSSLConnection.ca_certsMrr/c.|jjSrI)rrrss r8rzSSLConnection.ca_dataQrr/c.|jjSrI)rrrss r8rzSSLConnection.check_hostnameUs...r/)NNrequiredNNF)r2r3r4r r?rUrKrrrrrrrrrs@r8rr,s&*&*'&*%)#( c] sm   sm  c]  ! ((())**))((//r/rc |eZdZdZ d deedeedeedeedeedef d Zd ejfd Z y) r)rrrrrcontextrNrrrrrrc@||_||_|tj|_n\t |t rLtjtjtjd}||vrtd||||_||_ ||_ ||_ d|_ y)N)noneoptionalrz+Invalid SSL Certificate Requirements Flag: )rrrZ CERT_NONErrOr? CERT_OPTIONAL CERT_REQUIREDr$rrrr)rJrrrrrr CERT_REQSs r8rKzRedisSSLContext.__init__es     ]]DN  3 ' ----I  ) A)M'y1DN   ,15 r/rMc|jstj}|j|_|j|_|j r3|jr'|j|j |j|js |jr'|j|j|j||_|jS)N)rr)cafilecadata) rrZcreate_default_contextrr verify_moderrload_cert_chainrrload_verify_locations)rJrs r8r|zRedisSSLContext.gets||002G%)%8%8G ""&..G }}'' 'U}} --T]]4<<-X"DL||r/)NNNNNF) r2r3r4r_r r?rUrKrZ SSLContextr|r7r/r8rrZsI"&"&#'"&!%$6#63-6C= 6 3- 6 # 66: S^^ r/rc"eZdZddddddddddeedddddd d ed eeefd eed eedee dee dedede de dee e fde edede dedeef dZdeeeeeefffdZdZdZy)UnixDomainSocketConnectionrqrNrrFrg)pathrrrrrr=rFrGr rrrorrrr rrrrrrr=rFrGr rrrorrrctj|_||_||_||_||_||_||_|xs|xsd|_ | |_ | turg} | r| jt| |_| rR|tt!d|_nt%j&||_|j"j)| ntt!d|_||_d|_||_t1||| |_d|_d|_d|_| |_|j=| g|_d|_ tCjD|_#y)z Initialize a new UnixDomainSocketConnection. To specify a retry policy, first set `retry_on_timeout` to `True` then set `retry` to a valid `Retry` object Nrxrrr!)$r"r#rrrrrrrrr rr$r&rrrrr%r&r'rrr rDr_sockrrrr(rrrr)r)rJrrrrrrr=rFrGr rrrorrrr s r8rKz#UnixDomainSocketConnection.__init__s9499;   &  ,&<&V&VRV# 0 X %N   ! !, /, }"9;2 "]]51 JJ . .~ >y{A.DJ%:"!#"4x:JK    !1  %"$"\\^ r/rMcd|jfd|jfg}|jr|jd|jf|S)Nrrr)rrrr$r9s r8r5z&UnixDomainSocketConnection.repr_piecessB499%dgg7    MM=$*:*:; < r/cXKtj|j4d{tj|j d{\}}dddd{|_|_|jd{y7f7@7/#1d{7swY?xYw7 w)N)r) rrrropen_unix_connectionrrrr)rJrfrgs r8rNz#UnixDomainSocketConnection._connects (()D)DE P P#*#?#?TYY#OONFF P P  oo  PO P P P P sb$B*B B*$BBB B*!B"%B*B(B*BB*B%B B%!B*ct|jdk(r d|jd|jddSd|jdd|jd|jddS)Nrxz!Error connecting to unix socket: rkrrlrmz connecting to unix socket: )rzrrrns r8rPz)UnixDomainSocketConnection._error_messagesu y~~ ! #6tyykINNSTDUCVVWX X*++G99+R q 12!5 r/)r2r3r4rrr?rrSr rTrUrr1r rarrKrr r5rNrPr7r/r8rrs4"&"&*.26'!&!&19)6 %'*!%'=$=$ #s(O =$ 3- =$ 3- =$!=$!)=$=$=$=$=$dIo.=$:&=$=$ %!=$"#=$$%=$~XeCsCx,@&AB   r/r)0FFALSENNOrMcv||dk(ryt|tr|jtvryt |S)NrqF)rOr?upper FALSE_STRINGSrU)rLs r8to_boolrs4 } %%++-="@ ;r/)rrrr r max_connectionsrr.URL_QUERY_ARGUMENT_PARSERScZeZdZUeed<eed<eeed<eed<eed<eed<eed<y) ConnectKwargsrrconnection_classrrrrN)r2r3r4r?rAr rrSr7r/r8rrs+MM:&& I I G Ir/rurlct|}i}t|jjD]N\}}|s t |dkDst |d}t j|}|r ||||<J|||<P|jrt |j|d<|jrt |j|d<|jdk(r/|jrt |j|d<t|d<|S|jd vr|jrt |j|d <|j rt#|j |d <|jr6d |vr2 t#t |jj%d d|d <|jdk(r t(|d<|Sd}td|d#ttf$rtd|dwxYw#t&tf$rY^wxYw)NrzInvalid value for `z` in connection URL.rrunixrr)redisredissrrr/rqrzredis://, rediss://, unix://z5Redis URL must specify one of the following schemes ())rrqueryrcrzrrr|re ValueErrorrrschemerrhostnamerrSrAttributeErrorr)rparsedrname value_listrLparser valid_schemess r8 parse_urlr  s"3-FF$V\\288: %j #j/A-JqM*E/33D9FW#)%=F4L %t  %$V__5z $V__5z}} ;;$V[[1F6N%?!"0 M- - - ??$V__5F6N ;; -F6N ;;4v- "76;;#7#?#?R#HIt  ==H $)6F% & M 7 CM?RS T  E":.W$':4&@T%UVVW6#J/  s/ G /1G- G*-G?>G?_CPConnectionPool)boundceZdZdZedeededefdZe dfdee de e fd Z d Z d Zd Zd ZdZdZde fdZde fdZddefdZy)ra 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``. clsrrMc Jt|}|j||di|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: - `rediss://` creates a SSL wrapped TCP socket connection. See more at: - ``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. r7)r update)rrr url_optionss r8from_urlzConnectionPool.from_urlPs&P n  k"}V}r/Nrrc T|xsd}t|tr|dkr td||_||_||_t j|_tj|_ ||||j|jjdt|_y)Nlrz,"max_connections" must be a positive integerr)rOrSrrconnection_kwargsr threadingr) _fork_lockrrresetr|rDr)rJrrrs r8rKzConnectionPool.__init__|s *2U/3/?Q3FKL L 0!2.$..*\\^     !3377Qr/cn|jjd|jdi|jdS)Nr2r3r7)rWr2rrrss r8r7zConnectionPool.__repr__s>~~&&'%%%?(>(>?B! E r/ctj|_d|_g|_t |_tj|_ yr) rr)r_created_connections_available_connectionsset_in_use_connectionsr"r#rrss r8rzConnectionPool.resets8\\^ $%!&(##&5 99;r/cf|jtjk7rq|jj d}|st  |jtjk7r|j |jjyy#|jjwxYw)N)r)rr"r#racquirerrrelease)rJacquireds r8 _checkpidzConnectionPool._checkpidsF 88ryy{ "..q.9H** *88ryy{*JJL'') #'')s 1BB0cK|j|j4d{ |jj}|j j|dddd{ jd{ |jd{r tdd |S7#t$r|j }YwxYw7f#1d{7swYvxYw7d7M#t$r[|jd{7|jd{7|jd{7r tddY|SwxYw#t$r|jd{7wxYww)zGet a connection from the poolNConnection has dataConnection not ready)r&rrpop IndexErrormake_connectionr addrXrrr>rr$rJ command_namekeysoptionsrs r8get_connectionzConnectionPool.get_connectionsq :: 5 5 4!88<<>   $ $ ( ( 4  5 5 $$& & &  L#,,...)*?@dJ/9 5 4!113  4 5 5 5 5 ' /" L ++--- ((***#,,...)*@AtK/ L  ,,z* * *   s!E:B/E:CB1C E:)C*E:/EC'EC+C)C+-E:1C  C C  CE:C$C C$ E:'E)C++ED E D#!E9D<:E E E:EEE7/E20E77E:c|j}|j|jdd|jdd|jddS)z,Return an encoder based on encoding settingsr=rrFrrGFrE)rrr|)rJrs r8 get_encoderzConnectionPool.get_encodersQ''!!ZZ G4"JJ'8(C#ZZ(:EB"  r/c|j|jk\r td|xjdz c_|jdi|jS)zCreate a new connectionzToo many connectionsrxr7)rrrrrrss r8r,zConnectionPool.make_connection sO  $ $(<(< <!"89 9 !!Q&!$t$$>t'='=>>r/rcK|j|j4d{ |jj||j |r|j j|n?|xjdzc_|jd{ dddd{ydddd{y7#t$rYwxYw787)7#1d{7swYyxYww)z(Releases the connection back to the poolNrx) r&rr removeKeyErrorowns_connectionrr$rr>rs r8r$zConnectionPool.releases ::   ((// ; ##J/++22:> ))Q.) ++---!       .     s!C-CC-CCACCC C-*C+C-;C<C- C CCCC-C-C*C! C*&C-c4|j|jk(SrI)rrs r8r9zConnectionPool.owns_connection&s~~))r/inuse_connectionscK|j|j4d{|r!t|j|j}n |j}t j d|Dddid{}td|Dd}|r|dddd{y77.7 #1d{7swYyxYww)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. Nc3<K|]}|jywrIrr.rs r8r1z,ConnectionPool.disconnect..:sHj*'')Hreturn_exceptionsTc3BK|]}t|ts|ywrIrOrr.rs r8r1z,ConnectionPool.disconnect..=Ha:a+GH)r&rrrr rgathernext)rJr; connectionsresprUs r8r>zConnectionPool.disconnect)s ::   49//1I1I5 #99  HKH"&DH4H$OC        sW!B>B#B>AB)6B%7B) B>B'B>%B)'B>)B;/B2 0B;7B>r)r2r3r4r^ classmethodr r r?rrr rSrKr7rr&r2r4r,r$r9rUr>r7r/r8rrBs )d3i)c)))Z.8)-Rz*R"#R< "-*^B ? ****$r/c eZdZdZddeej fdedeede ede ejffd Z d Z d Z d Zd efd ZddefdZxZS)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) 2rrr queue_classc J||_||_|t| d||d|y)N)rrr7)rPrrrK)rJrrrrPrrWs r8rKzBlockingConnectionPool.__init__ds9'    -+   r/c|j|j|_ |jjd#tj $rYnwxYwg|_tj|_ yrI) rPrpool put_nowaitr QueueFull _connectionsr"r#rrss r8rzBlockingConnectionPool.resetvsl$$T%9%9:   $$T*$$   99;s?AAct|jdi|j}|jj||S)zMake a fresh connection.r7)rrrVr$rs r8r,z&BlockingConnectionPool.make_connections7*T**DT-C-CD    ,r/cJK|jd} tj|j4d{|jj d{}dddd{||j} |jd{ |jd{r tdd |S77i7[#1d{7swYkxYw#t j t jf$r tdwxYw7y7b#t$r[|jd{7|jd{7|jd{7r tddY|SwxYw#t$r|j|d{7wxYww)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. NzNo connection available.r(r))r&rrrSr|r QueueEmptyr&rr,rXrr>rr$r.s r8r2z%BlockingConnectionPool.get_connections   >$,,T\\: 3 3#'99==?2  3 3  --/J $$& & &  L#,,...)*?@dJ/A 32 3 3 3 3""G$8$89 >""<= = > ' /" L ++--- ((***#,,...)*@AtK/ L  ,,z* * *  sF##CCCC CC  C+C,C0F#E;DE;D/D0DF#CC C CC CC/D  F#E;DE80D31E8 E  E8"E%#E84E;5F#7E88E;;F FF  F#rc$K|j|j|s4|jd{|jj dy |jj |y7=#t j $rYywxYww)z)Releases the connection back to the pool.N)r&r9r>rSrTrrUrs r8r$zBlockingConnectionPool.releases ##J/ '') ) ) II  &   II  , *     s35BA5 BA74B7B  B B  Br;c6K|j|j4d{tjd|jDddid{}t d|Dd}|r|dddd{y7Z7.7 #1d{7swYyxYww)z(Disconnects all connections in the pool.Nc3<K|]}|jywrIrr>s r8r1z4BlockingConnectionPool.disconnect..sNj*'')Nr?r@Tc3BK|]}t|ts|ywrIrBrCs r8r1z4BlockingConnectionPool.disconnect..rErF)r&rrrGrVrH)rJr;rJrUs r8r>z!BlockingConnectionPool.disconnects ::   NDB*BBB- B8B9BBBB B BBr)r2r3r4r^rr LifoQueuerSr r QueuerKrr,r2r$rUr>rrs@r8rMrMBsF "!#-7+2+<+<   # z*  '--(  $0 3j * $ r/rM)urr%enumrrRrr"rrZrrrF itertoolsrtypesrtypingrrrrr r r r r rr urllib.parserrrrrredis.asyncio.retryr redis.backoffr redis.compatrrredis.exceptionsrrrrrrrrr r!r"r#r$r%r& redis.typingr'r( redis.utilsr)r*rBlockingIOError EWOULDBLOCKSSLWantReadErrorSSLWantWriteErrorSSLErrorrrr0rrrrSYM_LFrrEnumr1r6rrrrrr:rDr?r@rrarrrrArrrrrrrrrrUrrSrTrr5rr r rrMr7r/r8rrs  "    BA%#,".7 U&&!1LL! '#BGGIJ      !?    PN#T  %&&RCtIT)_@T8U'U!VVW?$?$DIIXQ:QhjJjZE, 5677!M M h  8 02NNOvvr+/J+/\22jVVr/ htnCS"'##!$%  CGC#v+)>$>? IU131=1he+,}}@f^fr/