PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/imh-python/lib/python3.9/site-packages/dogpile/cache
Viewing File: /opt/imh-python/lib/python3.9/site-packages/dogpile/cache/api.py
from __future__ import annotations import abc import enum import pickle import time from typing import Any from typing import Callable from typing import cast from typing import Literal from typing import Mapping from typing import NamedTuple from typing import Optional from typing import Sequence from typing import Union from ..util.typing import Self class NoValue(enum.Enum): """Describe a missing cache value. The :data:`.NO_VALUE` constant should be used. """ @property def payload(self) -> Self: return self def __repr__(self): """Ensure __repr__ is a consistent value in case NoValue is used to fill another cache key. """ return "<dogpile.cache.api.NoValue object>" def __bool__(self) -> Literal[False]: # pragma NO COVERAGE return False NO_VALUE = "NoValue" NoValueType = Literal[NoValue.NO_VALUE] NO_VALUE = NoValue.NO_VALUE """Value returned from :meth:`.CacheRegion.get` that describes a key not present.""" MetaDataType = Mapping[str, Any] KeyType = str """A cache key.""" ValuePayload = Any """An object to be placed in the cache against a key.""" KeyManglerType = Callable[[KeyType], KeyType] Serializer = Callable[[ValuePayload], bytes] Deserializer = Callable[[bytes], ValuePayload] class CantDeserializeException(Exception): """Exception indicating deserialization failed, and that caching should proceed to re-generate a value .. versionadded:: 1.2.0 """ class CacheMutex(abc.ABC): """Describes a mutexing object with acquire and release methods. This is an abstract base class; any object that has acquire/release methods may be used. .. versionadded:: 1.1 .. seealso:: :meth:`.CacheBackend.get_mutex` - the backend method that optionally returns this locking object. """ @abc.abstractmethod def acquire(self, wait: bool = True) -> bool: """Acquire the mutex. :param wait: if True, block until available, else return True/False immediately. :return: True if the lock succeeded. """ raise NotImplementedError() @abc.abstractmethod def release(self) -> None: """Release the mutex.""" raise NotImplementedError() @abc.abstractmethod def locked(self) -> bool: """Check if the mutex was acquired. :return: true if the lock is acquired. .. versionadded:: 1.1.2 """ raise NotImplementedError() @classmethod def __subclasshook__(cls, C): return hasattr(C, "acquire") and hasattr(C, "release") class CachedValue(NamedTuple): """Represent a value stored in the cache. :class:`.CachedValue` is a two-tuple of ``(payload, metadata)``, where ``metadata`` is dogpile.cache's tracking information ( currently the creation time). """ payload: ValuePayload """the actual cached value.""" metadata: MetaDataType """Metadata dictionary for the cached value. Prefer using accessors such as :attr:`.CachedValue.cached_time` rather than accessing this mapping directly. """ @property def cached_time(self) -> float: """The epoch (floating point time value) stored when this payload was cached. .. versionadded:: 1.3 """ return cast(float, self.metadata["ct"]) @property def age(self) -> float: """Returns the elapsed time in seconds as a `float` since the insertion of the value in the cache. This value is computed **dynamically** by subtracting the cached floating point epoch value from the value of ``time.time()``. .. versionadded:: 1.3 """ return time.time() - self.cached_time CacheReturnType = Union[CachedValue, NoValueType] """The non-serialized form of what may be returned from a backend get method. """ SerializedReturnType = Union[bytes, NoValueType] """the serialized form of what may be returned from a backend get method.""" BackendFormatted = Union[CacheReturnType, SerializedReturnType] """Describes the type returned from the :meth:`.CacheBackend.get` method.""" BackendSetType = Union[CachedValue, bytes] """Describes the value argument passed to the :meth:`.CacheBackend.set` method.""" BackendArguments = Mapping[str, Any] class CacheBackend: """Base class for backend implementations. Backends which set and get Python object values should subclass this backend. For backends in which the value that's stored is ultimately a stream of bytes, the :class:`.BytesBackend` should be used. """ key_mangler: Optional[Callable[[KeyType], KeyType]] = None """Key mangling function. May be None, or otherwise declared as an ordinary instance method. """ serializer: Union[None, Serializer] = None """Serializer function that will be used by default if not overridden by the region. .. versionadded:: 1.1 """ deserializer: Union[None, Deserializer] = None """deserializer function that will be used by default if not overridden by the region. .. versionadded:: 1.1 """ def __init__(self, arguments: BackendArguments): # pragma NO COVERAGE """Construct a new :class:`.CacheBackend`. Subclasses should override this to handle the given arguments. :param arguments: The ``arguments`` parameter passed to :func:`.make_registry`. """ raise NotImplementedError() @classmethod def from_config_dict( cls, config_dict: Mapping[str, Any], prefix: str ) -> Self: prefix_len = len(prefix) return cls( dict( (key[prefix_len:], config_dict[key]) for key in config_dict if key.startswith(prefix) ) ) def has_lock_timeout(self) -> bool: return False def get_mutex(self, key: KeyType) -> Optional[CacheMutex]: """Return an optional mutexing object for the given key. This object need only provide an ``acquire()`` and ``release()`` method. May return ``None``, in which case the dogpile lock will use a regular ``threading.Lock`` object to mutex concurrent threads for value creation. The default implementation returns ``None``. Different backends may want to provide various kinds of "mutex" objects, such as those which link to lock files, distributed mutexes, memcached semaphores, etc. Whatever kind of system is best suited for the scope and behavior of the caching backend. A mutex that takes the key into account will allow multiple regenerate operations across keys to proceed simultaneously, while a mutex that does not will serialize regenerate operations to just one at a time across all keys in the region. The latter approach, or a variant that involves a modulus of the given key's hash value, can be used as a means of throttling the total number of value recreation operations that may proceed at one time. """ return None def get(self, key: KeyType) -> BackendFormatted: # pragma NO COVERAGE """Retrieve an optionally serialized value from the cache. :param key: String key that was passed to the :meth:`.CacheRegion.get` method, which will also be processed by the "key mangling" function if one was present. :return: the Python object that corresponds to what was established via the :meth:`.CacheBackend.set` method, or the :data:`.NO_VALUE` constant if not present. If a serializer is in use, this method will only be called if the :meth:`.CacheBackend.get_serialized` method is not overridden. """ raise NotImplementedError() def get_multi( self, keys: Sequence[KeyType] ) -> Sequence[BackendFormatted]: # pragma NO COVERAGE """Retrieve multiple optionally serialized values from the cache. :param keys: sequence of string keys that was passed to the :meth:`.CacheRegion.get_multi` method, which will also be processed by the "key mangling" function if one was present. :return a list of values as would be returned individually via the :meth:`.CacheBackend.get` method, corresponding to the list of keys given. If a serializer is in use, this method will only be called if the :meth:`.CacheBackend.get_serialized_multi` method is not overridden. .. versionadded:: 0.5.0 """ raise NotImplementedError() def get_serialized(self, key: KeyType) -> SerializedReturnType: """Retrieve a serialized value from the cache. :param key: String key that was passed to the :meth:`.CacheRegion.get` method, which will also be processed by the "key mangling" function if one was present. :return: a bytes object, or :data:`.NO_VALUE` constant if not present. The default implementation of this method for :class:`.CacheBackend` returns the value of the :meth:`.CacheBackend.get` method. .. versionadded:: 1.1 .. seealso:: :class:`.BytesBackend` """ return cast(SerializedReturnType, self.get(key)) def get_serialized_multi( self, keys: Sequence[KeyType] ) -> Sequence[SerializedReturnType]: # pragma NO COVERAGE """Retrieve multiple serialized values from the cache. :param keys: sequence of string keys that was passed to the :meth:`.CacheRegion.get_multi` method, which will also be processed by the "key mangling" function if one was present. :return: list of bytes objects The default implementation of this method for :class:`.CacheBackend` returns the value of the :meth:`.CacheBackend.get_multi` method. .. versionadded:: 1.1 .. seealso:: :class:`.BytesBackend` """ return cast(Sequence[SerializedReturnType], self.get_multi(keys)) def set( self, key: KeyType, value: BackendSetType ) -> None: # pragma NO COVERAGE """Set an optionally serialized value in the cache. :param key: String key that was passed to the :meth:`.CacheRegion.set` method, which will also be processed by the "key mangling" function if one was present. :param value: The optionally serialized :class:`.CachedValue` object. May be an instance of :class:`.CachedValue` or a bytes object depending on if a serializer is in use with the region and if the :meth:`.CacheBackend.set_serialized` method is not overridden. .. seealso:: :meth:`.CacheBackend.set_serialized` """ raise NotImplementedError() def set_serialized( self, key: KeyType, value: bytes ) -> None: # pragma NO COVERAGE """Set a serialized value in the cache. :param key: String key that was passed to the :meth:`.CacheRegion.set` method, which will also be processed by the "key mangling" function if one was present. :param value: a bytes object to be stored. The default implementation of this method for :class:`.CacheBackend` calls upon the :meth:`.CacheBackend.set` method. .. versionadded:: 1.1 .. seealso:: :class:`.BytesBackend` """ self.set(key, value) def set_multi( self, mapping: Mapping[KeyType, BackendSetType] ) -> None: # pragma NO COVERAGE """Set multiple values in the cache. :param mapping: a dict in which the key will be whatever was passed to the :meth:`.CacheRegion.set_multi` method, processed by the "key mangling" function, if any. When implementing a new :class:`.CacheBackend` or cutomizing via :class:`.ProxyBackend`, be aware that when this method is invoked by :meth:`.Region.get_or_create_multi`, the ``mapping`` values are the same ones returned to the upstream caller. If the subclass alters the values in any way, it must not do so 'in-place' on the ``mapping`` dict -- that will have the undesirable effect of modifying the returned values as well. If a serializer is in use, this method will only be called if the :meth:`.CacheBackend.set_serialized_multi` method is not overridden. .. versionadded:: 0.5.0 """ raise NotImplementedError() def set_serialized_multi( self, mapping: Mapping[KeyType, bytes] ) -> None: # pragma NO COVERAGE """Set multiple serialized values in the cache. :param mapping: a dict in which the key will be whatever was passed to the :meth:`.CacheRegion.set_multi` method, processed by the "key mangling" function, if any. When implementing a new :class:`.CacheBackend` or cutomizing via :class:`.ProxyBackend`, be aware that when this method is invoked by :meth:`.Region.get_or_create_multi`, the ``mapping`` values are the same ones returned to the upstream caller. If the subclass alters the values in any way, it must not do so 'in-place' on the ``mapping`` dict -- that will have the undesirable effect of modifying the returned values as well. .. versionadded:: 1.1 The default implementation of this method for :class:`.CacheBackend` calls upon the :meth:`.CacheBackend.set_multi` method. .. seealso:: :class:`.BytesBackend` """ self.set_multi(mapping) def delete(self, key: KeyType) -> None: # pragma NO COVERAGE """Delete a value from the cache. :param key: String key that was passed to the :meth:`.CacheRegion.delete` method, which will also be processed by the "key mangling" function if one was present. The behavior here should be idempotent, that is, can be called any number of times regardless of whether or not the key exists. """ raise NotImplementedError() def delete_multi( self, keys: Sequence[KeyType] ) -> None: # pragma NO COVERAGE """Delete multiple values from the cache. :param keys: sequence of string keys that was passed to the :meth:`.CacheRegion.delete_multi` method, which will also be processed by the "key mangling" function if one was present. The behavior here should be idempotent, that is, can be called any number of times regardless of whether or not the key exists. .. versionadded:: 0.5.0 """ raise NotImplementedError() class DefaultSerialization: serializer: Union[None, Serializer] = staticmethod( # type: ignore pickle.dumps ) deserializer: Union[None, Deserializer] = staticmethod( # type: ignore pickle.loads ) class BytesBackend(DefaultSerialization, CacheBackend): """A cache backend that receives and returns series of bytes. This backend only supports the "serialized" form of values; subclasses should implement :meth:`.BytesBackend.get_serialized`, :meth:`.BytesBackend.get_serialized_multi`, :meth:`.BytesBackend.set_serialized`, :meth:`.BytesBackend.set_serialized_multi`. .. versionadded:: 1.1 """ def get_serialized(self, key: KeyType) -> SerializedReturnType: """Retrieve a serialized value from the cache. :param key: String key that was passed to the :meth:`.CacheRegion.get` method, which will also be processed by the "key mangling" function if one was present. :return: a bytes object, or :data:`.NO_VALUE` constant if not present. .. versionadded:: 1.1 """ raise NotImplementedError() def get_serialized_multi( self, keys: Sequence[KeyType] ) -> Sequence[SerializedReturnType]: # pragma NO COVERAGE """Retrieve multiple serialized values from the cache. :param keys: sequence of string keys that was passed to the :meth:`.CacheRegion.get_multi` method, which will also be processed by the "key mangling" function if one was present. :return: list of bytes objects .. versionadded:: 1.1 """ raise NotImplementedError() def set_serialized( self, key: KeyType, value: bytes ) -> None: # pragma NO COVERAGE """Set a serialized value in the cache. :param key: String key that was passed to the :meth:`.CacheRegion.set` method, which will also be processed by the "key mangling" function if one was present. :param value: a bytes object to be stored. .. versionadded:: 1.1 """ raise NotImplementedError() def set_serialized_multi( self, mapping: Mapping[KeyType, bytes] ) -> None: # pragma NO COVERAGE """Set multiple serialized values in the cache. :param mapping: a dict in which the key will be whatever was passed to the :meth:`.CacheRegion.set_multi` method, processed by the "key mangling" function, if any. When implementing a new :class:`.CacheBackend` or cutomizing via :class:`.ProxyBackend`, be aware that when this method is invoked by :meth:`.Region.get_or_create_multi`, the ``mapping`` values are the same ones returned to the upstream caller. If the subclass alters the values in any way, it must not do so 'in-place' on the ``mapping`` dict -- that will have the undesirable effect of modifying the returned values as well. .. versionadded:: 1.1 """ raise NotImplementedError()