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/gsutil/third_party/pyasn1/pyasn1/type
Viewing File: /opt/gsutil/third_party/pyasn1/pyasn1/type/constraint.py
# # This file is part of pyasn1 software. # # Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> # License: https://pyasn1.readthedocs.io/en/latest/license.html # # Original concept and code by Mike C. Fletcher. # import sys from pyasn1.type import error __all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint', 'ValueRangeConstraint', 'ValueSizeConstraint', 'PermittedAlphabetConstraint', 'InnerTypeConstraint', 'ConstraintsExclusion', 'ConstraintsIntersection', 'ConstraintsUnion'] class AbstractConstraint(object): def __init__(self, *values): self._valueMap = set() self._setValues(values) self.__hash = hash((self.__class__.__name__, self._values)) def __call__(self, value, idx=None): if not self._values: return try: self._testValue(value, idx) except error.ValueConstraintError as exc: raise error.ValueConstraintError( '%s failed at: %r' % (self, exc) ) def __repr__(self): representation = '%s object' % (self.__class__.__name__) if self._values: representation += ', consts %s' % ', '.join( [repr(x) for x in self._values]) return '<%s>' % representation def __eq__(self, other): if self is other: return True return self._values == other def __ne__(self, other): return self._values != other def __lt__(self, other): return self._values < other def __le__(self, other): return self._values <= other def __gt__(self, other): return self._values > other def __ge__(self, other): return self._values >= other def __bool__(self): return bool(self._values) def __hash__(self): return self.__hash def _setValues(self, values): self._values = values def _testValue(self, value, idx): raise error.ValueConstraintError(value) # Constraints derivation logic def getValueMap(self): return self._valueMap def isSuperTypeOf(self, otherConstraint): # TODO: fix possible comparison of set vs scalars here return (otherConstraint is self or not self._values or otherConstraint == self or self in otherConstraint.getValueMap()) def isSubTypeOf(self, otherConstraint): return (otherConstraint is self or not self or otherConstraint == self or otherConstraint in self._valueMap) class SingleValueConstraint(AbstractConstraint): """Create a SingleValueConstraint object. The SingleValueConstraint satisfies any value that is present in the set of permitted values. Objects of this type are iterable (emitting constraint values) and can act as operands for some arithmetic operations e.g. addition and subtraction. The latter can be used for combining multiple SingleValueConstraint objects into one. The SingleValueConstraint object can be applied to any ASN.1 type. Parameters ---------- *values: :class:`int` Full set of values permitted by this constraint object. Examples -------- .. code-block:: python class DivisorOfSix(Integer): ''' ASN.1 specification: Divisor-Of-6 ::= INTEGER (1 | 2 | 3 | 6) ''' subtypeSpec = SingleValueConstraint(1, 2, 3, 6) # this will succeed divisor_of_six = DivisorOfSix(1) # this will raise ValueConstraintError divisor_of_six = DivisorOfSix(7) """ def _setValues(self, values): self._values = values self._set = set(values) def _testValue(self, value, idx): if value not in self._set: raise error.ValueConstraintError(value) # Constrains can be merged or reduced def __contains__(self, item): return item in self._set def __iter__(self): return iter(self._set) def __add__(self, constraint): return self.__class__(*(self._set.union(constraint))) def __sub__(self, constraint): return self.__class__(*(self._set.difference(constraint))) class ContainedSubtypeConstraint(AbstractConstraint): """Create a ContainedSubtypeConstraint object. The ContainedSubtypeConstraint satisfies any value that is present in the set of permitted values and also satisfies included constraints. The ContainedSubtypeConstraint object can be applied to any ASN.1 type. Parameters ---------- *values: Full set of values and constraint objects permitted by this constraint object. Examples -------- .. code-block:: python class DivisorOfEighteen(Integer): ''' ASN.1 specification: Divisors-of-18 ::= INTEGER (INCLUDES Divisors-of-6 | 9 | 18) ''' subtypeSpec = ContainedSubtypeConstraint( SingleValueConstraint(1, 2, 3, 6), 9, 18 ) # this will succeed divisor_of_eighteen = DivisorOfEighteen(9) # this will raise ValueConstraintError divisor_of_eighteen = DivisorOfEighteen(10) """ def _testValue(self, value, idx): for constraint in self._values: if isinstance(constraint, AbstractConstraint): constraint(value, idx) elif value not in self._set: raise error.ValueConstraintError(value) class ValueRangeConstraint(AbstractConstraint): """Create a ValueRangeConstraint object. The ValueRangeConstraint satisfies any value that falls in the range of permitted values. The ValueRangeConstraint object can only be applied to :class:`~pyasn1.type.univ.Integer` and :class:`~pyasn1.type.univ.Real` types. Parameters ---------- start: :class:`int` Minimum permitted value in the range (inclusive) end: :class:`int` Maximum permitted value in the range (inclusive) Examples -------- .. code-block:: python class TeenAgeYears(Integer): ''' ASN.1 specification: TeenAgeYears ::= INTEGER (13 .. 19) ''' subtypeSpec = ValueRangeConstraint(13, 19) # this will succeed teen_year = TeenAgeYears(18) # this will raise ValueConstraintError teen_year = TeenAgeYears(20) """ def _testValue(self, value, idx): if value < self.start or value > self.stop: raise error.ValueConstraintError(value) def _setValues(self, values): if len(values) != 2: raise error.PyAsn1Error( '%s: bad constraint values' % (self.__class__.__name__,) ) self.start, self.stop = values if self.start > self.stop: raise error.PyAsn1Error( '%s: screwed constraint values (start > stop): %s > %s' % ( self.__class__.__name__, self.start, self.stop ) ) AbstractConstraint._setValues(self, values) class ValueSizeConstraint(ValueRangeConstraint): """Create a ValueSizeConstraint object. The ValueSizeConstraint satisfies any value for as long as its size falls within the range of permitted sizes. The ValueSizeConstraint object can be applied to :class:`~pyasn1.type.univ.BitString`, :class:`~pyasn1.type.univ.OctetString` (including all :ref:`character ASN.1 types <type.char>`), :class:`~pyasn1.type.univ.SequenceOf` and :class:`~pyasn1.type.univ.SetOf` types. Parameters ---------- minimum: :class:`int` Minimum permitted size of the value (inclusive) maximum: :class:`int` Maximum permitted size of the value (inclusive) Examples -------- .. code-block:: python class BaseballTeamRoster(SetOf): ''' ASN.1 specification: BaseballTeamRoster ::= SET SIZE (1..25) OF PlayerNames ''' componentType = PlayerNames() subtypeSpec = ValueSizeConstraint(1, 25) # this will succeed team = BaseballTeamRoster() team.extend(['Jan', 'Matej']) encode(team) # this will raise ValueConstraintError team = BaseballTeamRoster() team.extend(['Jan'] * 26) encode(team) Note ---- Whenever ValueSizeConstraint is applied to mutable types (e.g. :class:`~pyasn1.type.univ.SequenceOf`, :class:`~pyasn1.type.univ.SetOf`), constraint validation only happens at the serialisation phase rather than schema instantiation phase (as it is with immutable types). """ def _testValue(self, value, idx): valueSize = len(value) if valueSize < self.start or valueSize > self.stop: raise error.ValueConstraintError(value) class PermittedAlphabetConstraint(SingleValueConstraint): """Create a PermittedAlphabetConstraint object. The PermittedAlphabetConstraint satisfies any character string for as long as all its characters are present in the set of permitted characters. Objects of this type are iterable (emitting constraint values) and can act as operands for some arithmetic operations e.g. addition and subtraction. The PermittedAlphabetConstraint object can only be applied to the :ref:`character ASN.1 types <type.char>` such as :class:`~pyasn1.type.char.IA5String`. Parameters ---------- *alphabet: :class:`str` Full set of characters permitted by this constraint object. Example ------- .. code-block:: python class BooleanValue(IA5String): ''' ASN.1 specification: BooleanValue ::= IA5String (FROM ('T' | 'F')) ''' subtypeSpec = PermittedAlphabetConstraint('T', 'F') # this will succeed truth = BooleanValue('T') truth = BooleanValue('TF') # this will raise ValueConstraintError garbage = BooleanValue('TAF') ASN.1 `FROM ... EXCEPT ...` clause can be modelled by combining multiple PermittedAlphabetConstraint objects into one: Example ------- .. code-block:: python class Lipogramme(IA5String): ''' ASN.1 specification: Lipogramme ::= IA5String (FROM (ALL EXCEPT ("e"|"E"))) ''' subtypeSpec = ( PermittedAlphabetConstraint(*string.printable) - PermittedAlphabetConstraint('e', 'E') ) # this will succeed lipogramme = Lipogramme('A work of fiction?') # this will raise ValueConstraintError lipogramme = Lipogramme('Eel') Note ---- Although `ConstraintsExclusion` object could seemingly be used for this purpose, practically, for it to work, it needs to represent its operand constraints as sets and intersect one with the other. That would require the insight into the constraint values (and their types) that are otherwise hidden inside the constraint object. Therefore it's more practical to model `EXCEPT` clause at `PermittedAlphabetConstraint` level instead. """ def _setValues(self, values): self._values = values self._set = set(values) def _testValue(self, value, idx): if not self._set.issuperset(value): raise error.ValueConstraintError(value) class ComponentPresentConstraint(AbstractConstraint): """Create a ComponentPresentConstraint object. The ComponentPresentConstraint is only satisfied when the value is not `None`. The ComponentPresentConstraint object is typically used with `WithComponentsConstraint`. Examples -------- .. code-block:: python present = ComponentPresentConstraint() # this will succeed present('whatever') # this will raise ValueConstraintError present(None) """ def _setValues(self, values): self._values = ('<must be present>',) if values: raise error.PyAsn1Error('No arguments expected') def _testValue(self, value, idx): if value is None: raise error.ValueConstraintError( 'Component is not present:') class ComponentAbsentConstraint(AbstractConstraint): """Create a ComponentAbsentConstraint object. The ComponentAbsentConstraint is only satisfied when the value is `None`. The ComponentAbsentConstraint object is typically used with `WithComponentsConstraint`. Examples -------- .. code-block:: python absent = ComponentAbsentConstraint() # this will succeed absent(None) # this will raise ValueConstraintError absent('whatever') """ def _setValues(self, values): self._values = ('<must be absent>',) if values: raise error.PyAsn1Error('No arguments expected') def _testValue(self, value, idx): if value is not None: raise error.ValueConstraintError( 'Component is not absent: %r' % value) class WithComponentsConstraint(AbstractConstraint): """Create a WithComponentsConstraint object. The `WithComponentsConstraint` satisfies any mapping object that has constrained fields present or absent, what is indicated by `ComponentPresentConstraint` and `ComponentAbsentConstraint` objects respectively. The `WithComponentsConstraint` object is typically applied to :class:`~pyasn1.type.univ.Set` or :class:`~pyasn1.type.univ.Sequence` types. Parameters ---------- *fields: :class:`tuple` Zero or more tuples of (`field`, `constraint`) indicating constrained fields. Notes ----- On top of the primary use of `WithComponentsConstraint` (ensuring presence or absence of particular components of a :class:`~pyasn1.type.univ.Set` or :class:`~pyasn1.type.univ.Sequence`), it is also possible to pass any other constraint objects or their combinations. In case of scalar fields, these constraints will be verified in addition to the constraints belonging to scalar components themselves. However, formally, these additional constraints do not change the type of these ASN.1 objects. Examples -------- .. code-block:: python class Item(Sequence): # Set is similar ''' ASN.1 specification: Item ::= SEQUENCE { id INTEGER OPTIONAL, name OCTET STRING OPTIONAL } WITH COMPONENTS id PRESENT, name ABSENT | id ABSENT, name PRESENT ''' componentType = NamedTypes( OptionalNamedType('id', Integer()), OptionalNamedType('name', OctetString()) ) withComponents = ConstraintsUnion( WithComponentsConstraint( ('id', ComponentPresentConstraint()), ('name', ComponentAbsentConstraint()) ), WithComponentsConstraint( ('id', ComponentAbsentConstraint()), ('name', ComponentPresentConstraint()) ) ) item = Item() # This will succeed item['id'] = 1 # This will succeed item.reset() item['name'] = 'John' # This will fail (on encoding) item.reset() descr['id'] = 1 descr['name'] = 'John' """ def _testValue(self, value, idx): for field, constraint in self._values: constraint(value.get(field)) def _setValues(self, values): AbstractConstraint._setValues(self, values) # This is a bit kludgy, meaning two op modes within a single constraint class InnerTypeConstraint(AbstractConstraint): """Value must satisfy the type and presence constraints""" def _testValue(self, value, idx): if self.__singleTypeConstraint: self.__singleTypeConstraint(value) elif self.__multipleTypeConstraint: if idx not in self.__multipleTypeConstraint: raise error.ValueConstraintError(value) constraint, status = self.__multipleTypeConstraint[idx] if status == 'ABSENT': # XXX presence is not checked! raise error.ValueConstraintError(value) constraint(value) def _setValues(self, values): self.__multipleTypeConstraint = {} self.__singleTypeConstraint = None for v in values: if isinstance(v, tuple): self.__multipleTypeConstraint[v[0]] = v[1], v[2] else: self.__singleTypeConstraint = v AbstractConstraint._setValues(self, values) # Logic operations on constraints class ConstraintsExclusion(AbstractConstraint): """Create a ConstraintsExclusion logic operator object. The ConstraintsExclusion logic operator succeeds when the value does *not* satisfy the operand constraint. The ConstraintsExclusion object can be applied to any constraint and logic operator object. Parameters ---------- *constraints: Constraint or logic operator objects. Examples -------- .. code-block:: python class LuckyNumber(Integer): subtypeSpec = ConstraintsExclusion( SingleValueConstraint(13) ) # this will succeed luckyNumber = LuckyNumber(12) # this will raise ValueConstraintError luckyNumber = LuckyNumber(13) Note ---- The `FROM ... EXCEPT ...` ASN.1 clause should be modeled by combining constraint objects into one. See `PermittedAlphabetConstraint` for more information. """ def _testValue(self, value, idx): for constraint in self._values: try: constraint(value, idx) except error.ValueConstraintError: continue raise error.ValueConstraintError(value) def _setValues(self, values): AbstractConstraint._setValues(self, values) class AbstractConstraintSet(AbstractConstraint): def __getitem__(self, idx): return self._values[idx] def __iter__(self): return iter(self._values) def __add__(self, value): return self.__class__(*(self._values + (value,))) def __radd__(self, value): return self.__class__(*((value,) + self._values)) def __len__(self): return len(self._values) # Constraints inclusion in sets def _setValues(self, values): self._values = values for constraint in values: if constraint: self._valueMap.add(constraint) self._valueMap.update(constraint.getValueMap()) class ConstraintsIntersection(AbstractConstraintSet): """Create a ConstraintsIntersection logic operator object. The ConstraintsIntersection logic operator only succeeds if *all* its operands succeed. The ConstraintsIntersection object can be applied to any constraint and logic operator objects. The ConstraintsIntersection object duck-types the immutable container object like Python :py:class:`tuple`. Parameters ---------- *constraints: Constraint or logic operator objects. Examples -------- .. code-block:: python class CapitalAndSmall(IA5String): ''' ASN.1 specification: CapitalAndSmall ::= IA5String (FROM ("A".."Z"|"a".."z")) ''' subtypeSpec = ConstraintsIntersection( PermittedAlphabetConstraint('A', 'Z'), PermittedAlphabetConstraint('a', 'z') ) # this will succeed capital_and_small = CapitalAndSmall('Hello') # this will raise ValueConstraintError capital_and_small = CapitalAndSmall('hello') """ def _testValue(self, value, idx): for constraint in self._values: constraint(value, idx) class ConstraintsUnion(AbstractConstraintSet): """Create a ConstraintsUnion logic operator object. The ConstraintsUnion logic operator succeeds if *at least* a single operand succeeds. The ConstraintsUnion object can be applied to any constraint and logic operator objects. The ConstraintsUnion object duck-types the immutable container object like Python :py:class:`tuple`. Parameters ---------- *constraints: Constraint or logic operator objects. Examples -------- .. code-block:: python class CapitalOrSmall(IA5String): ''' ASN.1 specification: CapitalOrSmall ::= IA5String (FROM ("A".."Z") | FROM ("a".."z")) ''' subtypeSpec = ConstraintsUnion( PermittedAlphabetConstraint('A', 'Z'), PermittedAlphabetConstraint('a', 'z') ) # this will succeed capital_or_small = CapitalAndSmall('Hello') # this will raise ValueConstraintError capital_or_small = CapitalOrSmall('hello!') """ def _testValue(self, value, idx): for constraint in self._values: try: constraint(value, idx) except error.ValueConstraintError: pass else: return raise error.ValueConstraintError( 'all of %s failed for "%s"' % (self._values, value) ) # TODO: # refactor InnerTypeConstraint # add tests for type check # implement other constraint types # make constraint validation easy to skip