PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/opt/cloudlinux/venv/lib64/python3.11/site-packages/guppy/heapy/test/
Upload File :
Current File : //opt/cloudlinux/venv/lib64/python3.11/site-packages/guppy/heapy/test/test_Classifiers.py
from guppy.heapy.test import support
import textwrap

PORTABLE_TEST = 1       # Relax tests to be more portable


class TestCase(support.TestCase):
    def setUp(self):
        support.TestCase.setUp(self)
        self.View.is_rg_update_all = False

        self.US = US = self.heapy.UniSet

        self.Use = Use = self.heapy.Use
        Use.reprefix = 'hp.'
        self.do = lambda x: x.dictof

        self.un = Use.Anything.fam
        self.ty = Use.Type
        self.rc = Use.Rcs
        self.iso = Use.iso

        self.Anything = US.Anything
        self.Nothing = US.Nothing

        class C1:
            def x(self):
                return 0

        class C2:
            pass
        c1 = C1()

        self.C1 = C1
        self.C2 = C2
        self.c1 = c1

    def lt(self, a, b):
        self.assertTrue(a < b)

    def eq(self, a, b):
        self.assertTrue(a == b)

    def dj(self, a, b):
        # disjoint; not related by <= or >=, and not overlapping
        self.assertTrue(not a <= b)
        self.assertTrue(not b <= a)
        self.assertTrue(not a & b)
        self.assertTrue(a.disjoint(b))

    def nr(self, a, b):
        # not related by <= or >=, and overlapping
        self.assertTrue(not a <= b)
        self.assertTrue(not b <= a)
        self.assertTrue(a & b)
        self.assertTrue(not a.disjoint(b))


