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/numpy/f2py
Viewing File: /opt/imh-python/lib/python3.9/site-packages/numpy/f2py/auxfuncs.py
#!/usr/bin/env python3 """ Auxiliary functions for f2py2e. Copyright 1999,2000 Pearu Peterson all rights reserved, Pearu Peterson <pearu@ioc.ee> Permission to use, modify, and distribute this software is given under the terms of the NumPy (BSD style) LICENSE. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. $Date: 2005/07/24 19:01:55 $ Pearu Peterson """ import pprint import sys import re import types from functools import reduce from copy import deepcopy from . import __version__ from . import cfuncs __all__ = [ 'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle', 'getargs2', 'getcallprotoargument', 'getcallstatement', 'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode', 'getusercode1', 'getdimension', 'hasbody', 'hascallstatement', 'hascommon', 'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote', 'isallocatable', 'isarray', 'isarrayofstrings', 'ischaracter', 'ischaracterarray', 'ischaracter_or_characterarray', 'iscomplex', 'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn', 'isdouble', 'isdummyroutine', 'isexternal', 'isfunction', 'isfunction_wrap', 'isint1', 'isint1array', 'isinteger', 'isintent_aux', 'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict', 'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace', 'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical', 'islogicalfunction', 'islong_complex', 'islong_double', 'islong_doublefunction', 'islong_long', 'islong_longfunction', 'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isrequired', 'isroutine', 'isscalar', 'issigned_long_longarray', 'isstring', 'isstringarray', 'isstring_or_stringarray', 'isstringfunction', 'issubroutine', 'get_f2py_modulename', 'issubroutine_wrap', 'isthreadsafe', 'isunsigned', 'isunsigned_char', 'isunsigned_chararray', 'isunsigned_long_long', 'isunsigned_long_longarray', 'isunsigned_short', 'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess', 'replace', 'show', 'stripcomma', 'throw_error', 'isattr_value', 'deep_merge' ] f2py_version = __version__.version errmess = sys.stderr.write show = pprint.pprint options = {} debugoptions = [] wrapfuncs = 1 def outmess(t): if options.get('verbose', 1): sys.stdout.write(t) def debugcapi(var): return 'capi' in debugoptions def _ischaracter(var): return 'typespec' in var and var['typespec'] == 'character' and \ not isexternal(var) def _isstring(var): return 'typespec' in var and var['typespec'] == 'character' and \ not isexternal(var) def ischaracter_or_characterarray(var): return _ischaracter(var) and 'charselector' not in var def ischaracter(var): return ischaracter_or_characterarray(var) and not isarray(var) def ischaracterarray(var): return ischaracter_or_characterarray(var) and isarray(var) def isstring_or_stringarray(var): return _ischaracter(var) and 'charselector' in var def isstring(var): return isstring_or_stringarray(var) and not isarray(var) def isstringarray(var): return isstring_or_stringarray(var) and isarray(var) def isarrayofstrings(var): # obsolete? # leaving out '*' for now so that `character*(*) a(m)` and `character # a(m,*)` are treated differently. Luckily `character**` is illegal. return isstringarray(var) and var['dimension'][-1] == '(*)' def isarray(var): return 'dimension' in var and not isexternal(var) def isscalar(var): return not (isarray(var) or isstring(var) or isexternal(var)) def iscomplex(var): return isscalar(var) and \ var.get('typespec') in ['complex', 'double complex'] def islogical(var): return isscalar(var) and var.get('typespec') == 'logical' def isinteger(var): return isscalar(var) and var.get('typespec') == 'integer' def isreal(var): return isscalar(var) and var.get('typespec') == 'real' def get_kind(var): try: return var['kindselector']['*'] except KeyError: try: return var['kindselector']['kind'] except KeyError: pass def isint1(var): return var.get('typespec') == 'integer' \ and get_kind(var) == '1' and not isarray(var) def islong_long(var): if not isscalar(var): return 0 if var.get('typespec') not in ['integer', 'logical']: return 0 return get_kind(var) == '8' def isunsigned_char(var): if not isscalar(var): return 0 if var.get('typespec') != 'integer': return 0 return get_kind(var) == '-1' def isunsigned_short(var): if not isscalar(var): return 0 if var.get('typespec') != 'integer': return 0 return get_kind(var) == '-2' def isunsigned(var): if not isscalar(var): return 0 if var.get('typespec') != 'integer': return 0 return get_kind(var) == '-4' def isunsigned_long_long(var): if not isscalar(var): return 0 if var.get('typespec') != 'integer': return 0 return get_kind(var) == '-8' def isdouble(var): if not isscalar(var): return 0 if not var.get('typespec') == 'real': return 0 return get_kind(var) == '8' def islong_double(var): if not isscalar(var): return 0 if not var.get('typespec') == 'real': return 0 return get_kind(var) == '16' def islong_complex(var): if not iscomplex(var): return 0 return get_kind(var) == '32' def iscomplexarray(var): return isarray(var) and \ var.get('typespec') in ['complex', 'double complex'] def isint1array(var): return isarray(var) and var.get('typespec') == 'integer' \ and get_kind(var) == '1' def isunsigned_chararray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '-1' def isunsigned_shortarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '-2' def isunsignedarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '-4' def isunsigned_long_longarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '-8' def issigned_chararray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '1' def issigned_shortarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '2' def issigned_array(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '4' def issigned_long_longarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var) == '8' def isallocatable(var): return 'attrspec' in var and 'allocatable' in var['attrspec'] def ismutable(var): return not ('dimension' not in var or isstring(var)) def ismoduleroutine(rout): return 'modulename' in rout def ismodule(rout): return 'block' in rout and 'module' == rout['block'] def isfunction(rout): return 'block' in rout and 'function' == rout['block'] def isfunction_wrap(rout): if isintent_c(rout): return 0 return wrapfuncs and isfunction(rout) and (not isexternal(rout)) def issubroutine(rout): return 'block' in rout and 'subroutine' == rout['block'] def issubroutine_wrap(rout): if isintent_c(rout): return 0 return issubroutine(rout) and hasassumedshape(rout) def isattr_value(var): return 'value' in var.get('attrspec', []) def hasassumedshape(rout): if rout.get('hasassumedshape'): return True for a in rout['args']: for d in rout['vars'].get(a, {}).get('dimension', []): if d == ':': rout['hasassumedshape'] = True return True return False def requiresf90wrapper(rout): return ismoduleroutine(rout) or hasassumedshape(rout) def isroutine(rout): return isfunction(rout) or issubroutine(rout) def islogicalfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return islogical(rout['vars'][a]) return 0 def islong_longfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return islong_long(rout['vars'][a]) return 0 def islong_doublefunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return islong_double(rout['vars'][a]) return 0 def iscomplexfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return iscomplex(rout['vars'][a]) return 0 def iscomplexfunction_warn(rout): if iscomplexfunction(rout): outmess("""\ ************************************************************** Warning: code with a function returning complex value may not work correctly with your Fortran compiler. When using GNU gcc/g77 compilers, codes should work correctly for callbacks with: f2py -c -DF2PY_CB_RETURNCOMPLEX **************************************************************\n""") return 1 return 0 def isstringfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return isstring(rout['vars'][a]) return 0 def hasexternals(rout): return 'externals' in rout and rout['externals'] def isthreadsafe(rout): return 'f2pyenhancements' in rout and \ 'threadsafe' in rout['f2pyenhancements'] def hasvariables(rout): return 'vars' in rout and rout['vars'] def isoptional(var): return ('attrspec' in var and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var) def isexternal(var): return 'attrspec' in var and 'external' in var['attrspec'] def getdimension(var): dimpattern = r"\((.*?)\)" if 'attrspec' in var.keys(): if any('dimension' in s for s in var['attrspec']): return [re.findall(dimpattern, v) for v in var['attrspec']][0] def isrequired(var): return not isoptional(var) and isintent_nothide(var) def isintent_in(var): if 'intent' not in var: return 1 if 'hide' in var['intent']: return 0 if 'inplace' in var['intent']: return 0 if 'in' in var['intent']: return 1 if 'out' in var['intent']: return 0 if 'inout' in var['intent']: return 0 if 'outin' in var['intent']: return 0 return 1 def isintent_inout(var): return ('intent' in var and ('inout' in var['intent'] or 'outin' in var['intent']) and 'in' not in var['intent'] and 'hide' not in var['intent'] and 'inplace' not in var['intent']) def isintent_out(var): return 'out' in var.get('intent', []) def isintent_hide(var): return ('intent' in var and ('hide' in var['intent'] or ('out' in var['intent'] and 'in' not in var['intent'] and (not l_or(isintent_inout, isintent_inplace)(var))))) def isintent_nothide(var): return not isintent_hide(var) def isintent_c(var): return 'c' in var.get('intent', []) def isintent_cache(var): return 'cache' in var.get('intent', []) def isintent_copy(var): return 'copy' in var.get('intent', []) def isintent_overwrite(var): return 'overwrite' in var.get('intent', []) def isintent_callback(var): return 'callback' in var.get('intent', []) def isintent_inplace(var): return 'inplace' in var.get('intent', []) def isintent_aux(var): return 'aux' in var.get('intent', []) def isintent_aligned4(var): return 'aligned4' in var.get('intent', []) def isintent_aligned8(var): return 'aligned8' in var.get('intent', []) def isintent_aligned16(var): return 'aligned16' in var.get('intent', []) isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT', isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE', isintent_cache: 'INTENT_CACHE', isintent_c: 'INTENT_C', isoptional: 'OPTIONAL', isintent_inplace: 'INTENT_INPLACE', isintent_aligned4: 'INTENT_ALIGNED4', isintent_aligned8: 'INTENT_ALIGNED8', isintent_aligned16: 'INTENT_ALIGNED16', } def isprivate(var): return 'attrspec' in var and 'private' in var['attrspec'] def hasinitvalue(var): return '=' in var def hasinitvalueasstring(var): if not hasinitvalue(var): return 0 return var['='][0] in ['"', "'"] def hasnote(var): return 'note' in var def hasresultnote(rout): if not isfunction(rout): return 0 if 'result' in rout: a = rout['result'] else: a = rout['name'] if a in rout['vars']: return hasnote(rout['vars'][a]) return 0 def hascommon(rout): return 'common' in rout def containscommon(rout): if hascommon(rout): return 1 if hasbody(rout): for b in rout['body']: if containscommon(b): return 1 return 0 def containsmodule(block): if ismodule(block): return 1 if not hasbody(block): return 0 for b in block['body']: if containsmodule(b): return 1 return 0 def hasbody(rout): return 'body' in rout def hascallstatement(rout): return getcallstatement(rout) is not None def istrue(var): return 1 def isfalse(var): return 0 class F2PYError(Exception): pass class throw_error: def __init__(self, mess): self.mess = mess def __call__(self, var): mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess) raise F2PYError(mess) def l_and(*f): l1, l2 = 'lambda v', [] for i in range(len(f)): l1 = '%s,f%d=f[%d]' % (l1, i, i) l2.append('f%d(v)' % (i)) return eval('%s:%s' % (l1, ' and '.join(l2))) def l_or(*f): l1, l2 = 'lambda v', [] for i in range(len(f)): l1 = '%s,f%d=f[%d]' % (l1, i, i) l2.append('f%d(v)' % (i)) return eval('%s:%s' % (l1, ' or '.join(l2))) def l_not(f): return eval('lambda v,f=f:not f(v)') def isdummyroutine(rout): try: return rout['f2pyenhancements']['fortranname'] == '' except KeyError: return 0 def getfortranname(rout): try: name = rout['f2pyenhancements']['fortranname'] if name == '': raise KeyError if not name: errmess('Failed to use fortranname from %s\n' % (rout['f2pyenhancements'])) raise KeyError except KeyError: name = rout['name'] return name def getmultilineblock(rout, blockname, comment=1, counter=0): try: r = rout['f2pyenhancements'].get(blockname) except KeyError: return if not r: return if counter > 0 and isinstance(r, str): return if isinstance(r, list): if counter >= len(r): return r = r[counter] if r[:3] == "'''": if comment: r = '\t/* start ' + blockname + \ ' multiline (' + repr(counter) + ') */\n' + r[3:] else: r = r[3:] if r[-3:] == "'''": if comment: r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/' else: r = r[:-3] else: errmess("%s multiline block should end with `'''`: %s\n" % (blockname, repr(r))) return r def getcallstatement(rout): return getmultilineblock(rout, 'callstatement') def getcallprotoargument(rout, cb_map={}): r = getmultilineblock(rout, 'callprotoargument', comment=0) if r: return r if hascallstatement(rout): outmess( 'warning: callstatement is defined without callprotoargument\n') return from .capi_maps import getctype arg_types, arg_types2 = [], [] if l_and(isstringfunction, l_not(isfunction_wrap))(rout): arg_types.extend(['char*', 'size_t']) for n in rout['args']: var = rout['vars'][n] if isintent_callback(var): continue if n in cb_map: ctype = cb_map[n] + '_typedef' else: ctype = getctype(var) if l_and(isintent_c, l_or(isscalar, iscomplex))(var): pass elif isstring(var): pass else: if not isattr_value(var): ctype = ctype + '*' if ((isstring(var) or isarrayofstrings(var) # obsolete? or isstringarray(var))): arg_types2.append('size_t') arg_types.append(ctype) proto_args = ','.join(arg_types + arg_types2) if not proto_args: proto_args = 'void' return proto_args def getusercode(rout): return getmultilineblock(rout, 'usercode') def getusercode1(rout): return getmultilineblock(rout, 'usercode', counter=1) def getpymethoddef(rout): return getmultilineblock(rout, 'pymethoddef') def getargs(rout): sortargs, args = [], [] if 'args' in rout: args = rout['args'] if 'sortvars' in rout: for a in rout['sortvars']: if a in args: sortargs.append(a) for a in args: if a not in sortargs: sortargs.append(a) else: sortargs = rout['args'] return args, sortargs def getargs2(rout): sortargs, args = [], rout.get('args', []) auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a]) and a not in args] args = auxvars + args if 'sortvars' in rout: for a in rout['sortvars']: if a in args: sortargs.append(a) for a in args: if a not in sortargs: sortargs.append(a) else: sortargs = auxvars + rout['args'] return args, sortargs def getrestdoc(rout): if 'f2pymultilines' not in rout: return None k = None if rout['block'] == 'python module': k = rout['block'], rout['name'] return rout['f2pymultilines'].get(k, None) def gentitle(name): ln = (80 - len(name) - 6) // 2 return '/*%s %s %s*/' % (ln * '*', name, ln * '*') def flatlist(lst): if isinstance(lst, list): return reduce(lambda x, y, f=flatlist: x + f(y), lst, []) return [lst] def stripcomma(s): if s and s[-1] == ',': return s[:-1] return s def replace(str, d, defaultsep=''): if isinstance(d, list): return [replace(str, _m, defaultsep) for _m in d] if isinstance(str, list): return [replace(_m, d, defaultsep) for _m in str] for k in 2 * list(d.keys()): if k == 'separatorsfor': continue if 'separatorsfor' in d and k in d['separatorsfor']: sep = d['separatorsfor'][k] else: sep = defaultsep if isinstance(d[k], list): str = str.replace('#%s#' % (k), sep.join(flatlist(d[k]))) else: str = str.replace('#%s#' % (k), d[k]) return str def dictappend(rd, ar): if isinstance(ar, list): for a in ar: rd = dictappend(rd, a) return rd for k in ar.keys(): if k[0] == '_': continue if k in rd: if isinstance(rd[k], str): rd[k] = [rd[k]] if isinstance(rd[k], list): if isinstance(ar[k], list): rd[k] = rd[k] + ar[k] else: rd[k].append(ar[k]) elif isinstance(rd[k], dict): if isinstance(ar[k], dict): if k == 'separatorsfor': for k1 in ar[k].keys(): if k1 not in rd[k]: rd[k][k1] = ar[k][k1] else: rd[k] = dictappend(rd[k], ar[k]) else: rd[k] = ar[k] return rd def applyrules(rules, d, var={}): ret = {} if isinstance(rules, list): for r in rules: rr = applyrules(r, d, var) ret = dictappend(ret, rr) if '_break' in rr: break return ret if '_check' in rules and (not rules['_check'](var)): return ret if 'need' in rules: res = applyrules({'needs': rules['need']}, d, var) if 'needs' in res: cfuncs.append_needs(res['needs']) for k in rules.keys(): if k == 'separatorsfor': ret[k] = rules[k] continue if isinstance(rules[k], str): ret[k] = replace(rules[k], d) elif isinstance(rules[k], list): ret[k] = [] for i in rules[k]: ar = applyrules({k: i}, d, var) if k in ar: ret[k].append(ar[k]) elif k[0] == '_': continue elif isinstance(rules[k], dict): ret[k] = [] for k1 in rules[k].keys(): if isinstance(k1, types.FunctionType) and k1(var): if isinstance(rules[k][k1], list): for i in rules[k][k1]: if isinstance(i, dict): res = applyrules({'supertext': i}, d, var) if 'supertext' in res: i = res['supertext'] else: i = '' ret[k].append(replace(i, d)) else: i = rules[k][k1] if isinstance(i, dict): res = applyrules({'supertext': i}, d) if 'supertext' in res: i = res['supertext'] else: i = '' ret[k].append(replace(i, d)) else: errmess('applyrules: ignoring rule %s.\n' % repr(rules[k])) if isinstance(ret[k], list): if len(ret[k]) == 1: ret[k] = ret[k][0] if ret[k] == []: del ret[k] return ret def deep_merge(dict1, dict2): """Recursively merge two dictionaries into a new dictionary. Parameters: - dict1: The base dictionary. - dict2: The dictionary to merge into a copy of dict1. If a key exists in both, the dict2 value will take precedence. Returns: - A new merged dictionary. """ merged_dict = deepcopy(dict1) for key, value in dict2.items(): if key in merged_dict: if isinstance(merged_dict[key], dict) and isinstance(value, dict): merged_dict[key] = deep_merge(merged_dict[key], value) else: merged_dict[key] = value else: merged_dict[key] = value return merged_dict _f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]+)', re.I).match _f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]*?' r'__user__[\w_]*)', re.I).match def get_f2py_modulename(source): name = None with open(source) as f: for line in f: m = _f2py_module_name_match(line) if m: if _f2py_user_module_name_match(line): # skip *__user__* names continue name = m.group('name') break return name