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/wrapt
Viewing File: /opt/imh-python/lib/python3.9/site-packages/wrapt/wrappers.py
import sys import operator import inspect PY2 = sys.version_info[0] == 2 if PY2: string_types = basestring, else: string_types = str, def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" return meta("NewBase", bases, {}) class _ObjectProxyMethods(object): # We use properties to override the values of __module__ and # __doc__. If we add these in ObjectProxy, the derived class # __dict__ will still be setup to have string variants of these # attributes and the rules of descriptors means that they appear to # take precedence over the properties in the base class. To avoid # that, we copy the properties into the derived class type itself # via a meta class. In that way the properties will always take # precedence. @property def __module__(self): return self.__wrapped__.__module__ @__module__.setter def __module__(self, value): self.__wrapped__.__module__ = value @property def __doc__(self): return self.__wrapped__.__doc__ @__doc__.setter def __doc__(self, value): self.__wrapped__.__doc__ = value # We similar use a property for __dict__. We need __dict__ to be # explicit to ensure that vars() works as expected. @property def __dict__(self): return self.__wrapped__.__dict__ # Need to also propagate the special __weakref__ attribute for case # where decorating classes which will define this. If do not define # it and use a function like inspect.getmembers() on a decorator # class it will fail. This can't be in the derived classes. @property def __weakref__(self): return self.__wrapped__.__weakref__ class _ObjectProxyMetaType(type): def __new__(cls, name, bases, dictionary): # Copy our special properties into the class so that they # always take precedence over attributes of the same name added # during construction of a derived class. This is to save # duplicating the implementation for them in all derived classes. dictionary.update(vars(_ObjectProxyMethods)) return type.__new__(cls, name, bases, dictionary) class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): __slots__ = '__wrapped__' def __init__(self, wrapped): object.__setattr__(self, '__wrapped__', wrapped) # Python 3.2+ has the __qualname__ attribute, but it does not # allow it to be overridden using a property and it must instead # be an actual string object instead. try: object.__setattr__(self, '__qualname__', wrapped.__qualname__) except AttributeError: pass # Python 3.10 onwards also does not allow itself to be overridden # using a property and it must instead be set explicitly. try: object.__setattr__(self, '__annotations__', wrapped.__annotations__) except AttributeError: pass def __self_setattr__(self, name, value): object.__setattr__(self, name, value) @property def __name__(self): return self.__wrapped__.__name__ @__name__.setter def __name__(self, value): self.__wrapped__.__name__ = value @property def __class__(self): return self.__wrapped__.__class__ @__class__.setter def __class__(self, value): self.__wrapped__.__class__ = value def __dir__(self): return dir(self.__wrapped__) def __str__(self): return str(self.__wrapped__) if not PY2: def __bytes__(self): return bytes(self.__wrapped__) def __repr__(self): return '<{} at 0x{:x} for {} at 0x{:x}>'.format( type(self).__name__, id(self), type(self.__wrapped__).__name__, id(self.__wrapped__)) def __format__(self, format_spec): return format(self.__wrapped__, format_spec) def __reversed__(self): return reversed(self.__wrapped__) if not PY2: def __round__(self, ndigits=None): return round(self.__wrapped__, ndigits) if sys.hexversion >= 0x03070000: def __mro_entries__(self, bases): return (self.__wrapped__,) def __lt__(self, other): return self.__wrapped__ < other def __le__(self, other): return self.__wrapped__ <= other def __eq__(self, other): return self.__wrapped__ == other def __ne__(self, other): return self.__wrapped__ != other def __gt__(self, other): return self.__wrapped__ > other def __ge__(self, other): return self.__wrapped__ >= other def __hash__(self): return hash(self.__wrapped__) def __nonzero__(self): return bool(self.__wrapped__) def __bool__(self): return bool(self.__wrapped__) def __setattr__(self, name, value): if name.startswith('_self_'): object.__setattr__(self, name, value) elif name == '__wrapped__': object.__setattr__(self, name, value) try: object.__delattr__(self, '__qualname__') except AttributeError: pass try: object.__setattr__(self, '__qualname__', value.__qualname__) except AttributeError: pass try: object.__delattr__(self, '__annotations__') except AttributeError: pass try: object.__setattr__(self, '__annotations__', value.__annotations__) except AttributeError: pass elif name == '__qualname__': setattr(self.__wrapped__, name, value) object.__setattr__(self, name, value) elif name == '__annotations__': setattr(self.__wrapped__, name, value) object.__setattr__(self, name, value) elif hasattr(type(self), name): object.__setattr__(self, name, value) else: setattr(self.__wrapped__, name, value) def __getattr__(self, name): # If we are being to lookup '__wrapped__' then the # '__init__()' method cannot have been called. if name == '__wrapped__': raise ValueError('wrapper has not been initialised') return getattr(self.__wrapped__, name) def __delattr__(self, name): if name.startswith('_self_'): object.__delattr__(self, name) elif name == '__wrapped__': raise TypeError('__wrapped__ must be an object') elif name == '__qualname__': object.__delattr__(self, name) delattr(self.__wrapped__, name) elif hasattr(type(self), name): object.__delattr__(self, name) else: delattr(self.__wrapped__, name) def __add__(self, other): return self.__wrapped__ + other def __sub__(self, other): return self.__wrapped__ - other def __mul__(self, other): return self.__wrapped__ * other def __div__(self, other): return operator.div(self.__wrapped__, other) def __truediv__(self, other): return operator.truediv(self.__wrapped__, other) def __floordiv__(self, other): return self.__wrapped__ // other def __mod__(self, other): return self.__wrapped__ % other def __divmod__(self, other): return divmod(self.__wrapped__, other) def __pow__(self, other, *args): return pow(self.__wrapped__, other, *args) def __lshift__(self, other): return self.__wrapped__ << other def __rshift__(self, other): return self.__wrapped__ >> other def __and__(self, other): return self.__wrapped__ & other def __xor__(self, other): return self.__wrapped__ ^ other def __or__(self, other): return self.__wrapped__ | other def __radd__(self, other): return other + self.__wrapped__ def __rsub__(self, other): return other - self.__wrapped__ def __rmul__(self, other): return other * self.__wrapped__ def __rdiv__(self, other): return operator.div(other, self.__wrapped__) def __rtruediv__(self, other): return operator.truediv(other, self.__wrapped__) def __rfloordiv__(self, other): return other // self.__wrapped__ def __rmod__(self, other): return other % self.__wrapped__ def __rdivmod__(self, other): return divmod(other, self.__wrapped__) def __rpow__(self, other, *args): return pow(other, self.__wrapped__, *args) def __rlshift__(self, other): return other << self.__wrapped__ def __rrshift__(self, other): return other >> self.__wrapped__ def __rand__(self, other): return other & self.__wrapped__ def __rxor__(self, other): return other ^ self.__wrapped__ def __ror__(self, other): return other | self.__wrapped__ def __iadd__(self, other): self.__wrapped__ += other return self def __isub__(self, other): self.__wrapped__ -= other return self def __imul__(self, other): self.__wrapped__ *= other return self def __idiv__(self, other): self.__wrapped__ = operator.idiv(self.__wrapped__, other) return self def __itruediv__(self, other): self.__wrapped__ = operator.itruediv(self.__wrapped__, other) return self def __ifloordiv__(self, other): self.__wrapped__ //= other return self def __imod__(self, other): self.__wrapped__ %= other return self def __ipow__(self, other): self.__wrapped__ **= other return self def __ilshift__(self, other): self.__wrapped__ <<= other return self def __irshift__(self, other): self.__wrapped__ >>= other return self def __iand__(self, other): self.__wrapped__ &= other return self def __ixor__(self, other): self.__wrapped__ ^= other return self def __ior__(self, other): self.__wrapped__ |= other return self def __neg__(self): return -self.__wrapped__ def __pos__(self): return +self.__wrapped__ def __abs__(self): return abs(self.__wrapped__) def __invert__(self): return ~self.__wrapped__ def __int__(self): return int(self.__wrapped__) def __long__(self): return long(self.__wrapped__) def __float__(self): return float(self.__wrapped__) def __complex__(self): return complex(self.__wrapped__) def __oct__(self): return oct(self.__wrapped__) def __hex__(self): return hex(self.__wrapped__) def __index__(self): return operator.index(self.__wrapped__) def __len__(self): return len(self.__wrapped__) def __contains__(self, value): return value in self.__wrapped__ def __getitem__(self, key): return self.__wrapped__[key] def __setitem__(self, key, value): self.__wrapped__[key] = value def __delitem__(self, key): del self.__wrapped__[key] def __getslice__(self, i, j): return self.__wrapped__[i:j] def __setslice__(self, i, j, value): self.__wrapped__[i:j] = value def __delslice__(self, i, j): del self.__wrapped__[i:j] def __enter__(self): return self.__wrapped__.__enter__() def __exit__(self, *args, **kwargs): return self.__wrapped__.__exit__(*args, **kwargs) def __iter__(self): return iter(self.__wrapped__) def __copy__(self): raise NotImplementedError('object proxy must define __copy__()') def __deepcopy__(self, memo): raise NotImplementedError('object proxy must define __deepcopy__()') def __reduce__(self): raise NotImplementedError( 'object proxy must define __reduce__()') def __reduce_ex__(self, protocol): raise NotImplementedError( 'object proxy must define __reduce_ex__()') class CallableObjectProxy(ObjectProxy): def __call__(*args, **kwargs): def _unpack_self(self, *args): return self, args self, args = _unpack_self(*args) return self.__wrapped__(*args, **kwargs) class PartialCallableObjectProxy(ObjectProxy): def __init__(*args, **kwargs): def _unpack_self(self, *args): return self, args self, args = _unpack_self(*args) if len(args) < 1: raise TypeError('partial type takes at least one argument') wrapped, args = args[0], args[1:] if not callable(wrapped): raise TypeError('the first argument must be callable') super(PartialCallableObjectProxy, self).__init__(wrapped) self._self_args = args self._self_kwargs = kwargs def __call__(*args, **kwargs): def _unpack_self(self, *args): return self, args self, args = _unpack_self(*args) _args = self._self_args + args _kwargs = dict(self._self_kwargs) _kwargs.update(kwargs) return self.__wrapped__(*_args, **_kwargs) class _FunctionWrapperBase(ObjectProxy): __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', '_self_binding', '_self_parent', '_self_owner') def __init__(self, wrapped, instance, wrapper, enabled=None, binding='callable', parent=None, owner=None): super(_FunctionWrapperBase, self).__init__(wrapped) object.__setattr__(self, '_self_instance', instance) object.__setattr__(self, '_self_wrapper', wrapper) object.__setattr__(self, '_self_enabled', enabled) object.__setattr__(self, '_self_binding', binding) object.__setattr__(self, '_self_parent', parent) object.__setattr__(self, '_self_owner', owner) def __get__(self, instance, owner): # This method is actually doing double duty for both unbound and bound # derived wrapper classes. It should possibly be broken up and the # distinct functionality moved into the derived classes. Can't do that # straight away due to some legacy code which is relying on it being # here in this base class. # # The distinguishing attribute which determines whether we are being # called in an unbound or bound wrapper is the parent attribute. If # binding has never occurred, then the parent will be None. # # First therefore, is if we are called in an unbound wrapper. In this # case we perform the binding. # # We have two special cases to worry about here. These are where we are # decorating a class or builtin function as neither provide a __get__() # method to call. In this case we simply return self. # # Note that we otherwise still do binding even if instance is None and # accessing an unbound instance method from a class. This is because we # need to be able to later detect that specific case as we will need to # extract the instance from the first argument of those passed in. if self._self_parent is None: # Technically can probably just check for existence of __get__ on # the wrapped object, but this is more explicit. if self._self_binding == 'builtin': return self if self._self_binding == "class": return self binder = getattr(self.__wrapped__, '__get__', None) if binder is None: return self descriptor = binder(instance, owner) return self.__bound_function_wrapper__(descriptor, instance, self._self_wrapper, self._self_enabled, self._self_binding, self, owner) # Now we have the case of binding occurring a second time on what was # already a bound function. In this case we would usually return # ourselves again. This mirrors what Python does. # # The special case this time is where we were originally bound with an # instance of None and we were likely an instance method. In that case # we rebind against the original wrapped function from the parent again. if self._self_instance is None and self._self_binding in ('function', 'instancemethod', 'callable'): descriptor = self._self_parent.__wrapped__.__get__( instance, owner) return self._self_parent.__bound_function_wrapper__( descriptor, instance, self._self_wrapper, self._self_enabled, self._self_binding, self._self_parent, owner) return self def __call__(*args, **kwargs): def _unpack_self(self, *args): return self, args self, args = _unpack_self(*args) # If enabled has been specified, then evaluate it at this point # and if the wrapper is not to be executed, then simply return # the bound function rather than a bound wrapper for the bound # function. When evaluating enabled, if it is callable we call # it, otherwise we evaluate it as a boolean. if self._self_enabled is not None: if callable(self._self_enabled): if not self._self_enabled(): return self.__wrapped__(*args, **kwargs) elif not self._self_enabled: return self.__wrapped__(*args, **kwargs) # This can occur where initial function wrapper was applied to # a function that was already bound to an instance. In that case # we want to extract the instance from the function and use it. if self._self_binding in ('function', 'instancemethod', 'classmethod', 'callable'): if self._self_instance is None: instance = getattr(self.__wrapped__, '__self__', None) if instance is not None: return self._self_wrapper(self.__wrapped__, instance, args, kwargs) # This is generally invoked when the wrapped function is being # called as a normal function and is not bound to a class as an # instance method. This is also invoked in the case where the # wrapped function was a method, but this wrapper was in turn # wrapped using the staticmethod decorator. return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs) def __set_name__(self, owner, name): # This is a special method use to supply information to # descriptors about what the name of variable in a class # definition is. Not wanting to add this to ObjectProxy as not # sure of broader implications of doing that. Thus restrict to # FunctionWrapper used by decorators. if hasattr(self.__wrapped__, "__set_name__"): self.__wrapped__.__set_name__(owner, name) def __instancecheck__(self, instance): # This is a special method used by isinstance() to make checks # instance of the `__wrapped__`. return isinstance(instance, self.__wrapped__) def __subclasscheck__(self, subclass): # This is a special method used by issubclass() to make checks # about inheritance of classes. We need to upwrap any object # proxy. Not wanting to add this to ObjectProxy as not sure of # broader implications of doing that. Thus restrict to # FunctionWrapper used by decorators. if hasattr(subclass, "__wrapped__"): return issubclass(subclass.__wrapped__, self.__wrapped__) else: return issubclass(subclass, self.__wrapped__) class BoundFunctionWrapper(_FunctionWrapperBase): def __call__(*args, **kwargs): def _unpack_self(self, *args): return self, args self, args = _unpack_self(*args) # If enabled has been specified, then evaluate it at this point and if # the wrapper is not to be executed, then simply return the bound # function rather than a bound wrapper for the bound function. When # evaluating enabled, if it is callable we call it, otherwise we # evaluate it as a boolean. if self._self_enabled is not None: if callable(self._self_enabled): if not self._self_enabled(): return self.__wrapped__(*args, **kwargs) elif not self._self_enabled: return self.__wrapped__(*args, **kwargs) # We need to do things different depending on whether we are likely # wrapping an instance method vs a static method or class method. if self._self_binding == 'function': if self._self_instance is None and args: instance, newargs = args[0], args[1:] if isinstance(instance, self._self_owner): wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) return self._self_wrapper(wrapped, instance, newargs, kwargs) return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs) elif self._self_binding == 'callable': if self._self_instance is None: # This situation can occur where someone is calling the # instancemethod via the class type and passing the instance as # the first argument. We need to shift the args before making # the call to the wrapper and effectively bind the instance to # the wrapped function using a partial so the wrapper doesn't # see anything as being different. if not args: raise TypeError('missing 1 required positional argument') instance, args = args[0], args[1:] wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) return self._self_wrapper(wrapped, instance, args, kwargs) return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs) else: # As in this case we would be dealing with a classmethod or # staticmethod, then _self_instance will only tell us whether # when calling the classmethod or staticmethod they did it via an # instance of the class it is bound to and not the case where # done by the class type itself. We thus ignore _self_instance # and use the __self__ attribute of the bound function instead. # For a classmethod, this means instance will be the class type # and for a staticmethod it will be None. This is probably the # more useful thing we can pass through even though we loose # knowledge of whether they were called on the instance vs the # class type, as it reflects what they have available in the # decoratored function. instance = getattr(self.__wrapped__, '__self__', None) return self._self_wrapper(self.__wrapped__, instance, args, kwargs) class FunctionWrapper(_FunctionWrapperBase): __bound_function_wrapper__ = BoundFunctionWrapper def __init__(self, wrapped, wrapper, enabled=None): # What it is we are wrapping here could be anything. We need to # try and detect specific cases though. In particular, we need # to detect when we are given something that is a method of a # class. Further, we need to know when it is likely an instance # method, as opposed to a class or static method. This can # become problematic though as there isn't strictly a fool proof # method of knowing. # # The situations we could encounter when wrapping a method are: # # 1. The wrapper is being applied as part of a decorator which # is a part of the class definition. In this case what we are # given is the raw unbound function, classmethod or staticmethod # wrapper objects. # # The problem here is that we will not know we are being applied # in the context of the class being set up. This becomes # important later for the case of an instance method, because in # that case we just see it as a raw function and can't # distinguish it from wrapping a normal function outside of # a class context. # # 2. The wrapper is being applied when performing monkey # patching of the class type afterwards and the method to be # wrapped was retrieved direct from the __dict__ of the class # type. This is effectively the same as (1) above. # # 3. The wrapper is being applied when performing monkey # patching of the class type afterwards and the method to be # wrapped was retrieved from the class type. In this case # binding will have been performed where the instance against # which the method is bound will be None at that point. # # This case is a problem because we can no longer tell if the # method was a static method, plus if using Python3, we cannot # tell if it was an instance method as the concept of an # unnbound method no longer exists. # # 4. The wrapper is being applied when performing monkey # patching of an instance of a class. In this case binding will # have been perfomed where the instance was not None. # # This case is a problem because we can no longer tell if the # method was a static method. # # Overall, the best we can do is look at the original type of the # object which was wrapped prior to any binding being done and # see if it is an instance of classmethod or staticmethod. In # the case where other decorators are between us and them, if # they do not propagate the __class__ attribute so that the # isinstance() checks works, then likely this will do the wrong # thing where classmethod and staticmethod are used. # # Since it is likely to be very rare that anyone even puts # decorators around classmethod and staticmethod, likelihood of # that being an issue is very small, so we accept it and suggest # that those other decorators be fixed. It is also only an issue # if a decorator wants to actually do things with the arguments. # # As to not being able to identify static methods properly, we # just hope that that isn't something people are going to want # to wrap, or if they do suggest they do it the correct way by # ensuring that it is decorated in the class definition itself, # or patch it in the __dict__ of the class type. # # So to get the best outcome we can, whenever we aren't sure what # it is, we label it as a 'callable'. If it was already bound and # that is rebound later, we assume that it will be an instance # method and try and cope with the possibility that the 'self' # argument it being passed as an explicit argument and shuffle # the arguments around to extract 'self' for use as the instance. binding = None if isinstance(wrapped, _FunctionWrapperBase): binding = wrapped._self_binding if not binding: if inspect.isbuiltin(wrapped): binding = 'builtin' elif inspect.isfunction(wrapped): binding = 'function' elif inspect.isclass(wrapped): binding = 'class' elif isinstance(wrapped, classmethod): binding = 'classmethod' elif isinstance(wrapped, staticmethod): binding = 'staticmethod' elif hasattr(wrapped, '__self__'): if inspect.isclass(wrapped.__self__): binding = 'classmethod' elif inspect.ismethod(wrapped): binding = 'instancemethod' else: binding = 'callable' else: binding = 'callable' super(FunctionWrapper, self).__init__(wrapped, None, wrapper, enabled, binding)