class SpecialCases(TestCase):
    # Special tests that catch cases that came up during development & debugging
    def test_1(self):
        un = self.un
        ty = self.ty
        do = self.do
        rc = self.rc
        iso = self.iso
        All = self.Anything
        Nothing = self.Nothing
        C1 = self.C1
        C2 = self.C2
        c1 = self.c1

        def eq(a, b):
            self.assertTrue(a == b)
            self.assertTrue(str(a) == str(b))

        e1 = []
        e2 = {}
        e3 = []
        e4 = ()

        a = ty(int)
        b = ty(dict)
        self.assertTrue(~a & ~b != Nothing)

        eq(ty(list) & iso(e1, e2, e3), iso(e1, e3))
        eq((ty(list) | ty(dict)) & iso(e1, e2, e3, e4), iso(e1, e2, e3))
        eq(iso(e1, e3) | ty(list), ty(list))
        eq(ty(list) | iso(e1, e3), ty(list))

        eq(iso(e1, e3) - iso(e3), iso(e1))
        eq(~iso(e3) & iso(e1, e3), iso(e1))

        eq(iso(e1, e2, e3) - ty(dict), iso(e1, e3))
        eq(~ty(dict) & iso(e1, e2, e3), iso(e1, e3))
        eq(ty(dict) | iso(e1, e2), ty(dict) | iso(e1))
        eq(iso(e1, e2) | ty(dict), ty(dict) | iso(e1))
        eq((ty(dict) | ty(tuple)) | iso(e1, e2), (ty(dict) | ty(tuple)) | iso(e1))
        eq(iso(e1, e2) | (ty(dict) | ty(tuple)), (ty(dict) | ty(tuple)) | iso(e1))
        eq(~ty(dict) | iso(e1, e2), ~ty(dict) | iso(e2))
        eq(iso(e1, e2) | ~ty(dict), ~ty(dict) | iso(e2))
        eq(ty(dict) - iso(e1, e2), ty(dict) - iso(e2))
        eq(~iso(e1, e2) & ty(dict), ty(dict) - iso(e2))

        eq(iso(e1, e3) ^ iso(e2), iso(e1, e2, e3))
        eq(iso(e1, e3) ^ iso(e2, e3), iso(e1, e2))
        eq(iso(e1, e3) ^ iso(e1, e3), Nothing)

        eq(iso(e1, e3) <= ty(list), True)
        eq(iso(e1, e2) <= ty(list) | ty(dict), True)
        eq(ty(list) >= iso(e1, e3), True)
        eq(ty(list) | ty(dict) >= iso(e1, e2), True)

    def test_2(self):
        un = self.un
        ty = self.ty
        do = self.do
        rc = self.rc
        iso = self.iso
        All = self.Anything
        Nothing = self.Nothing
        C1 = self.C1
        C2 = self.C2
        c1 = self.c1

        class C3(object):
            def x(self):
                return 1

        def asrt(x):
            self.assertTrue(x)

        def no(x):
            self.assertTrue(not x)

        eq = self.aseq

        # Tests to do with Nothing being finite - having length and iteration

        no(dict in (ty(dict) | ty(int)))
        no([] in (ty(dict) | ty(int)))
        asrt({} in (ty(dict) | ty(int)))
        asrt(dict in (ty(dict) | ty(int) | ty(type(dict))))
        asrt(list(ty(list) & iso({})) == [])

        # When creating ISO classes, we don't want to memoize them
        # which would leak the elements.

        from sys import getrefcount as grc
        import sys
        import types

        c = C1()
        rc = grc(c)
        x = iso(c)
        x = None
        eq(grc(c), rc)

    def test_dictowner(self):
        # Special test for dict ownership
        # motivated by: dicts that are not found in traversal, should not
        # cause repeated (unsuccessfull) updates of dict ownership
        # This is a performance question, requires special kind of testing
        #
        # Also tests that dict & dict owners are not leaked

        import gc
        from sys import getrefcount as grc
        Use = self.Use
        C1 = self.C1
        c1 = self.c1
        iso = self.iso

        o = self.python.io.StringIO()

        # Create a dict hidden from view
        d1 = self.View.immnodeset([{}])
        d3 = {}

        # Remember the initial ref counts for target objects

        gc.collect()

        rcd1 = grc(list(d1)[0])
        rcd3 = grc(d3)
        rcC1 = grc(C1)
        rcc1 = grc(c1)
        rcdc1 = grc(c1.__dict__)

        clock = self.python.time.process_time

        N = 5
        M = 50

        # This was the fast case, when only reachable dicts are classified
        for i in range(N):
            print(iso(d3).kind, file=o)
            print(iso(c1.__dict__).kind, file=o)

        # Now measure it

        while 1:
            gc.collect()
            t = clock()
            for i in range(M):
                iso(d3).kind
                iso(c1.__dict__).kind
            fast = clock()-t
            if fast >= 0.5:  # Enough resolution?
                break
            else:
                M *= 2  # No, try more loops

        # This was a slow case; involving repeated classification of a unreachable dict
        # It was originally 4.97 times slower when N was 5
        # The problem occurs for successive classifications of different dicts,
        # when at least one of them is unreachable.

        gc.collect()
        for i in range(N):
            print(iso(*d1).kind, file=o)
            print(iso(c1.__dict__).kind, file=o)

        gc.collect()
        # Now measure it

        t = clock()
        for i in range(M):
            iso(*d1).kind
            iso(c1.__dict__).kind
        slow = clock()-t

        self.assertTrue(slow <= 1.5*fast)

        # This is another slow case according to notes Nov 18 2004.
        # A succession of different unreachable dicts.

        gc.collect()
        dn = self.View.immnodeset([{} for i in range(N)])
        for i in range(N):
            print(iso(list(dn)[i]).kind, file=o)

        # Now measure it
        gc.collect()
        dn = self.View.immnodeset([{} for i in range(M)])

        t = clock()
        for i in range(M):
            iso(list(dn)[i]).kind
        slow = clock()-t

        # Sometimes M might be huge, and the vast majority of time it is not
        # doing the classification.
        # self.assertTrue(slow <= 1.5*fast)

        # Partition was likewise slow for unreachable dicts
        dn = self.View.immnodeset([{} for i in range(N)])
        gc.collect()
        print([x[0] for x in Use.Clodo.classifier.partition(dn)], file=o)

        # Now measure it
        dn = self.View.immnodeset([{} for i in range(M)])
        gc.collect()
        t = clock()
        [x[0] for x in Use.Clodo.classifier.partition(dn)]
        slow = clock()-t
        self.assertTrue(slow <= 1.5*fast)

        # Check that ref counts for target objects are the same as initially

        gc.collect()
        gc.collect()    # Note May 17 2005

        self.aseq(grc(list(d1)[0]), rcd1)
        self.aseq(grc(d3), rcd3)
        self.aseq(grc(c1), rcc1)
        self.aseq(grc(C1), rcC1)
        self.aseq(grc(c1.__dict__), rcdc1)

        self.aseq(o.getvalue(), """\
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict of <Module>.C1
dict (no owner)
dict (no owner)
dict (no owner)
dict (no owner)
dict (no owner)
[hp.Nothing.dictof]
""".replace('<Module>', self.__module__))

    def test_retclaset(self):
        # Test (A) that referrer classifications don't leak their classes
        # and (B) that selection is not disturbed by list arguments
        # (This is removed since it doesnt always work)
        # and (C) that selection does update referrer graph correctly

        self.__module__ = '<Module>'  # Make the rendering independent on our name

        from sys import getrefcount as grc
        import gc
        C1 = self.C1
        c1 = self.c1

        iso = self.iso
        rcC1 = grc(C1)

        o = self.python.io.StringIO()
        print(iso(C1).byrcs.kind, file=o)

        s = iso(c1).byrcs.kind
        print(s, file=o)
        self.aseq(s & iso(c1), iso(c1))

        x = C1()

        self.aseq(s & iso(c1, x), iso(c1))

        s = iso(x).byrcs.kind
        self.aseq(s & iso(c1, x), iso(x))
        x = C1()
        # (C) make sure referrer graph is updated by select
        self.aseq(s & iso(c1, x), iso(x))

        s = None
        x = None
        gc.collect()
        gc.collect()                    # Note May 17 2005
        self.aseq(grc(C1), rcC1)        # (A)

    def test_alt_retclaset(self):
        # Test the alternative referrer memo update
        # On low level, and the speed of selection

        import gc
        iso = self.iso
        a = []
        b = self.View.immnodeset([[]])

        x = [a, b]

        hv = self.View.hv

        rg = self.View.nodegraph()

        gc.collect()
        hv.update_referrers_completely(rg)
        self.assertTrue(x in rg[a])

        self.assertTrue(rg[list(b)[0]] == (None,))
        rg.clear()
        rg = None

        # Test View functionality

        self.View.is_rg_update_all = True
        gc.collect()
        iso(a).referrers
        self.assertTrue(a in self.View.rg.get_domain())
        self.assertTrue(list(b)[0] in self.View.rg.get_domain())

        clock = self.python.time.process_time
        s = iso(a)
        N = 1000
        while 1:
            t = clock()
            for i in range(N):
                s.referrers
            fast = clock()-t
            if fast >= 0.5:
                break
            N *= 2      # CPU is too fast to get good resolution, try more loops

        t = clock()
        for i in range(N):
            self.View.rg.domain_covers([a])
            self.View.rg[a]
        faster = clock()-t
        s = iso(*b)
        t = clock()
        for i in range(N):
            s.referrers
        slow = clock() - t
        self.assertTrue(not slow > fast * 4)

    def test_via(self, vlist=['v', ]):  # vlist is just to make v unoptimizable
        # Special tests for the via classifier

        from sys import getrefcount as grc
        import gc

        iso = self.iso
        hp = self.Use
        d = {}
        k = ('k',)
        v = tuple(vlist)  # Make sure v is not optimized to a constant

        d[k] = v
        d[v] = v

        rck = grc(k)
        rcv = grc(v)

        s = iso(v)

        self.assertTrue(s.byvia.kind == hp.Via("_.f_locals['v']", "_[('k',)]", "_[('v',)]", '_.keys()[1]') or
                        s.byvia.kind == hp.Via("_.f_locals['v']", "_[('k',)]", "_[('v',)]", '_.keys()[0]'))

        del s
        gc.collect()
        gc.collect()
        self.aseq(grc(k), rck)
        self.aseq(grc(v), rcv)


