ÿØÿà JFIF    ÿÛ „ !.%+&8&+/1555$;@;4?.451 4,$,44444444444414444444444444444444444444444444444444ÿÀ  á á" ÿÄ     ÿÄ ?    !1AQaq"2‘¡±ÁðBRbrÑá#‚’¢²3S CñÿÄ   ÿÄ !    !1QAa‘2ÿÚ   ? 5˜Z¯V¦cø)›t/? z¨±>Õ5€¶‹Á¤·¼z¼Ü¬+ñ®v¤¨_ˆR­BFn©—˜ý®ç̝P8gýt·ÉSTŦˆìät?þé¼íìN/Þa)ì–í6ô… Ï¿øÃj´¿KÇü]ÿ ªô¹-eKànëÕHTx}ýSÜ›ÿ ”7Ø×&µ<¦  ¥ÑO¶[Ù¯ä¨ÞÃÿ PZ-¬;#õ|•oaÿ ©CìÞz3˜öː/¤­ñTûIØ}š^ mÓ%ªxˆ¥ÉŸu=Z+ISe¿45™¼u;ú&WØ÷€æßQ™®{|íx*TC“#ZŠìZ§²‹ 6pv…³¿¡äª*áZÐ%ÒOáˆo"x«OHk w±æ+¬V(kMúŸ5Vö«$ ÁrÏbàb57/luR ¸ÑÛj Òµì`Мq­û žICÀÊ•©4€Âcà¨Ï€O´<èÐ:›ù(Ë^L8þ‘ÍÌ#¸Ð_Ì©ÙK(Öz 4¬û+¸;ü’V’84‘¬ÃŽ:[â‡ÔÌáõp¢~§ªlæ£ö{®G>J¼"°‡7¯ÆÉèßû ‹É‹§ÁòÃýâßî ^ƾÙõ‹×óH#«LP½ïX=xÑÍ$|W?•~• îëÔ©ª‹ {ÝT…Kÿ ”hûâá)J*ö˜–ÔU;iÇ€/ ÆþjóZ\ýwØ=Ìm ºèËL9 ýèÆð/¨’¥öo=nË.%Îì ŽÕ¯È|{Oj²ƒE6e/ßdÄõ²Ìâ1O®ò×TsəԸhOMýíMˆ¿¼H˜l²,7Â¥#MF/Úf°Ö½± ¸–dr‹NýÊ íjqx{œÉ ä-È ¦ øÄër¨q°ð †nцýÑÄÆ’mä…n<0È™;ÁÝá¯ÁZƒ7FÀmì­ É&9ˆîéi¶ùN§Y• ÃZãAâ?•‡©‰ , ó¾IŸŠc1 4â&y­&pŠ­6;M À 0¹qç»p.á …ŸÅáK@%6·y6ƒ‰3?”úºŽ‰éX5ªPT §µ!=Mž«Ú½‹ÅgÂSâÉaþÓoö–¯ÁÔìR>5éÿ üs¶ÆUcÌ kÇR ]ÿ ù¬¼«VŽ;Â|‡~¢¦”ÏŰæ {L™Õ°Óv¹ò¸írޡעCÃ!íVÕ {¶»sŒNPg/ "uÕbkm²“$ďå¿é¹§°½æz¯6 †s¿!s–wÚÝ“™Œ °.ûj>·+™Òa…©Œ&rÝÎtÛë긪Ît’LAVp%c Úý[ÄzJ¾ÇàXXç@˜ó<êL]·T˜¾¥1Ó©V‡g´æ½¦Ý@¹óø!_@´ÞâSÁ —S3™•& ]@JHÚý©ZŽ €×æÔr»Áf!‡yÞ4Mv*èÓã_{‘åóUuљØ«Oïé*®EvÑ Œ÷‡U \"㪒ÍK+À 4“M¡ï:0¥5í!'<@î´”>Ç»&Z–ïCCV˜Ì5Šo&îhè.žû |ÓK©h$s6KìŒëã)¹hI¦GïOåóI;ììü#É$Š0…Ææ¥TØ.5­¾gn´ “ÂÖ\:hœ89G)J@„}œ:’Ò{/Š"¦_Æ×7Æ3VÇŠÊa]ÚŒÙ€Ä–=®uÁßâACZƒ§§£ Qnâ:«,×{tyø¬iÛcœÜÄ€H½ÄÍCk´÷šß .W'b¤Íåh]÷€=,Žv×cÚEÚHXJX¶îo¨FÒtèöŸ>ªª6[J®Fµ£sGÁeqõfe\íjÒÐïÄÐGˆe1Ø‹.Ø”‘Ëuø Y­ˆÜ ŽG|zùªüMpDnQWÄ”%JŠ™)â*p@Örš«ÕT2Ð%ˆG#ª„ ·¤!°ŸOTÂT¸aÚ%4&h™LµšØüÐ.F¿²ÐÞ_Ç‚¾ÅÃaÜ÷09Æ q€öy˜v‡85õN÷]¬äѼóS{°_MެúÔ#°Ç¸0åÞè2ëôPcvÆw9®ií1Ä8F™˜à‰´+‰Ik1òÝ7“Ñ×ÒsÝ\x‚h`ÞÑ`ó"|µEcý£n˜h`}GÞ !±ù²Ápü²ß6 0ïi󜵩SÈÇ7˜-ÕURO˜¦´f$ªž-Í6(œ}<„ éc øs]ŽŽ„*—¾ ìdŽ„)méª\¿êÎIg¾ØÞ~I#C/¼¼´EÁÈŽi8“©õådô·>euä ƒ'Ê×लR1ÉJE1ÐAát`t;ÇР%Ý<‡¥„ÍÆ`×Oyó)õiI€ñQaŸ4Ûù\áàaÃÔ¹HÃu¹*k€¦<„e S‡&õÏ B!ŽhüÞ`yj}mªf×\¿ Ç~æ­9‡û\՞Ǖg²1Žû5V7 !àöšm° c`ܬøÇìµÒ'P"?…´Ö,"§^•õލsÔ)6˜sæéÍR¼ ò|Sl”‹7 nPW Gòú÷½§O¯‡„l¡kSÞŒr½PÊ@æ¢pŽ-mÿ #Ÿ˜Àº¶Áä¦;ïÔæ$1££`“Õ>„—·ž)ßð³ñ#Ï Ô$¶œ‰ÊE‹À;÷º ¯«P:Ñ”8–IÊtpÞ3ª“>ê“þës4ò2OÏÕ­±zô†Õ§‰.÷ä¸;¿˜“'œ›žª}«Œ{ª±Ì 9ÔóÞÕ‡0 $íWV3Üì¬ —@kÝ4@¿r¼±½¬™›?øØæ´'Áé®CË3-g$˜ö‡×auÚi´Žp/êÛ æF›Ú2v‹ã¿¿,nB1̨ƃqÞa5͝@&Æû“él÷ \C²½UÍc ¯k×¢U ÖéQå™—-r wô ÞÏ<Ò=&=ÿ Ôê Òêˈt,i—;LîÜ á¸*ÚÃ1$êL•LÍ <É)ýÐà’ ;F™{ƒ™˜€&'}‚ãÄK`¡ÞT@I;®žZóè‚s’7®°›+§O­Åq©é»²9<Ô J ¼9O’HL»Ùïì¸rk¼Ž_ý‘TŸu[²ßÚŒ·ü÷B%¯E ŸÔX5êO´ Ç•€’I0 ÉJX` ñ¹õ%;µŸD‘«´€àwÒ™U ûئžÖö\×®×´8 ½‡ºÐÆÓ§?Àkmœ=;d5*@-ì0F Rªýš[Ü6âö̃ڸr*KA9· u*µæ£?U¸Âêí†8@¦X4 e-ò„0s{ HâUpU?¼mñRa°®a%Ð'tÉ×’\¾ÊÉ]t›h>·(Ë@R¼¡Ãt h}’O÷au<+nT…Ö…MӐ??Óe95 q>í/;&JSû °¯ÊéÞ øƒ*Ã2½Ài&:nôUl=¾¿5eˆ3”ñc|Ú2V”>„»&eE;«ÚäC p¢Û úy 9š[ŒÌx¼擼A&DåÒ¯ˆ¤ÀÌ;"˜ ÏQä¸åhÊ}Ûq«Û0WžÒ|»€ø®öCm5•\ÇÀ§Pe3£]0ÃàLDÉ‰1øªxjgwT‚÷¿LΨK‹›ùs—xˆÜ±µ kæ¸f‰‰ÜGk/LÛØ6d9ò¶ùA{ƒA3š/¬D¬khÓk‰`˜"㯒r¿±Óã jx‡°e}<Ñø\3y:'À•/h½Í€Ç4~g ?Û(¼]v‘ªlKÎâ~?O‚W%{Ì:“'©úNq¾›úo(X’¥¯ˆ nFê{Ç€ü?º'ë ø‹ì Þ09ŒÌç9Æ —ËC`j@ÓÄ(+a‹un¸#ÂꟋ{K`‘ÑÍÍ'à´»/Û,KW;Þ4²þð ï Nm|~fGÏ(…³Ã)«1ö­Õ ¥‡¨©ƒÃ™ü-s=à=U66Ï«Ýc蓦W¹íž®›nÔ%êÇìŒ<#Ü×84ån®Ð ÒåOC` ñânÑs‡¢ç 1õ%Îhì½Ã½® e:ݼUZo™`  ÅZŸŒÊ«ê1ÏÄo$q¹Þ€©ˆhÐÉä¯ñ[!…Ú˜àJ:x2$Íß&PåT£6ç— ‡Í*4Ýšçjÿ ‰É nófÐ ó(L5C•åÆ\rMÒ@ò }y-W}™üýVù—ú¢=Ù”c®‘< M ž ´Phr ¦©TD ‘ù.$´÷O‡‘V2Æò.=IUŒ=ž‡â¬i™aþÓåÙ?òUø'ØÖ•.~* šTŒ!•-×áºTâ®ä#õü'´ eýlYÅÓeÕKÂrT"CÚ@u!Óxƒ{š3€}1¿(r}%«nËamjÑ%ÑNEò v ˜à  σöK³,*º.àzù¨™Ó ÚçâU¦*¿ 9{%Ö¹ njûdaXöb) kÛÆ±ûÓ\°M7ˆÂ=û›ç¿Ã‚­V»Cg–8ÙêE- j)k$º`Ã-ùEýeBÆÇ]c¡°ñty&Òd0nõ'¡W+ƒ*|–øµFa\GQªEAÔp5\Ǽ·¼Ç8·õ -â§Ú[ ‡ uZeÖ 3}×d'+¹:ð+K†Û®s!Ï$úe€<Û”x)1»a­¡LC]¸µík…ÚàA»AYº{†ªS[¦5HÒ7ù --,ísòDØ€èk ÞÀîÜ ò@â( ËNˆë›4ô½•/¦o‡€Û7 ê•ÆêòðÜy'Án½µ á˜ݦ ndeo…[ì¶Ê,¥R³Ä=À±—–ß;£™´ñSâ*g§”ïaið‘Jå~™ÓÞ ß³Õ¢»8x埒²52>AÊb&-÷\7´éÄù€T˜,w;3{ï˜k…à¹ÄqÀ«œ{€\ ˆ¾[´¨јr &Úé„Ívˆ±8†¿]|¬ņ4I×pÞS1ÈÖz‰#Ìv‡G!YNògñ:màTz¢Ý1ô©^O=~ë|5Bã™ç•¼µõ•bÆ@úÕS¬ÈŒ#¬zünrŸ û” Z²•èðV"ÁHÚý©wÝ €7¼Ìu1hÑa3Éä û f$o¿É ™Ú›ÝçnpÒ3äÌ3†Í§,Äï]$‰/pê †«À¼¸e9­Æê_C]žƒ·ý·frÁN«, E=›Çq -‰öŒ:aÏ¿±í&£Í:-} 84‘ÿ eƒQÑeëSsuiA ³g㟥ú£?ÿ ʼn*”“÷aühe:ÊWa@ÒÞk±eØ] F Ô—r.åä˜ @ö¥ªZoÐýYL·¥S²G/‡ñ <~*ZÆ´è>JlòàÛÆ½ÿ 窘ìGN¢:I®KšJp/`íIÁÀõ#Ä-€ö­šµŒoF4|ÆQØÆ@Ì|£Ô…¢À{9˜è½Üó›€ôYÒÎYsið;ís¤€à²ˆ‚4qÉVŒI$ ‰"° æµ8cXGjœˏ¡Aâý•ËÜ¢ûï e·çLx']á"oÅÎê3¯Ç—¹”ó0nå‚âg{Œñ> S´˜îè°g238‚ãköÝfÚd´6Ò€;ò÷±¢™¼›º ¢Æ'¥Ðx'e¬ç ]bÈÆV¢ó‹kýBO ðÊâ$Ÿ!×T 3Mýמ žìٍàÌü‘8÷€àæØ8æ©6‰©L´«…oãpð„~Çk‰!ñ;‹”ÛžÍ àž±z Ÿôû øŸÝužÏ;ÿ #|u6™Þ¬ÚˆÐõA4¶â|ôl|Ê2ŽÇ¤ÝÅÇY.<#Aí.k§hóF‚”Y; M½Ö4hŸ4&›­¿tès´%FìL¥£Ãk‰ÇT¤haÁ¤ÚxfÉ`ÑìË›>i 3t‚:,–+^÷´–{Û–Nxi"x‘Ûg î¨>¥Õ܁ùZH,2Û“:8xÊ¢Çí9.É-Ìâã-=çjwµS˜dütžçwýGòú®®ûº_ˆýx$–¡ãøO EÚÛÏ÷R„×w+3£Á£öUMyR²¹âŒ°š›¸Ñãò9§Ó_Dl+Ùßc›úšGÅÌc†Ž!Ko=¶.‘Îÿ c²(2®V mª.ÿ ¹B›¹å ù„öŸSV>™ü¯$y:G¢Z×àøúdî¹û­·ýÇ´:•c LÍõi_‹ö+ÎæGÊè>OŠ•äž´§Þ{X}¨1ÚTc›»Qþ•êô°t¿OP?eæ~É{5]•ÙR£r5†nZ\ã@ &îJõ ¾àC°þV>fé¥/ü5ñÊIº_é5 ;e­h<@ Ä&æÃëE%;X,ÒãÆÞ`Oò¦kŸm#˜!ÀyÄ¢| óLšò¥Ä` ¶R=|ÈCâh5ò3DˆïF†ðÒ#ÅìÛœ?¸yhBãœí ZxßÎÄhºRK„`Þödvײ™ÀÈÑÒgŒuY w³%†ƒÓzõ ÖÏp‚dH®¦A´ù§»ÓÇMæ~)ˆð‡û:ù&Ä •vGD´À n ݇¼Ö8Fö óáà£~Ë¥x`oK|Ä?fxiØü%pìR>éò+Û±éÎ>núlFŤ'tq8LZÏvÃ?„¡ß±È⽆¯³íü@x|PöUäèØã¡ð‚ŒAìÏ"vÍwóŸÍ{ ý0.z È•Ö{,N¡£¡ŸKÕÙž>Ýœþ ÍÀ°<×EA!Å‚D™IúOÍ¡>ôG}Â` ÍßkÜL™Ž Þð™ {IøF²¹òQ3&!ÃÂÞz.d&Ï-sH¸,Ôõ˜ŽP€ 77ˆÝ¼ÊëÜw =cÕ Ú,ØÐ5ÎYÐ)ì´öœgŒ[¤ßv㙑8心>h]§µháYš£²ºÑ.{Ï7Sð•?´~×SÃKýJÛ˜ ™Íäiúu<µX¶1õ^kâçIÑ£sZ4h>j*ÔšD:4­¿_ ÷¸ Õxæÿ ¸?Mù _•­ÊÐ ä ÷ý ÑwL œ­ïnTkÛUÍN©ë:¦fV ¶ÜÔÜMªÅâA½–¿R×TXš-%iTÊT•‡Ù‚JôϐZxWÑè‰f‰òG º ×Õû2aZ7OU3[“×AT–ÞŒ…-‘¤”Ì ì&(ˆ¿­•ƒkï’:ðY¦W‘ Å)“†‘˜³Åtcø˜ñTÂwÚÇ4|üLÇªí–v- qˆèU qPE.†â‘˜µ Æ,ÐÅs]8¾„oúÑ i>ÜxxÈó)ƒ ´æÁâØ$À‰vžŸf$Ž |ãw;ÀÁIJ»b` {¦Ó¤Ú$©YÀ‘n@Óïž«9J¼êG m¤ ܯ¹ÌW4€ÐÒÅÛ‡#褕Ÿn-?í|с¥÷Ú¹¬'´ÞÜ9ÓK `hê£SÄSà?7—Wí_´…óB›»:=Ãïq`<8ñÓŒÑlú2d¬ê³£hÖ[l|$vÝro~'R®‰§°ñmY ͧäP |PUª¹·:3Œ[Û{Xÿ ºâ@‚W–Äé u‚ ¯´*=íή.pûÒdt @G‰¬ s¸ ëÉücr ÞæÑ¨Ê@>¤¢Ö±. Þ'¯°ÌME[YéïĵÂCå½ Ué©Áû'Ê9%eÔðNU”ë‘ÌsD3/®+UI˜9h.WC”빓$#:pz:YÓ ¿xž* ³$Í +$kñAŠ‹†¢ Uê>¸)_š¬÷©ßAÂÔb9ÇU ¯¾á•9¯ÏÏ÷O÷¼¼Fähal1‰3Ì[Ïr•´UCksNÐ] R‘¸¥H+§Šé†c©vÖÞ0iÓ76s†î!§=ß ¼~Ô'°Ãmäoäš³ªøi1úÉ)³yV8 CLÄØÁ‘WYïi€H6ÖÑiámø^ÈY´°Ñ7¥Û*—Ñ©L«Qƒï—Ùrÿ ›£Ð*š¸ˆL©ˆ$ˆ ÷¾D§9È®«qbqC)–ˆïv´çñsÑVT­Ø, <àïºÀO«Jý·õ àfPìð .wFšir´þ’2_Y *Æ€x\« ì€9š@ Ž|F⇥ˆkZ@hÖÄ0t¿-<“‹qµ¾*ZL¤Ú)&BJpÓF5=$„at*Zš$’ÑtdûÝRI1 2މ$€$I$#‰SÞ’Hë¬ï;Á$¡t$’`<(ñÇt)$‡Ð.Êf¢X’Kt=Éé$‚ˆªè¢oÝëòI%Rgcª÷ŠyI%¡‰ÿ !ñ)´õ $¤ Ô’IIGÿÙ# Python test set -- built-in functions import unittest import sys import pickle import itertools from test.support import ALWAYS_EQ # pure Python implementations (3 args only), for comparison def pyrange(start, stop, step): if (start - stop) // step < 0: # replace stop with next element in the sequence of integers # that are congruent to start modulo step. stop += (start - stop) % step while start != stop: yield start start += step def pyrange_reversed(start, stop, step): stop += (start - stop) % step return pyrange(stop - step, start - step, -step) class RangeTest(unittest.TestCase): def assert_iterators_equal(self, xs, ys, test_id, limit=None): # check that an iterator xs matches the expected results ys, # up to a given limit. if limit is not None: xs = itertools.islice(xs, limit) ys = itertools.islice(ys, limit) sentinel = object() pairs = itertools.zip_longest(xs, ys, fillvalue=sentinel) for i, (x, y) in enumerate(pairs): if x == y: continue elif x == sentinel: self.fail('{}: iterator ended unexpectedly ' 'at position {}; expected {}'.format(test_id, i, y)) elif y == sentinel: self.fail('{}: unexpected excess element {} at ' 'position {}'.format(test_id, x, i)) else: self.fail('{}: wrong element at position {}; ' 'expected {}, got {}'.format(test_id, i, y, x)) def test_range(self): self.assertEqual(list(range(3)), [0, 1, 2]) self.assertEqual(list(range(1, 5)), [1, 2, 3, 4]) self.assertEqual(list(range(0)), []) self.assertEqual(list(range(-3)), []) self.assertEqual(list(range(1, 10, 3)), [1, 4, 7]) self.assertEqual(list(range(5, -5, -3)), [5, 2, -1, -4]) a = 10 b = 100 c = 50 self.assertEqual(list(range(a, a+2)), [a, a+1]) self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1]) self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2]) seq = list(range(a, b, c)) self.assertIn(a, seq) self.assertNotIn(b, seq) self.assertEqual(len(seq), 2) seq = list(range(b, a, -c)) self.assertIn(b, seq) self.assertNotIn(a, seq) self.assertEqual(len(seq), 2) seq = list(range(-a, -b, -c)) self.assertIn(-a, seq) self.assertNotIn(-b, seq) self.assertEqual(len(seq), 2) self.assertRaises(TypeError, range) self.assertRaises(TypeError, range, 1, 2, 3, 4) self.assertRaises(ValueError, range, 1, 2, 0) self.assertRaises(TypeError, range, 0.0, 2, 1) self.assertRaises(TypeError, range, 1, 2.0, 1) self.assertRaises(TypeError, range, 1, 2, 1.0) self.assertRaises(TypeError, range, 1e100, 1e101, 1e101) self.assertRaises(TypeError, range, 0, "spam") self.assertRaises(TypeError, range, 0, 42, "spam") self.assertEqual(len(range(0, sys.maxsize, sys.maxsize-1)), 2) r = range(-sys.maxsize, sys.maxsize, 2) self.assertEqual(len(r), sys.maxsize) def test_range_constructor_error_messages(self): with self.assertRaisesRegex( TypeError, "range expected at least 1 argument, got 0" ): range() with self.assertRaisesRegex( TypeError, "range expected at most 3 arguments, got 6" ): range(1, 2, 3, 4, 5, 6) def test_large_operands(self): x = range(10**20, 10**20+10, 3) self.assertEqual(len(x), 4) self.assertEqual(len(list(x)), 4) x = range(10**20+10, 10**20, 3) self.assertEqual(len(x), 0) self.assertEqual(len(list(x)), 0) self.assertFalse(x) x = range(10**20, 10**20+10, -3) self.assertEqual(len(x), 0) self.assertEqual(len(list(x)), 0) self.assertFalse(x) x = range(10**20+10, 10**20, -3) self.assertEqual(len(x), 4) self.assertEqual(len(list(x)), 4) self.assertTrue(x) # Now test range() with longs for x in [range(-2**100), range(0, -2**100), range(0, 2**100, -1)]: self.assertEqual(list(x), []) self.assertFalse(x) a = int(10 * sys.maxsize) b = int(100 * sys.maxsize) c = int(50 * sys.maxsize) self.assertEqual(list(range(a, a+2)), [a, a+1]) self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1]) self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2]) seq = list(range(a, b, c)) self.assertIn(a, seq) self.assertNotIn(b, seq) self.assertEqual(len(seq), 2) self.assertEqual(seq[0], a) self.assertEqual(seq[-1], a+c) seq = list(range(b, a, -c)) self.assertIn(b, seq) self.assertNotIn(a, seq) self.assertEqual(len(seq), 2) self.assertEqual(seq[0], b) self.assertEqual(seq[-1], b-c) seq = list(range(-a, -b, -c)) self.assertIn(-a, seq) self.assertNotIn(-b, seq) self.assertEqual(len(seq), 2) self.assertEqual(seq[0], -a) self.assertEqual(seq[-1], -a-c) def test_large_range(self): # Check long ranges (len > sys.maxsize) # len() is expected to fail due to limitations of the __len__ protocol def _range_len(x): try: length = len(x) except OverflowError: step = x[1] - x[0] length = 1 + ((x[-1] - x[0]) // step) return length a = -sys.maxsize b = sys.maxsize expected_len = b - a x = range(a, b) self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 self.assertEqual(x[idx], a+idx) self.assertEqual(x[idx:idx+1][0], a+idx) with self.assertRaises(IndexError): x[-expected_len-1] with self.assertRaises(IndexError): x[expected_len] a = 0 b = 2 * sys.maxsize expected_len = b - a x = range(a, b) self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 self.assertEqual(x[idx], a+idx) self.assertEqual(x[idx:idx+1][0], a+idx) with self.assertRaises(IndexError): x[-expected_len-1] with self.assertRaises(IndexError): x[expected_len] a = 0 b = sys.maxsize**10 c = 2*sys.maxsize expected_len = 1 + (b - a) // c x = range(a, b, c) self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 self.assertEqual(x[idx], a+(idx*c)) self.assertEqual(x[idx:idx+1][0], a+(idx*c)) with self.assertRaises(IndexError): x[-expected_len-1] with self.assertRaises(IndexError): x[expected_len] a = sys.maxsize**10 b = 0 c = -2*sys.maxsize expected_len = 1 + (b - a) // c x = range(a, b, c) self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 self.assertEqual(x[idx], a+(idx*c)) self.assertEqual(x[idx:idx+1][0], a+(idx*c)) with self.assertRaises(IndexError): x[-expected_len-1] with self.assertRaises(IndexError): x[expected_len] def test_invalid_invocation(self): self.assertRaises(TypeError, range) self.assertRaises(TypeError, range, 1, 2, 3, 4) self.assertRaises(ValueError, range, 1, 2, 0) a = int(10 * sys.maxsize) self.assertRaises(ValueError, range, a, a + 1, int(0)) self.assertRaises(TypeError, range, 1., 1., 1.) self.assertRaises(TypeError, range, 1e100, 1e101, 1e101) self.assertRaises(TypeError, range, 0, "spam") self.assertRaises(TypeError, range, 0, 42, "spam") # Exercise various combinations of bad arguments, to check # refcounting logic self.assertRaises(TypeError, range, 0.0) self.assertRaises(TypeError, range, 0, 0.0) self.assertRaises(TypeError, range, 0.0, 0) self.assertRaises(TypeError, range, 0.0, 0.0) self.assertRaises(TypeError, range, 0, 0, 1.0) self.assertRaises(TypeError, range, 0, 0.0, 1) self.assertRaises(TypeError, range, 0, 0.0, 1.0) self.assertRaises(TypeError, range, 0.0, 0, 1) self.assertRaises(TypeError, range, 0.0, 0, 1.0) self.assertRaises(TypeError, range, 0.0, 0.0, 1) self.assertRaises(TypeError, range, 0.0, 0.0, 1.0) def test_index(self): u = range(2) self.assertEqual(u.index(0), 0) self.assertEqual(u.index(1), 1) self.assertRaises(ValueError, u.index, 2) u = range(-2, 3) self.assertEqual(u.count(0), 1) self.assertEqual(u.index(0), 2) self.assertRaises(TypeError, u.index) class BadExc(Exception): pass class BadCmp: def __eq__(self, other): if other == 2: raise BadExc() return False a = range(4) self.assertRaises(BadExc, a.index, BadCmp()) a = range(-2, 3) self.assertEqual(a.index(0), 2) self.assertEqual(range(1, 10, 3).index(4), 1) self.assertEqual(range(1, -10, -3).index(-5), 2) self.assertEqual(range(10**20).index(1), 1) self.assertEqual(range(10**20).index(10**20 - 1), 10**20 - 1) self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87) self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86) self.assertEqual(range(10).index(ALWAYS_EQ), 0) def test_user_index_method(self): bignum = 2*sys.maxsize smallnum = 42 # User-defined class with an __index__ method class I: def __init__(self, n): self.n = int(n) def __index__(self): return self.n self.assertEqual(list(range(I(bignum), I(bignum + 1))), [bignum]) self.assertEqual(list(range(I(smallnum), I(smallnum + 1))), [smallnum]) # User-defined class with a failing __index__ method class IX: def __index__(self): raise RuntimeError self.assertRaises(RuntimeError, range, IX()) # User-defined class with an invalid __index__ method class IN: def __index__(self): return "not a number" self.assertRaises(TypeError, range, IN()) # Test use of user-defined classes in slice indices. self.assertEqual(range(10)[:I(5)], range(5)) with self.assertRaises(RuntimeError): range(0, 10)[:IX()] with self.assertRaises(TypeError): range(0, 10)[:IN()] def test_count(self): self.assertEqual(range(3).count(-1), 0) self.assertEqual(range(3).count(0), 1) self.assertEqual(range(3).count(1), 1) self.assertEqual(range(3).count(2), 1) self.assertEqual(range(3).count(3), 0) self.assertIs(type(range(3).count(-1)), int) self.assertIs(type(range(3).count(1)), int) self.assertEqual(range(10**20).count(1), 1) self.assertEqual(range(10**20).count(10**20), 0) self.assertEqual(range(3).index(1), 1) self.assertEqual(range(1, 2**100, 2).count(2**87), 0) self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1) self.assertEqual(range(10).count(ALWAYS_EQ), 10) self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10) def test_repr(self): self.assertEqual(repr(range(1)), 'range(0, 1)') self.assertEqual(repr(range(1, 2)), 'range(1, 2)') self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)') def test_pickling(self): testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3), (-2, 2, 2), (2**65, 2**65+2)] for proto in range(pickle.HIGHEST_PROTOCOL + 1): for t in testcases: with self.subTest(proto=proto, test=t): r = range(*t) self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))), list(r)) def test_iterator_pickling(self): testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3), (-2, 2, 2)] for M in 2**31, 2**63: testcases += [ (M-3, M-1), (4*M, 4*M+2), (M-2, M-1, 2), (-M+1, -M, -2), (1, 2, M-1), (-1, -2, -M), (1, M-1, M-1), (-1, -M, -M), ] for proto in range(pickle.HIGHEST_PROTOCOL + 1): for t in testcases: with self.subTest(proto=proto, t=t): it = itorg = iter(range(*t)) data = list(range(*t)) d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), data) it = pickle.loads(d) try: next(it) except StopIteration: continue d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), data[1:]) def test_iterator_pickling_overflowing_index(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(proto=proto): it = iter(range(2**32 + 2)) _, _, idx = it.__reduce__() self.assertEqual(idx, 0) it.__setstate__(2**32 + 1) # undocumented way to set r->index _, _, idx = it.__reduce__() self.assertEqual(idx, 2**32 + 1) d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(next(it), 2**32 + 1) def test_exhausted_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): r = range(2**65, 2**65+2) i = iter(r) while True: r = next(i) if r == 2**65+1: break d = pickle.dumps(i, proto) i2 = pickle.loads(d) self.assertEqual(list(i), []) self.assertEqual(list(i2), []) def test_large_exhausted_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): r = range(20) i = iter(r) while True: r = next(i) if r == 19: break d = pickle.dumps(i, proto) i2 = pickle.loads(d) self.assertEqual(list(i), []) self.assertEqual(list(i2), []) def test_odd_bug(self): # This used to raise a "SystemError: NULL result without error" # because the range validation step was eating the exception # before NULL was returned. with self.assertRaises(TypeError): range([], 1, -1) def test_types(self): # Non-integer objects *equal* to any of the range's items are supposed # to be contained in the range. self.assertIn(1.0, range(3)) self.assertIn(True, range(3)) self.assertIn(1+0j, range(3)) self.assertIn(ALWAYS_EQ, range(3)) # Objects are never coerced into other types for comparison. class C2: def __int__(self): return 1 def __index__(self): return 1 self.assertNotIn(C2(), range(3)) # ..except if explicitly told so. self.assertIn(int(C2()), range(3)) # Check that the range.__contains__ optimization is only # used for ints, not for instances of subclasses of int. class C3(int): def __eq__(self, other): return True self.assertIn(C3(11), range(10)) self.assertIn(C3(11), list(range(10))) def test_strided_limits(self): r = range(0, 101, 2) self.assertIn(0, r) self.assertNotIn(1, r) self.assertIn(2, r) self.assertNotIn(99, r) self.assertIn(100, r) self.assertNotIn(101, r) r = range(0, -20, -1) self.assertIn(0, r) self.assertIn(-1, r) self.assertIn(-19, r) self.assertNotIn(-20, r) r = range(0, -20, -2) self.assertIn(-18, r) self.assertNotIn(-19, r) self.assertNotIn(-20, r) def test_empty(self): r = range(0) self.assertNotIn(0, r) self.assertNotIn(1, r) r = range(0, -10) self.assertNotIn(0, r) self.assertNotIn(-1, r) self.assertNotIn(1, r) def test_range_iterators(self): # exercise 'fast' iterators, that use a rangeiterobject internally. # see issue 7298 limits = [base + jiggle for M in (2**32, 2**64) for base in (-M, -M//2, 0, M//2, M) for jiggle in (-2, -1, 0, 1, 2)] test_ranges = [(start, end, step) for start in limits for end in limits for step in (-2**63, -2**31, -2, -1, 1, 2)] for start, end, step in test_ranges: iter1 = range(start, end, step) iter2 = pyrange(start, end, step) test_id = "range({}, {}, {})".format(start, end, step) # check first 100 entries self.assert_iterators_equal(iter1, iter2, test_id, limit=100) iter1 = reversed(range(start, end, step)) iter2 = pyrange_reversed(start, end, step) test_id = "reversed(range({}, {}, {}))".format(start, end, step) self.assert_iterators_equal(iter1, iter2, test_id, limit=100) def test_range_iterators_invocation(self): # verify range iterators instances cannot be created by # calling their type rangeiter_type = type(iter(range(0))) self.assertRaises(TypeError, rangeiter_type, 1, 3, 1) long_rangeiter_type = type(iter(range(1 << 1000))) self.assertRaises(TypeError, long_rangeiter_type, 1, 3, 1) def test_slice(self): def check(start, stop, step=None): i = slice(start, stop, step) self.assertEqual(list(r[i]), list(r)[i]) self.assertEqual(len(r[i]), len(list(r)[i])) for r in [range(10), range(0), range(1, 9, 3), range(8, 0, -3), range(sys.maxsize+1, sys.maxsize+10), ]: check(0, 2) check(0, 20) check(1, 2) check(20, 30) check(-30, -20) check(-1, 100, 2) check(0, -1) check(-1, -3, -1) def test_contains(self): r = range(10) self.assertIn(0, r) self.assertIn(1, r) self.assertIn(5.0, r) self.assertNotIn(5.1, r) self.assertNotIn(-1, r) self.assertNotIn(10, r) self.assertNotIn("", r) r = range(9, -1, -1) self.assertIn(0, r) self.assertIn(1, r) self.assertIn(5.0, r) self.assertNotIn(5.1, r) self.assertNotIn(-1, r) self.assertNotIn(10, r) self.assertNotIn("", r) r = range(0, 10, 2) self.assertIn(0, r) self.assertNotIn(1, r) self.assertNotIn(5.0, r) self.assertNotIn(5.1, r) self.assertNotIn(-1, r) self.assertNotIn(10, r) self.assertNotIn("", r) r = range(9, -1, -2) self.assertNotIn(0, r) self.assertIn(1, r) self.assertIn(5.0, r) self.assertNotIn(5.1, r) self.assertNotIn(-1, r) self.assertNotIn(10, r) self.assertNotIn("", r) def test_reverse_iteration(self): for r in [range(10), range(0), range(1, 9, 3), range(8, 0, -3), range(sys.maxsize+1, sys.maxsize+10), ]: self.assertEqual(list(reversed(r)), list(r)[::-1]) def test_issue11845(self): r = range(*slice(1, 18, 2).indices(20)) values = {None, 0, 1, -1, 2, -2, 5, -5, 19, -19, 20, -20, 21, -21, 30, -30, 99, -99} for i in values: for j in values: for k in values - {0}: r[i:j:k] def test_comparison(self): test_ranges = [range(0), range(0, -1), range(1, 1, 3), range(1), range(5, 6), range(5, 6, 2), range(5, 7, 2), range(2), range(0, 4, 2), range(0, 5, 2), range(0, 6, 2)] test_tuples = list(map(tuple, test_ranges)) # Check that equality of ranges matches equality of the corresponding # tuples for each pair from the test lists above. ranges_eq = [a == b for a in test_ranges for b in test_ranges] tuples_eq = [a == b for a in test_tuples for b in test_tuples] self.assertEqual(ranges_eq, tuples_eq) # Check that != correctly gives the logical negation of == ranges_ne = [a != b for a in test_ranges for b in test_ranges] self.assertEqual(ranges_ne, [not x for x in ranges_eq]) # Equal ranges should have equal hashes. for a in test_ranges: for b in test_ranges: if a == b: self.assertEqual(hash(a), hash(b)) # Ranges are unequal to other types (even sequence types) self.assertIs(range(0) == (), False) self.assertIs(() == range(0), False) self.assertIs(range(2) == [0, 1], False) # Huge integers aren't a problem. self.assertEqual(range(0, 2**100 - 1, 2), range(0, 2**100, 2)) self.assertEqual(hash(range(0, 2**100 - 1, 2)), hash(range(0, 2**100, 2))) self.assertNotEqual(range(0, 2**100, 2), range(0, 2**100 + 1, 2)) self.assertEqual(range(2**200, 2**201 - 2**99, 2**100), range(2**200, 2**201, 2**100)) self.assertEqual(hash(range(2**200, 2**201 - 2**99, 2**100)), hash(range(2**200, 2**201, 2**100))) self.assertNotEqual(range(2**200, 2**201, 2**100), range(2**200, 2**201 + 1, 2**100)) # Order comparisons are not implemented for ranges. with self.assertRaises(TypeError): range(0) < range(0) with self.assertRaises(TypeError): range(0) > range(0) with self.assertRaises(TypeError): range(0) <= range(0) with self.assertRaises(TypeError): range(0) >= range(0) def test_attributes(self): # test the start, stop and step attributes of range objects self.assert_attrs(range(0), 0, 0, 1) self.assert_attrs(range(10), 0, 10, 1) self.assert_attrs(range(-10), 0, -10, 1) self.assert_attrs(range(0, 10, 1), 0, 10, 1) self.assert_attrs(range(0, 10, 3), 0, 10, 3) self.assert_attrs(range(10, 0, -1), 10, 0, -1) self.assert_attrs(range(10, 0, -3), 10, 0, -3) def assert_attrs(self, rangeobj, start, stop, step): self.assertEqual(rangeobj.start, start) self.assertEqual(rangeobj.stop, stop) self.assertEqual(rangeobj.step, step) with self.assertRaises(AttributeError): rangeobj.start = 0 with self.assertRaises(AttributeError): rangeobj.stop = 10 with self.assertRaises(AttributeError): rangeobj.step = 1 with self.assertRaises(AttributeError): del rangeobj.start with self.assertRaises(AttributeError): del rangeobj.stop with self.assertRaises(AttributeError): del rangeobj.step if __name__ == "__main__": unittest.main()