class RenderCase(TestCase):
    def test_rendering(self):
        import sys
        import types
        iso = self.iso
        C1 = self.C1
        c1 = self.c1

        class C3(object):
            def x(self):
                return 1

        e1 = []
        e2 = {}
        e3 = []

        o = self.python.io.StringIO()
        # str'ing of homogenous & inhoumogenous values

        self.US.summary_str.str_address = lambda x: '<address>'

        def ps(x):
            print(x.brief, file=o)

        ps(iso(1, 2))
        ps(iso(1, 2.0, 3.0))
        ps(iso(e1))
        ps(iso(e1, e2))
        ps(iso(e1, e3))

        ps(iso(self.python.builtins.TypeError()))
        # ps(iso(type('MetaType', (type,), {})('MetaTypeIns', (), {})))
        ps(iso(None))
        ps(iso(sys, support, types))
        ps(iso(int, type, C3))
        ps(iso(C1()))
        ps(iso(C3()))
        ps(iso(C1))
        ps(iso(C3))
        ps(iso(len))
        ps(iso(self.setUp))
        ps(iso(C1.x))
        ps(iso(C1().x))
        ps(iso(C3.x))
        ps(iso(C3().x))

        ps(iso({}))
        ps(iso(c1.__dict__))
        ps(iso(types.__dict__))

        try:
            1/0
        except ZeroDivisionError:
            typ, value, traceback = sys.exc_info()

        ps(iso(traceback))
        ps(iso(traceback.tb_frame))

        expected = textwrap.dedent("""\
            <2 int: 1, 2>
            <3 (float | int): <2 float: 2.0, 3.0> | <1 int: 1>>
            <1 list: <address>*0>
            <2 (dict (no owner) | list): <1 dict (no owner): <address>*0> | <1 list: <ad...>
            <2 list: <address>*0, <address>*0>
            <1 TypeError: <address>>
            <1 builtins.NoneType: None>
            <3 module: guppy.heapy.test.support, sys, types>
            <3 type: <Module>.C3, int, type>
            <1 <Module>.C1: <address>>
            <1 <Module>.C3: <address>>
            <1 type: <Module>.C1>
            <1 type: <Module>.C3>
            <1 types.BuiltinMethodType: len>
            <1 types.MethodType: <<Module>.RenderCase at <addre...>
            <1 function: <Module>.x>
            <1 types.MethodType: <<Module>.C1 at <address>>.x>
            <1 function: <Module>.x>
            <1 types.MethodType: <<Module>.C3 at <address>>.x>
            <1 dict (no owner): <address>*0>
            <1 dict of <Module>.C1: <address>>
            <1 dict of module: types>
            <1 types.TracebackType: <in frame <test_rendering at <address>> at <address>>>
            <1 types.FrameType: <test_rendering at <address>>>
            """)
        expected = expected.replace('<Module>', self.__module__)

        if self.version_info >= (3, 10):
            expected = expected.replace('builtins.NoneType', 'types.NoneType')
        self.aseq(o.getvalue(), expected)

        if PORTABLE_TEST:
            return

        o = self.python.io.StringIO()

        # The following is nonportable, sizes may change
        # In particular, the list size changed from 2.3 to 2.4
        # The following test is only for 2.3 in 32-bit python

        # pp'ing prints in a nice form
        # This tests all types currently defined in Classifiers.Summary_str
        # and then some
        # Except: frametype; its size varies from time to time!

        x = iso(len, C1, 1.0+3j, {1: 2, 3: 4}, 1.25, C1.x.__func__, 1, ['list'],
                100000000000, None, C1.x, C1().x, C3.x, C3().x, sys, support,
                'string', ('tuple',), C3, int, type(None),
                # and some types not defined
                C1(), C3(), c1.__dict__

                )

        print(x, file=o)
        print(x.more, file=o)

        # Test instancetype; we need to replace the classifier with bytype

        x = iso(C1()).bytype
        print(x, file=o)

        expected = """\
Partition of a set of 24 objects. Total size = 2128 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0      3  12     1272  60      1272  60 type
     1      4  17      144   7      1416  67 types.MethodType
     2      1   4      136   6      1552  73 dict (no owner)
     3      1   4      136   6      1688  79 dict of <Module>.C1
     4      1   4       60   3      1748  82 list
     5      1   4       56   3      1804  85 function
     6      2   8       48   2      1852  87 module
     7      1   4       44   2      1896  89 class
     8      1   4       32   2      1928  91 <Module>.C1
     9      1   4       32   2      1960  92 str
<8 more rows. Type e.g. '_.more' to view.>
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
    10      1   4       32   2      1992  94 types.BuiltinMethodType
    11      1   4       28   1      2020  95 <Module>.C3
    12      1   4       28   1      2048  96 tuple
    13      1   4       24   1      2072  97 complex
    14      1   4       20   1      2092  98 long
    15      1   4       16   1      2108  99 float
    16      1   4       12   1      2120 100 int
    17      1   4        8   0      2128 100 types.NoneType
Partition of a set of 1 object. Total size = 32 bytes.
 Index  Count   %     Size   % Cumulative  % Type
     0      1 100       32 100        32 100 types.InstanceType
""".replace('<Module>', self.__module__)
        self.aseq(o.getvalue(), expected)


class BaseCase(TestCase):
    def test_minmax(self):
        s = self.guppy.sets.immbitset
        min = self.US.minimals
        max = self.US.maximals

        self.aseq(min([]), [])
        self.aseq(min([1]), [1])
        self.aseq(min([1, 1]), [1])
        self.aseq(min([1, 2]), [1])
        self.aseq(min([[], []]), [[]])

        self.aseq(min([s([1]), s([1, 2])]), [s([1])])
        self.aseq(min([s([1]), s([1, 2]), s([3])]), [s([1]), s([3])])

        self.aseq(max([]), [])
        self.aseq(max([1]), [1])
        self.aseq(max([1, 1]), [1])
        self.aseq(max([1, 2]), [2])
        self.aseq(max([[], []]), [[]])

        self.aseq(max([s([1]), s([1, 2])]), [s([1, 2])])
        self.aseq(max([s([1]), s([1, 2]), s([3])]), [s([1, 2]), s([3])])

    def test_base_classes(self):
        un = self.un
        ty = self.ty
        do = self.do
        rc = self.rc
        iso = self.iso
        All = self.Anything
        Nothing = self.Nothing
        C1 = self.C1
        C2 = self.C2
        c1 = self.c1
        lt = self.lt
        eq = self.eq
        dj = self.dj
        nr = self.nr

        data = [
            (All,       eq,     All),


            (ty(int),   eq,     ty(int)),
            (ty(int),   dj,     ty(dict)),
            (ty(int),   lt,     All),

            (rc(ty(dict)), eq,   rc(ty(dict))),
            (rc(ty(dict)), lt,   All),
            (rc(ty(dict)), dj,   rc(ty(list))),

            (iso(1),    eq,     iso(1)),
            (iso(1),    lt,     All),
            (iso(1),    dj,     iso(2)),
            (iso(1),    lt,     ty(int)),
            (iso(1),    dj,     ty(dict)),

            (Nothing,   eq,     Nothing),
            (Nothing,   lt,     ty(int)),
            (Nothing,   lt,     iso(1)),
        ]

        # Test relation of base classifications
        for a, cmp, b in data:
            cmp(a, b)
            # Test the four set-operations: & | - ^
            # depending on the asserted argument relation
            if cmp is eq:
                eq(b, a)
            elif cmp is lt:
                self.assertTrue(b > a)
                eq(b ^ a, b - a)        # Simple transformation
                eq(a ^ b, b - a)        # -=-, indep. of type
                lt(a, b)
            elif cmp is dj:
                dj(b, a)  # check that the dj relation is symmetric
                eq(a & b, Nothing)
                eq(b & a, Nothing)
                eq(a | b, b | a)
                eq(a - b, a)
                eq((a | b) - b, a)
                eq(a ^ b, a | b)
                eq(b ^ a, a | b)
                lt(a, a | b)
                lt(b, a | b)
            elif cmp is nr:
                nr(b, a)         # symmetric as well
                eq(a & b, b & a)
                eq(a & b & b, a & b)
                eq((a & b) - b, Nothing)
                eq((a | b) - b, a - b)
                eq(a | b, b | a)
                lt(Nothing, a & b)
                lt(Nothing, b & a)
                lt(a & b, a)
                lt(a & b, b)
                lt(a - b, a)
                dj(a - b, b)
                lt(a ^ b, a | b)
                lt(a, a | b)
                lt(b, a | b)

    def test_invalid_operations(self):
        US = self.US
        US.auto_convert_iter = False
        US.auto_convert_type = False

        ty = self.ty
        c1 = self.c1

        self.assertRaises(TypeError, lambda: ty(c1))
        self.assertRaises(TypeError, lambda: ty(int) <= None)
        self.assertRaises(TypeError, lambda: None >= ty(int))
        self.assertRaises(TypeError, lambda: None <= ty(int))

        self.assertRaises(TypeError, lambda: list(ty(int)))
        self.assertRaises(TypeError, lambda: len(ty(int)))

        self.assertRaises(TypeError, lambda: ty(int) & None)
        self.assertRaises(TypeError, lambda: None & ty(int))
        self.assertRaises(TypeError, lambda: ty(int) | None)
        self.assertRaises(TypeError, lambda: None | ty(int))
        self.assertRaises(TypeError, lambda: ty(int) - None)
        self.assertRaises(TypeError, lambda: None - ty(int))
        self.assertRaises(TypeError, lambda: ty(int) ^ None)
        self.assertRaises(TypeError, lambda: None ^ ty(int))

        self.assertRaises(TypeError, lambda: ty(int) | [14])
        self.assertRaises(TypeError, lambda: ty(int) | dict)
        self.assertRaises(TypeError, lambda: ty(int) | self.C1)

    def test_fancy_list_args(self):
        # Test the, normally disabled, possibility to use iterables as
        # right and left arguments in set expressions.
        # This option can cause problems as noted 22/11 2004.

        self.US.auto_convert_iter = True

        eq = self.eq
        iso = self.iso
        ty = self.ty

        e1 = []
        e2 = {}
        e3 = []
        e4 = ()

        eq(ty(list) & [e1, e2, e3], iso(e1, e3))
        eq([e1, e2, e3] & ty(list), iso(e1, e3))       # Requires __rand__
        eq([e1, e2, e4] & (ty(dict) | ty(list)) == [e1, e2], True)
        eq([e1, e2] & (ty(dict) | ty(list)) == [e1, e2], True)
        eq(iso(e1, e2) & (ty(dict) | ty(list)) == [e1, e2], True)
        eq(iso(e1, e2) & [e1, e3], iso(e1))
        eq(iso(e1, e2) | [e1, e3], iso(e1, e2, e3))
        # Requires __ror__
        eq([e1, e3] | iso(e1, e2), iso(e1, e2, e3))
        eq(iso(e1, e3) - [e3], iso(e1))
        eq([e1, e3] - iso(e3), iso(e1))                 # Requires __rsub__
        eq([e1, e2, e3] - ty(dict), iso(e1, e3))
        eq(~ty(dict) & [e1, e2, e3], iso(e1, e3))
        eq(iso(e1, e3) ^ [e2], iso(e1, e2, e3))
        eq([e2] ^ iso(e1, e3), iso(e1, e2, e3))           # Requires __rxor__
        eq([e1, e2] <= iso(e1, e2, e3), True)
        eq([e1, e2] <= ty(list) | ty(dict), True)
        eq((ty(list) | ty(dict)) >= [e1, e2], True)
        eq([e1, e2] <= ty(list), False)
        eq([e1, e2] <= iso(e1), False)
        eq([e1, e2] >= iso(e1, e2, e3), False)
        eq([e1, e2] >= iso(e1, e2), True)
        eq(iso(e1, e2, e3) <= [e1, e2], False)
        eq(iso(e1, e2) <= [e1, e2], True)
        eq(iso(e1, e2, e3) >= [e1, e2], True)
        eq(iso(e1, e2) >= [e1, e2, e3], False)

    def test_fancy_type_conversions(self):
        # Test the, perhaps optional, possibility to use types and classes
        # in classification set expressions.

        self.US.auto_convert_type = True

        un = self.un
        ty = self.ty
        do = self.do
        rc = self.rc
        iso = self.iso
        All = self.Anything
        Nothing = self.Nothing
        C1 = self.C1
        C2 = self.C2
        c1 = self.c1

        def eq(a, b):
            self.assertTrue(a == b)

        e1 = []
        e2 = {}
        e3 = []
        e4 = ()

        eq(ty(dict), dict)
        eq(iso(e1, e2) & dict, iso(e2))
        eq(dict & iso(e1, e2), iso(e2))
        eq(iso(e1, e2) | dict, iso(e1) | ty(dict))
        eq(dict | iso(e1, e2), iso(e1) | ty(dict))
        eq(iso(e1, e2) - dict, iso(e1))
        eq(dict - iso(e1, e2), ty(dict) - iso(e2))
        eq(iso(e1, e2, e3) ^ dict, (ty(dict)-iso(e2)) | iso(e1, e3))


class LawsCase(TestCase):
    def test_laws(self):
        un = self.un
        ty = self.ty
        do = self.do
        rc = self.rc
        iso = self.iso
        All = self.Anything
        Nothing = self.Nothing
        C1 = self.C1
        C2 = self.C2
        c1 = self.c1
        lt = self.lt
        eq = self.eq

        t = self.guppy.sets.test

        absorption = t.absorption
        associative = t.associative
        commutative = t.commutative
        deMorgan = t.deMorgan
        distributive = t.distributive
        idempotence = t.idempotence
        inclusion = t.inclusion

        def ltr(a, b, level=3):
            lt(a, b)
            eq(a & b, a)
            eq(b & a, a)
            eq(a | b, b)
            eq(b | a, b)
            eq(a - b, Nothing)
            eqr(b - a, b - a)
            eq((b - a) | a, b)
            eq(a | (b - a), b)
            eq(a & (b - a), Nothing)
            eq((b - a) & a, Nothing)
            eq((b - a) - a, (b - a))
            eq(a - (b - a), a)  # note Nov 3 2004
            if level > 0:
                if a is Nothing:
                    eq(b - a, b)
                else:
                    ltr(b - a, b, level-1)

        def eqr(a, b, level=1):
            eq(a, b)
            eq(a & b, a)
            eq(a | b, a)
            eq(a - b, Nothing)
            eq(a ^ b, Nothing)
            if level:
                eqr(b, a, level - 1)

        classes = [All, ty(int), ty(type(c1)), rc(ty(dict)), iso(c1), Nothing]

        for a in classes:
            idempotence(a)
            for b in classes:
                if a <= b:
                    if b <= a:
                        eqr(a, b)
                    else:
                        ltr(a, b)
                elif b <= a:
                    ltr(b, a)

                absorption(a, b)
                commutative(a, b)

                inclusion(a, b)
                deMorgan(a, b)
                for c in classes:
                    associative(a, b, c)
                    deMorgan(a, b, c)
                    distributive(a, b, c)


class ClassificationCase(TestCase):
    def test_classification(self):
        # Test classification by the standard classifiers
        self.View.is_rg_update_all = True  # Tricky details Note Apr 22 2005
        Use = self.Use
        iso = self.iso
        nodeset = self.heapy.UniSet.immnodeset

        class A:
            pass

        class B(object):
            pass
        a = A()
        b = B()
        li = [1, [], {}, a, b, a.__dict__, b.__dict__]
        for o in li:
            self.asis(iso(o).bytype.kind.arg, type(o))
        for o in li:
            if o is a.__dict__:
                kind = iso(a).kind
            elif o is b.__dict__:
                kind = iso(b).kind
            elif type(o) is dict:
                kind = Use.Nothing
            elif o is a:
                kind = a.__class__
            else:
                kind = type(o)
            self.aseq(iso(o).kind.arg, kind)
        cla = iso(()).byunity.kind
        self.asis(cla.arg, None)
        for o in li:
            self.aseq(iso(o).byunity.kind, cla)
        for o in li:
            self.aseq(iso(o).byid.kind, Use.Id(id(o)))
        # self.View.update_referrers(nodeset(li))
        for i, o in enumerate(li):
            cl = iso(o).byrcs.kind
            if 1 <= i <= 2:
                self.aseq(cl, Use.Clodo.sokind(list).refdby)
            if i == 5:
                self.aseq(cl, Use.Clodo.sokind(A)(list).refdby)
            if i == 6:
                self.aseq(cl, Use.Clodo.sokind(B)(list).refdby)

    def test_selection(self):
        # Test classifications operations via selection invariant

        Use = self.Use

        class A:
            pass

        class B(object):
            pass
        a = A()
        b = B()
        li = Use.iso(135, [], {}, a, b, a.__dict__, b.__dict__)

        allers = (Use.Unity, Use.Type, Use.Clodo,
                  Use.Rcs, Use.Via)  # , Use.Id
        ps = {}
        for er in allers:
            # p = er.classifier.partition(li.nodes)
            p = [(av.kind, av) for av in li.by(er).partition]
            for ak, av in p:
                if ak in ps:
                    self.aseq(ps[ak],  av)
                else:
                    ps[ak] = av

        for ak, av in list(ps.items()):
            self.aseq(ak & li, av)
            for bk, bv in list(ps.items()):
                # Test set operations by selection definition
                self.aseq((ak & bk) & li, av & bv)
                self.aseq((ak | bk) & li, av | bv)
                self.aseq((ak - bk) & li, av - bv)
                self.aseq((bk - ak) & li, bv - av)
                self.aseq((ak ^ bk) & li, av ^ bv)


def test_main(testrender=1, debug=0):
    support.run_unittest(BaseCase, debug)
    support.run_unittest(ClassificationCase, debug)
    support.run_unittest(LawsCase, debug)
    support.run_unittest(RenderCase, debug)
    support.run_unittest(SpecialCases, debug)