superclass with tests common to all generators subclasses must arrange for self gen to retrieve the random instance to be tested helper function to make a list of random numbers return self gen random for i in rangen def testautoseedself self gen seed state1 self gen getstate time sleep0 1 self gen seed different seeds at different times state2 self gen getstate self assertnotequalstate1 state2 def testsaverestoreself n 1000 self gen seed state self gen getstate randseq self randomlistn self gen setstatestate should regenerate the same sequence self assertequalrandseq self randomlistn def testseedargsself seed value with a negative hash class myseedobject def hashself return 1729 for arg in none 0 1 1 1020 1020 false true 3 14 a self gen seedarg for arg in 12j tuple abc myseed with self assertraisestypeerror self gen seedarg for arg in listrange3 dictone1 self assertraisestypeerror self gen seed arg self assertraisestypeerror self gen seed 1 2 3 4 self assertraisestypeerror typeself gen def testseednomutatebug44018self a bytearrayb 1234 self gen seeda self assertequala bytearrayb 1234 unittest mock patch random urandom os urandom def testseedwhenrandomnesssourcenotfoundself urandommock random seed uses time time when an operating system specific randomness source is not found to test this on machines where it exists run the above test testseedargs again after mocking os urandom so that it raises the exception expected when the randomness source is not available urandommock sideeffect notimplementederror self testseedargs def testshuffleself shuffle self gen shuffle lst shufflelst self assertequallst lst 37 shufflelst self assertequallst 37 seqs listrangen for n in range10 shuffledseqs listrangen for n in range10 for shuffledseq in shuffledseqs shuffleshuffledseq for seq shuffledseq in zipseqs shuffledseqs self assertequallenseq lenshuffledseq self assertequalsetseq setshuffledseq the above tests all would pass if the shuffle was a noop the following nondeterministic test covers that it asserts that the shuffled sequence of 1000 distinct elements must be different from the original one although there is mathematically a nonzero probability that this could actually happen in a genuinely random shuffle it is completely negligible given that the number of possible permutations of 1000 objects is 1000 factorial of 1000 which is considerably larger than the number of atoms in the universe lst listrange1000 shuffledlst listrange1000 shuffleshuffledlst self asserttruelst shuffledlst shufflelst self asserttruelst shuffledlst self assertraisestypeerror shuffle 1 2 3 def testchoiceself choice self gen choice with self assertraisesindexerror choice self assertequalchoice50 50 self assertinchoice25 75 25 75 def testchoicewithnumpyself accommodation for numpy arrays which have disabled bool see https github compythoncpythonissues100805 choice self gen choice class nalist simulate numpy array behavior def boolself raise runtimeerror with self assertraisesindexerror choicena self assertequalchoicena50 50 self assertinchoicena25 75 25 75 def testsampleself for the entire allowable range of 0 k n validate that the sample is of the correct length and contains only unique items n 100 population rangen for k in rangen1 s self gen samplepopulation k self assertequallens k uniq sets self assertequallenuniq k self asserttrueuniq setpopulation self assertequalself gen sample 0 test edge case nk0 exception raised if size of sample exceeds that of population self assertraisesvalueerror self gen sample population n1 self assertraisesvalueerror self gen sample 1 def testsampledistributionself for the entire allowable range of 0 k n validate that sample generates all possible permutations n 5 pop rangen trials 10000 large num prevents false negatives without slowing normal case for k in rangen expected factorialn factorialnk perms for i in rangetrials permstupleself gen samplepop k none if lenperms expected break else self fail def testsampleinputsself sf bug 801342 population can be any iterable defining len self gen samplerange20 2 self gen samplerange20 2 self gen samplestr abcdefghijklmnopqrst 2 self gen sampletuple abcdefghijklmnopqrst 2 def testsampleondictsself self assertraisestypeerror self gen sample dict fromkeys abcdef 2 def testsampleonsetsself with self assertraisestypeerror population 10 20 30 40 50 60 70 self gen samplepopulation k5 def testsampleonseqsetsself class seqsetabc sequence abc set def initself items self items items def lenself return lenself items def getitemself index return self itemsindex population seqset2 4 1 3 with warnings catchwarnings warnings simplefiltererror deprecationwarning self gen samplepopulation k2 def testsamplewithcountsself sample self gen sample general case colors red green blue orange black brown amber counts 500 200 20 10 5 0 1 k 700 summary countersamplecolors countscounts kk self assertequalsumsummary values k for color weight in zipcolors counts self assertlessequalsummarycolor weight self assertnotin brown summary case that exhausts the population k sumcounts summary countersamplecolors countscounts kk self assertequalsumsummary values k for color weight in zipcolors counts self assertlessequalsummarycolor weight self assertnotin brown summary case with population size of 1 summary countersample x counts10 k8 self assertequalsummary counterx8 case with all counts equal nc lencolors summary countersamplecolors counts10nc k10nc self assertequalsummary counter10colors test error handling with self assertraisestypeerror sample red green blue counts10 k10 counts not iterable with self assertraisesvalueerror sample red green blue counts3 7 8 k2 counts are negative with self assertraisesvalueerror sample red green blue counts0 0 0 k2 counts are zero with self assertraisesvalueerror sample red green counts10 10 k21 population too small with self assertraisesvalueerror sample red green blue counts1 2 k2 too few counts with self assertraisesvalueerror sample red green blue counts1 2 3 4 k2 too many counts def testchoicesself choices self gen choices data red green blue yellow strdata abcd rangedata range4 setdata setrange4 basic functionality for sample in choicesdata k5 choicesdata range4 k5 choicesk5 populationdata weightsrange4 choicesk5 populationdata cumweightsrange4 self assertequallensample 5 self assertequaltypesample list self asserttruesetsample setdata test argument handling with self assertraisestypeerror missing arguments choices2 self assertequalchoicesdata k0 k 0 self assertequalchoicesdata k1 negative k behaves like 0 1 with self assertraisestypeerror choicesdata k2 5 k is a float self asserttruesetchoicesstrdata k5 setstrdata population is a string sequence self asserttruesetchoicesrangedata k5 setrangedata population is a range with self assertraisestypeerror choicessetdata k2 population is not a sequence self asserttruesetchoicesdata none k5 setdata weights is none self asserttruesetchoicesdata weightsnone k5 setdata with self assertraisesvalueerror choicesdata 1 2 k5 lenweights lenpopulation with self assertraisestypeerror choicesdata 10 k5 noniterable weights with self assertraisestypeerror choicesdata none4 k5 nonnumeric weights for weights in 15 10 25 30 integer weights 15 1 10 2 25 2 30 3 float weights fraction1 3 fraction2 6 fraction3 6 fraction4 6 fractional weights true false true false booleans include exclude self asserttruesetchoicesdata weights k5 setdata with self assertraisesvalueerror choicesdata cumweights1 2 k5 lenweights lenpopulation with self assertraisestypeerror choicesdata cumweights10 k5 noniterable cumweights with self assertraisestypeerror choicesdata cumweightsnone4 k5 nonnumeric cumweights with self assertraisestypeerror choicesdata range4 cumweightsrange4 k5 both weights and cumweights for weights in 15 10 25 30 integer cumweights 15 1 10 2 25 2 30 3 float cumweights fraction1 3 fraction2 6 fraction3 6 fraction4 6 fractional cumweights self asserttruesetchoicesdata cumweightsweights k5 setdata test weight focused on a single element of the population self assertequalchoices abcd 1 0 0 0 a self assertequalchoices abcd 0 1 0 0 b self assertequalchoices abcd 0 0 1 0 c self assertequalchoices abcd 0 0 0 1 d test consistency with random choice for empty population with self assertraisesindexerror choices k1 with self assertraisesindexerror choices weights k1 with self assertraisesindexerror choices cumweights k5 def testchoicessubnormalself subnormal weights would occasionally trigger an indexerror in choices when the value returned by random was large enough to make random total round up to the total see https bugs python orgmsg275594 for more detail choices self gen choices choicespopulation1 2 weights1e323 1e323 k5000 def testchoiceswithallzeroweightsself see issue 38881 with self assertraisesvalueerror self gen choices ab 0 0 0 0 def testchoicesnegativetotalself with self assertraisesvalueerror self gen choices abc 3 5 1 def testchoicesinfinitetotalself with self assertraisesvalueerror self gen choices a float inf with self assertraisesvalueerror self gen choices ab 0 0 float inf with self assertraisesvalueerror self gen choices ab float inf 123 with self assertraisesvalueerror self gen choices ab 0 0 float nan with self assertraisesvalueerror self gen choices ab float inf float inf def testgaussself ensure that the seed method initializes all the hidden state in particular through 2 2 1 it failed to reset a piece of state used by and only by the gauss method for seed in 1 12 123 1234 12345 123456 654321 self gen seedseed x1 self gen random y1 self gen gauss0 1 self gen seedseed x2 self gen random y2 self gen gauss0 1 self assertequalx1 x2 self assertequaly1 y2 def testgetrandbitsself verify ranges for k in range1 1000 self asserttrue0 self gen getrandbitsk 2k self assertequalself gen getrandbits0 0 verify all bits active getbits self gen getrandbits for span in 1 2 3 4 31 32 32 52 53 54 119 127 128 129 allbits 2span1 cum 0 cplcum 0 for i in range100 v getbitsspan cum v cplcum allbits v self assertequalcum allbits self assertequalcplcum allbits verify argument checking self assertraisestypeerror self gen getrandbits self assertraisestypeerror self gen getrandbits 1 2 self assertraisesvalueerror self gen getrandbits 1 self assertraisestypeerror self gen getrandbits 10 1 def testpicklingself for proto in rangepickle highestprotocol 1 state pickle dumpsself gen proto origseq self gen random for i in range10 newgen pickle loadsstate restoredseq newgen random for i in range10 self assertequalorigseq restoredseq def testbug1727780self verify that version2pickles can be loaded fine whether they are created on 32bit or 64bit platforms and that version3pickles load fine files randv232 pck 780 randv264 pck 866 randv3 pck 343 for file value in files with opensupport findfilefile rb as f r pickle loadf self assertequalintr random1000 value def testbug9025self had problem with an uneven distribution in intnrandom verify the fix by checking that distributions fall within expectations n 100000 randrange self gen randrange k sumrandrange6755399441055744 3 2 for i in rangen self asserttrue0 30 kn 37 kn def testrandbytesself verify ranges for n in range1 10 data self gen randbytesn self assertequaltypedata bytes self assertequallendata n self assertequalself gen randbytes0 b verify argument checking self assertraisestypeerror self gen randbytes self assertraisestypeerror self gen randbytes 1 2 self assertraisesvalueerror self gen randbytes 1 self assertraisestypeerror self gen randbytes 1 0 def testmusigmadefaultargsself self assertisinstanceself gen normalvariate float self assertisinstanceself gen gauss float try random systemrandom random except notimplementederror systemrandomavailable false else systemrandomavailable true unittest skipunlesssystemrandomavailable random systemrandom not available class systemrandomtestbasicopstestbasicops unittest testcase gen random systemrandom def testautoseedself doesn t need to do anything except not fail self gen seed def testsaverestoreself self assertraisesnotimplementederror self gen getstate self assertraisesnotimplementederror self gen setstate none def testseedargsself doesn t need to do anything except not fail self gen seed100 def testgaussself self gen gaussnext none self gen seed100 self assertequalself gen gaussnext none def testpicklingself for proto in rangepickle highestprotocol 1 self assertraisesnotimplementederror pickle dumps self gen proto def test53bitsperfloatself this should pass whenever a c double has 53 bit precision span 2 53 cum 0 for i in range100 cum intself gen random span self assertequalcum span1 def testbigrandself the randrange routine should buildup the required number of bits in stages so that all bit positions are active span 2 500 cum 0 for i in range100 r self gen randrangespan self asserttrue0 r span cum r self assertequalcum span1 def testbigrandrangesself for i in 40 80 160 200 211 250 375 512 550 start self gen randrange2 i2 stop self gen randrange2 i if stop start continue self asserttruestart self gen randrangestart stop stop def testrangelimitsself for start stop in 2 0 2602 260 260 2602 self assertequalsetrangestart stop setself gen randrangestart stop for i in range100 def testrandrangenonunitstepself rint self gen randrange0 10 2 self assertinrint 0 2 4 6 8 rint self gen randrange0 2 2 self assertequalrint 0 def testrandrangeerrorsself raisesvalueerror partialself assertraises valueerror self gen randrange raisestypeerror partialself assertraises typeerror self gen randrange empty range raisesvalueerror3 3 raisesvalueerror721 raisesvalueerror0 100 12 zero step raisesvalueerror0 42 0 raisestypeerror0 42 0 0 raisestypeerror0 0 0 0 noninteger stop raisestypeerror3 14159 raisestypeerror3 0 raisestypeerrorfraction3 1 raisestypeerror 3 raisestypeerror0 2 71827 raisestypeerror0 2 0 raisestypeerror0 fraction2 1 raisestypeerror0 2 raisestypeerror0 2 71827 2 noninteger start raisestypeerror2 71827 5 raisestypeerror2 0 5 raisestypeerrorfraction2 1 5 raisestypeerror 2 5 raisestypeerror2 71827 5 2 noninteger step raisestypeerror0 42 3 14159 raisestypeerror0 42 3 0 raisestypeerror0 42 fraction3 1 raisestypeerror0 42 3 raisestypeerror0 42 1 0 raisestypeerror0 0 1 0 def testrandrangestepself bpo42772 when stop is none the step argument was being ignored randrange self gen randrange with self assertraisestypeerror randrange1000 step100 with self assertraisestypeerror randrange1000 none step100 def testrandbelowlogicself loglog intint check bitcount transition points 2i and 2i11 show that k int1 001 logn 2 is equal to or one greater than the number of bits in n for i in range1 1000 n 1 i check an exact power of two numbits i1 k int1 00001 logn 2 self assertequalk numbits self assertequaln 2k1 n n 1 check 1 below the next power of two k int1 00001 logn 2 self assertink numbits numbits1 self asserttrue2k n 2k2 n n 15 check a little farther below the next power of two k int1 00001 logn 2 self assertequalk numbits note the stronger assertion self asserttrue2k n 2k1 note the stronger assertion class testrawmersennetwisterunittest testcase test support cpythononly def testbug41052self random random should not be allowed to serialization import random for proto in rangepickle highestprotocol 1 r random random self assertraisestypeerror pickle dumps r proto test support cpythononly def testbug42008self random random should call seed with first element of arg tuple import random r1 random random r1 seed8675309 r2 random random8675309 self assertequalr1 random r2 random class mersennetwistertestbasicopstestbasicops unittest testcase gen random random def testguaranteedstableself these sequences are guaranteed to stay the same across versions of python self gen seed3456147 version1 self assertequalself gen random hex for i in range4 0x1 ac362300d90d2p1 0x1 9d16f74365005p1 0x1 1ebb4352e4c4dp1 0x1 1a7422abf9c11p1 self gen seedthe quick brown fox version2 self assertequalself gen random hex for i in range4 0x1 1239ddfb11b7cp3 0x1 b3cbb5c51b120p4 0x1 8c4f55116b60fp1 0x1 63eb525174a27p1 def testbug27706self verify that version 1 seeds are unaffected by hash randomization self gen seed nofar version1 hash nofar 5990528763808513177 self assertequalself gen random hex for i in range4 0x1 8645314505ad7p1 0x1 afb1f82e40a40p5 0x1 2a59d2285e971p1 0x1 56977142a7880p6 self gen seed rachel version1 hash rachel 9091735575445484789 self assertequalself gen random hex for i in range4 0x1 0b294cc856fcdp1 0x1 2ad22d79e77b8p3 0x1 3052b9c072678p2 0x1 578f332106574p3 self gen seed version1 hash 0 self assertequalself gen random hex for i in range4 0x1 b0580f98a7dbep1 0x1 84129978f9c1ap1 0x1 aeaa51052e978p2 0x1 092178fb945a6p2 def testbug31478self there shouldn t be an assertion failure in random random seed in case the argument has a bad abs method class badintint def absself return none try self gen seedbadint except typeerror pass def testbug31482self verify that version 1 seeds are unaffected by hash randomization when the seeds are expressed as bytes rather than strings the hashb values listed are the python2 7 hash values which were used for seeding self gen seedb nofar version1 hash nofar 5990528763808513177 self assertequalself gen random hex for i in range4 0x1 8645314505ad7p1 0x1 afb1f82e40a40p5 0x1 2a59d2285e971p1 0x1 56977142a7880p6 self gen seedb rachel version1 hash rachel 9091735575445484789 self assertequalself gen random hex for i in range4 0x1 0b294cc856fcdp1 0x1 2ad22d79e77b8p3 0x1 3052b9c072678p2 0x1 578f332106574p3 self gen seedb version1 hash 0 self assertequalself gen random hex for i in range4 0x1 b0580f98a7dbep1 0x1 84129978f9c1ap1 0x1 aeaa51052e978p2 0x1 092178fb945a6p2 b b x00x20x40x60x80xa0xc0xe0xf0 self gen seedb version1 hashb 5015594239749365497 self assertequalself gen random hex for i in range4 0x1 52c2fde444d23p1 0x1 875174f0daea4p2 0x1 9e9b2c50e5cd2p1 0x1 fa57768bd321cp2 def testsetstatefirstargself self assertraisesvalueerror self gen setstate 1 none none def testsetstatemiddleargself startstate self gen getstate wrong type sb tuple self assertraisestypeerror self gen setstate 2 none none wrong length sb 625 self assertraisesvalueerror self gen setstate 2 1 2 3 none wrong type sb tuple of 625 ints self assertraisestypeerror self gen setstate 2 a 625 none last element sb an int also self assertraisestypeerror self gen setstate 2 0 624 a none last element sb between 0 and 624 with self assertraisesvalueerror overflowerror self gen setstate2 1 624625 none with self assertraisesvalueerror overflowerror self gen setstate2 1 6241 none failed calls to setstate should not have changed the state bits100 self gen getrandbits100 self gen setstatestartstate self assertequalself gen getrandbits100 bits100 little trick to make tuplex 232 for x in internalstate raise valueerror i cannot think of a simple way to achieve this so i am opting for using a generator as the middle argument of setstate which attempts to cast a nan to integer statevalues self gen getstate1 statevalues liststatevalues statevalues1 float nan state intx for x in statevalues self assertraisestypeerror self gen setstate 2 state none def testreferenceimplementationself compare the python implementation with results from the original code create 2000 53bit precision random floats compare only the last ten entries to show that the independent implementations are tracking here is the main function needed to create the list of expected random numbers void mainvoid int i unsigned long init461731 24903 614 42143 length4 initbyarrayinit length for i0 i2000 i printf 15f genrandres53 if i54 printfn expected 0 45839803073713259 0 86057815201978782 0 92848331726782152 0 35932681119782461 0 081823493762449573 0 14332226470169329 0 084297823823520024 0 53814864671831453 0 089215024911993401 0 78486196105372907 self gen seed61731 2490332 61464 4214396 actual self randomlist200010 for a e in zipactual expected self assertalmostequala e places14 def teststrongreferenceimplementationself like testreferenceimplementation but checks for exact bitlevel equality this should pass on any box where c double contains at least 53 bits of precision the underlying algorithm suffers no rounding errors all results are exact from math import ldexp expected 0x0eab3258d2231f 0x1b89db315277a5 0x1db622a5518016 0x0b7f9af0d575bf 0x029e4c4db82240 0x04961892f5d673 0x02b291598e4589 0x11388382c15694 0x02dad977c9e1fe 0x191d96d4d334c6 self gen seed61731 2490332 61464 4214396 actual self randomlist200010 for a e in zipactual expected self assertequalintldexpa 53 e def testlongseedself this is most interesting to run in debug mode just to make sure nothing blows up under the covers a dynamically resized array is allocated consuming space proportional to the number of bits in the seed unfortunately that s a quadratictime algorithm so don t make this horribly big seed 1 10000 8 1 about 10k bytes self gen seedseed def test53bitsperfloatself this should pass whenever a c double has 53 bit precision span 2 53 cum 0 for i in range100 cum intself gen random span self assertequalcum span1 def testbigrandself the randrange routine should buildup the required number of bits in stages so that all bit positions are active span 2 500 cum 0 for i in range100 r self gen randrangespan self asserttrue0 r span cum r self assertequalcum span1 def testbigrandrangesself for i in 40 80 160 200 211 250 375 512 550 start self gen randrange2 i2 stop self gen randrange2 i if stop start continue self asserttruestart self gen randrangestart stop stop def testrangelimitsself for start stop in 2 0 2602 260 260 2602 self assertequalsetrangestart stop setself gen randrangestart stop for i in range100 def testgetrandbitsself super testgetrandbits verify crossplatform repeatability self gen seed1234567 self assertequalself gen getrandbits100 97904845777343510404718956115 def testrandrangeusesgetrandbitsself verify use of getrandbits by randrange use same seed as in the crossplatform repeatability test in testgetrandbits above self gen seed1234567 if randrange uses getrandbits it should pick getrandbits100 when called with a 100bits stop argument self assertequalself gen randrange299 97904845777343510404718956115 def testrandbelowlogicself loglog intint check bitcount transition points 2i and 2i11 show that k int1 001 logn 2 is equal to or one greater than the number of bits in n for i in range1 1000 n 1 i check an exact power of two numbits i1 k int1 00001 logn 2 self assertequalk numbits self assertequaln 2k1 n n 1 check 1 below the next power of two k int1 00001 logn 2 self assertink numbits numbits1 self asserttrue2k n 2k2 n n 15 check a little farther below the next power of two k int1 00001 logn 2 self assertequalk numbits note the stronger assertion self asserttrue2k n 2k1 note the stronger assertion def testrandbelowwithoutgetrandbitsself random randbelow can only use random when the builtin one has been overridden but no new getrandbits method was supplied maxsize 1random bpf with warnings catchwarnings warnings simplefilterignore userwarning population range too large n maxsize self gen randbelowwithoutgetrandbits maxsize1 maxsizemaxsize self gen randbelowwithoutgetrandbits5640 maxsizemaxsize this might be going too far to test a single line but because of our noble aim of achieving 100 test coverage we need to write a case in which the following line in random randbelow gets executed rem maxsize n limit maxsize rem maxsize r random while r limit r random this line therefore to guarantee that the while loop is executed at least once we need to mock random so that it returns a number greater than limit the first time it gets called n 42 epsilon 0 01 limit maxsize maxsize n maxsize with unittest mock patch objectrandom random random as randommock randommock sideeffect limit epsilon limit epsilon self gen randbelowwithoutgetrandbitsn maxsizemaxsize self assertequalrandommock callcount 2 def testrandrangebug1590891self start 1000000000000 stop 100000000000000000000 step 200 x self gen randrangestart stop step self asserttruestop x start self assertequalxstopstep 0 def testchoicesalgorithmsself the various ways of specifying weights should produce the same results choices self gen choices n 104729 self gen seed8675309 a self gen choicesrangen k10000 self gen seed8675309 b self gen choicesrangen 1n k10000 self assertequala b self gen seed8675309 c self gen choicesrangen cumweightsrange1 n1 k10000 self assertequala c american roulette population red black green weights 18 18 2 cumweights 18 36 38 expandedpopulation red 18 black 18 green 2 self gen seed9035768 a self gen choicesexpandedpopulation k10000 self gen seed9035768 b self gen choicespopulation weights k10000 self assertequala b self gen seed9035768 c self gen choicespopulation cumweightscumweights k10000 self assertequala c def testrandbytesself super testrandbytes mersenne twister randbytes is deterministic and does not depend on the endian and bitness seed 8675309 expected b 3xa8xf9fxf4xa4xd06x19x8fx9fx82x02oexf0 self gen seedseed self assertequalself gen randbytes16 expected randbytes0 must not consume any entropy self gen seedseed self assertequalself gen randbytes0 b self assertequalself gen randbytes16 expected four randbytes4 calls give the same output than randbytes16 self gen seedseed self assertequalb joinself gen randbytes4 for in range4 expected each randbytes1 randbytes2 or randbytes3 call consumes 4 bytes of entropy self gen seedseed expected1 expected3 4 self assertequalb joinself gen randbytes1 for in range4 expected1 self gen seedseed expected2 b joinexpectedi 2 i 4 for i in range0 lenexpected 4 self assertequalb joinself gen randbytes2 for in range4 expected2 self gen seedseed expected3 b joinexpectedi 1 i 4 for i in range0 lenexpected 4 self assertequalb joinself gen randbytes3 for in range4 expected3 def testrandbytesgetrandbitsself there is a simple relation between randbytes and getrandbits seed 2849427419 gen2 random random self gen seedseed gen2 seedseed for n in range9 self assertequalself gen randbytesn gen2 getrandbitsn 8 tobytesn little def testsamplecountsequivalenceself test the documented strong equivalence to a sample with repeated elements we run this test on random random which makes deterministic selections for a given seed value sample self gen sample seed self gen seed colors red green blue orange black amber counts 500 200 20 10 5 1 k 700 seed8675309 s1 samplecolors countscounts kk seed8675309 expanded color for color count in zipcolors counts for i in rangecount self assertequallenexpanded sumcounts s2 sampleexpanded kk self assertequals1 s2 pop abcdefghi counts 10 9 8 7 6 5 4 3 2 seed8675309 s1 joinsamplepop countscounts k30 expanded joinletter for letter count in zippop counts for i in rangecount seed8675309 s2 joinsampleexpanded k30 self assertequals1 s2 def gammaz sqrt2pi2 0pi0 5 reflection to right half of complex plane if z 0 5 return pi sinpiz gamma1 0z lanczos approximation with g7 az z 7 0 0 5 return az z0 5 expaz sqrt2pi fsum 0 9999999999995183 676 5203681218835 z 1259 139216722289 z1 0 771 3234287757674 z2 0 176 6150291498386 z3 0 12 50734324009056 z4 0 0 1385710331296526 z5 0 0 9934937113930748e05 z6 0 0 1659470187408462e06 z7 0 class testdistributionsunittest testcase def testzeroinputsself verify that distributions can handle a series of zero inputs g random random x g random for i in range50 0 05 g random x pop g uniform1 10 g random x pop g paretovariate1 0 g random x pop g expovariate1 0 g random x pop g expovariate g random x pop g weibullvariate1 0 1 0 g random x pop g vonmisesvariate1 0 1 0 g random x pop g normalvariate0 0 1 0 g random x pop g gauss0 0 1 0 g random x pop g lognormvariate0 0 1 0 g random x pop g vonmisesvariate0 0 1 0 g random x pop g gammavariate0 01 1 0 g random x pop g gammavariate1 0 1 0 g random x pop g gammavariate200 0 1 0 g random x pop g betavariate3 0 3 0 g random x pop g triangular0 0 1 0 1 03 0 def testavgstdself use integration to test distribution average and standard deviation only works for distributions which do not consume variates in pairs g random random n 5000 x ifloatn for i in range1 n for variate args mu sigmasqrd in g uniform 1 0 10 0 10 01 02 10 01 0212 g triangular 0 0 1 0 1 03 0 4 09 0 7 09 018 0 g expovariate 1 5 11 5 11 52 g vonmisesvariate 1 23 0 pi pi23 g paretovariate 5 0 5 05 01 5 05 0125 02 g weibullvariate 1 0 3 0 gamma113 0 gamma123 0gamma113 02 g random x pop y for i in rangelenx try y appendvariateargs except indexerror pass s1 s2 0 for e in y s1 e s2 e mu 2 n leny self assertalmostequals1n mu places2 msg sr variate name args self assertalmostequals2n1 sigmasqrd places2 msg sr variate name args def testconstantself g random random n 100 for variate args expected in g uniform 10 0 10 0 10 0 g triangular 10 0 10 0 10 0 g triangular 10 0 10 0 10 0 10 0 g expovariate float inf 0 0 g vonmisesvariate 3 0 float inf 3 0 g gauss 10 0 0 0 10 0 g lognormvariate 0 0 0 0 1 0 g lognormvariate float inf 0 0 0 0 g normalvariate 10 0 0 0 10 0 g binomialvariate 0 0 5 0 g binomialvariate 10 0 0 0 g binomialvariate 10 1 0 10 g paretovariate float inf 1 0 g weibullvariate 10 0 float inf 10 0 g weibullvariate 0 0 10 0 0 0 for i in rangen self assertequalvariateargs expected def testbinomialvariateself b random binomialvariate cover all the code paths with self assertraisesvalueerror bn1 negative n with self assertraisesvalueerror bn1 p0 5 negative p with self assertraisesvalueerror bn1 p1 5 p 1 0 self assertequalb0 0 5 0 n 0 self assertequalb10 0 0 0 p 0 0 self assertequalb10 1 0 10 p 1 0 self asserttrueb1 0 3 in 0 1 n 1 fast path self asserttrueb1 0 9 in 0 1 n 1 fast path self asserttrueb1 0 0 in 0 n 1 fast path self asserttrueb1 1 0 in 1 n 1 fast path bg method very small p self assertequalb5 1e18 0 bg method p 0 5 and np1 25 self asserttrueb5 0 25 in setrange6 bg method p 0 5 and n1p1 25 self asserttrueb5 0 75 in setrange6 btrs method p 0 5 and np25 self asserttrueb100 0 25 in setrange101 btrs method p 0 5 and n1p25 self asserttrueb100 0 75 in setrange101 statistical tests chosen such that they are exceedingly unlikely to ever fail for correct code bg code path expected dist 31641 42188 21094 4688 391 c counterb4 0 25 for i in range100000 self asserttrue29641 c0 33641 c self asserttrue40188 c1 44188 self asserttrue19094 c2 23094 self asserttrue2688 c3 6688 self assertequalsetc 0 1 2 3 4 btrs code path sum of c20 c21 c22 c23 c24 expected to be 36 214 c counterb100 0 25 for i in range100000 self asserttrue34214 c20c21c22c23c24 38214 self asserttruesetc setrange101 self assertequalc total 100000 demonstrate the btrs works for huge values of n self asserttrue19000000 b100000000 0 2 21000000 self asserttrue89000000 b100000000 0 9 91000000 def testvonmisesrangeself issue 17149 von mises variates were not consistently in the range 0 2pi g random random n 100 for mu in 0 0 0 1 3 1 6 2 for kappa in 0 0 2 3 500 0 for in rangen sample g vonmisesvariatemu kappa self asserttrue 0 sample random twopi msgvonmisesvariate produced a result out of range 0 2pi formatmu kappa sample def testvonmiseslargekappaself issue 17141 vonmisesvariate was hang for large kappas random vonmisesvariate0 1e15 random vonmisesvariate0 1e100 def testgammavariateerrorsself both alpha and beta must be 0 0 self assertraisesvalueerror random gammavariate 1 3 self assertraisesvalueerror random gammavariate 0 2 self assertraisesvalueerror random gammavariate 2 0 self assertraisesvalueerror random gammavariate 1 3 there are three different possibilities in the current implementation of random gammavariate depending on the value of alpha what we are going to do here is to fix the values returned by random to generate test cases that provide 100 line coverage of the method unittest mock patch random random random def testgammavariatealphagreateroneself randommock 1 alpha 1 0 we want the first random number to be outside the 1e7 9999999 range so that the continue statement executes once the values of u1 and u2 will be 0 5 and 0 3 respectively randommock sideeffect 1e8 0 5 0 3 returnedvalue random gammavariate1 1 2 3 self assertalmostequalreturnedvalue 2 53 unittest mock patch random random random def testgammavariatealphaequaloneself randommock 2 a alpha 1 the execution body of the while loop executes once then random random returns 0 45 which causes while to stop looping and the algorithm to terminate randommock sideeffect 0 45 returnedvalue random gammavariate1 0 3 14 self assertalmostequalreturnedvalue 1 877208182372648 unittest mock patch random random random def testgammavariatealphaequaloneequalsexpovariateself randommock 2 b alpha 1 it must be equivalent of calling expovariate1 0 beta beta 3 14 randommock sideeffect 1e8 1e8 gammavariatereturnedvalue random gammavariate1 0 beta expovariatereturnedvalue random expovariate1 0 beta self assertalmostequalgammavariatereturnedvalue expovariatereturnedvalue unittest mock patch random random random def testgammavariatealphabetweenzeroandoneself randommock 3 0 alpha 1 this is the most complex region of code to cover as there are multiple ifelse statements let s take a look at the source code and determine the values that we need accordingly while 1 u random b e alphae p bu if p 1 0 a x p 1 0alpha else b x logbpalpha u1 random if p 1 0 c if u1 x alpha 1 0 d break elif u1 expx e break return x beta first we want a to be true for that we need that brandom 1 0 r1 random 1 0 b we now get to the second ifelse branch and here since p 1 0 c is false and we take the elif branch e for it to be true so that the break is executed we need that r2 random expx r2 expp 1 0alpha r2 expbr1 1 0alpha e random e exp random exp log random log alpha 0 35 beta 1 45 b e alphae epsilon 0 01 r1 0 8859296441566 1 0 b r2 0 3678794411714 expbr1 1 0alpha these four random values result in the following trace a true e false next iteration of while a true e true while loop breaks randommock sideeffect r1 r2 epsilon r1 r2 returnedvalue random gammavariatealpha beta self assertalmostequalreturnedvalue 1 4499999999997544 let s now make a be false if this is the case when we get to the second ifelse p is greater than 1 so c evaluates to true we now encounter a second if statement d which in order to execute must satisfy the following condition r2 x alpha 1 0 r2 logbpalpha alpha 1 0 r2 logbbr1alpha alpha 1 0 r1 0 8959296441566 1 0 b epsilon so that a is false r2 0 9445400408898141 and these four values result in the following trace b and c true d false next iteration of while b and c true d true while loop breaks randommock sideeffect r1 r2 epsilon r1 r2 returnedvalue random gammavariatealpha beta self assertalmostequalreturnedvalue 1 5830349561760781 unittest mock patch random random gammavariate def testbetavariatereturnzeroself gammavariatemock betavariate returns zero when the gamma distribution that it uses internally returns this same value gammavariatemock returnvalue 0 0 self assertequal0 0 random betavariate2 71828 3 14159 class testrandomsubclassingunittest testcase def testrandomsubclasswithkwargsself sf bug 1486663 this used to erroneously raise a typeerror class subclassrandom random def initself newargnone random random initself subclassnewarg1 def testsubclassesoverridingmethodsself subclasses with an overridden random but only the original getrandbits method should not rely on getrandbits in for randrange but should use a getrandbitsindependent implementation instead subclass providing its own random and getrandbits methods like random systemrandom does keep relying on getrandbits for randrange class subclass1random random def randomself called add subclass1 random return random random randomself def getrandbitsself n called add subclass1 getrandbits return random random getrandbitsself n called set subclass1 randrange42 self assertequalcalled subclass1 getrandbits subclass providing only random can only use random for randrange class subclass2random random def randomself called add subclass2 random return random random randomself called set subclass2 randrange42 self assertequalcalled subclass2 random subclass defining getrandbits to complement its inherited random can now rely on getrandbits for randrange again class subclass3subclass2 def getrandbitsself n called add subclass3 getrandbits return random random getrandbitsself n called set subclass3 randrange42 self assertequalcalled subclass3 getrandbits subclass providing only random and inherited getrandbits random takes precedence class subclass4subclass3 def randomself called add subclass4 random return random random randomself called set subclass4 randrange42 self assertequalcalled subclass4 random following subclasses don t define random or getrandbits directly but inherit them from classes which are not subclasses of random class mixin1 def randomself called add mixin1 random return random random randomself class mixin2 def getrandbitsself n called add mixin2 getrandbits return random random getrandbitsself n class subclass5mixin1 random random pass called set subclass5 randrange42 self assertequalcalled mixin1 random class subclass6mixin2 random random pass called set subclass6 randrange42 self assertequalcalled mixin2 getrandbits class subclass7mixin1 mixin2 random random pass called set subclass7 randrange42 self assertequalcalled mixin1 random class subclass8mixin2 mixin1 random random pass called set subclass8 randrange42 self assertequalcalled mixin2 getrandbits class testmoduleunittest testcase def testmagicconstantsself self assertalmostequalrandom nvmagicconst 1 71552776992141 self assertalmostequalrandom twopi 6 28318530718 self assertalmostequalrandom log4 1 38629436111989 self assertalmostequalrandom sgmagicconst 2 50407739677627 def testallself tests validity but not completeness of the all list self asserttruesetrandom all setdirrandom test support requiresfork def testafterforkself test the global random instance gets reseeded in child r w os pipe pid os fork if pid 0 child process try val random getrandbits128 with openw w as f f writestrval finally os exit0 else parent process os closew val random getrandbits128 with openr r as f childval evalf read self assertnotequalval childval support waitprocesspid exitcode0 if name main unittest main superclass with tests common to all generators subclasses must arrange for self gen to retrieve the random instance to be tested helper function to make a list of random numbers different seeds at different times should regenerate the same sequence seed value with a negative hash os urandom random seed uses time time when an operating system specific randomness source is not found to test this on machines where it exists run the above test test_seedargs again after mocking os urandom so that it raises the exception expected when the randomness source is not available the above tests all would pass if the shuffle was a no op the following non deterministic test covers that it asserts that the shuffled sequence of 1000 distinct elements must be different from the original one although there is mathematically a non zero probability that this could actually happen in a genuinely random shuffle it is completely negligible given that the number of possible permutations of 1000 objects is 1000 factorial of 1000 which is considerably larger than the number of atoms in the universe accommodation for numpy arrays which have disabled __bool__ see https github com python cpython issues 100805 for the entire allowable range of 0 k n validate that the sample is of the correct length and contains only unique items test edge case n k 0 exception raised if size of sample exceeds that of population for the entire allowable range of 0 k n validate that sample generates all possible permutations large num prevents false negatives without slowing normal case sf bug 801342 population can be any iterable defining __len__ general case case that exhausts the population case with population size of 1 case with all counts equal test error handling counts not iterable counts are negative counts are zero population too small too few counts too many counts basic functionality test argument handling missing arguments k 0 negative k behaves like 0 1 k is a float population is a string sequence population is a range population is not a sequence weights is none len weights len population non iterable weights non numeric weights integer weights float weights fractional weights booleans include exclude len weights len population non iterable cum_weights non numeric cum_weights both weights and cum_weights integer cum_weights float cum_weights fractional cum_weights test weight focused on a single element of the population test consistency with random choice for empty population subnormal weights would occasionally trigger an indexerror in choices when the value returned by random was large enough to make random total round up to the total see https bugs python org msg275594 for more detail see issue 38881 ensure that the seed method initializes all the hidden state in particular through 2 2 1 it failed to reset a piece of state used by and only by the gauss method verify ranges verify all bits active verify argument checking verify that version 2 pickles can be loaded fine whether they are created on 32 bit or 64 bit platforms and that version 3 pickles load fine had problem with an uneven distribution in int n random verify the fix by checking that distributions fall within expectations verify ranges verify argument checking doesn t need to do anything except not fail doesn t need to do anything except not fail this should pass whenever a c double has 53 bit precision the randrange routine should build up the required number of bits in stages so that all bit positions are active empty range zero step non integer stop non integer start non integer step bpo 42772 when stop is none the step argument was being ignored check bitcount transition points 2 i and 2 i 1 1 show that k int 1 001 _log n 2 is equal to or one greater than the number of bits in n check an exact power of two check 1 below the next power of two check a little farther below the next power of two note the stronger assertion note the stronger assertion _random random should not be allowed to serialization _random random should call seed with first element of arg tuple these sequences are guaranteed to stay the same across versions of python verify that version 1 seeds are unaffected by hash randomization hash nofar 5990528763808513177 hash rachel 9091735575445484789 hash 0 there shouldn t be an assertion failure in _random random seed in case the argument has a bad __abs__ method verify that version 1 seeds are unaffected by hash randomization when the seeds are expressed as bytes rather than strings the hash b values listed are the python2 7 hash values which were used for seeding hash nofar 5990528763808513177 hash rachel 9091735575445484789 hash 0 hash b 5015594239749365497 wrong type s b tuple wrong length s b 625 wrong type s b tuple of 625 ints last element s b an int also last element s b between 0 and 624 failed calls to setstate should not have changed the state little trick to make tuple x 2 32 for x in internalstate raise valueerror i cannot think of a simple way to achieve this so i am opting for using a generator as the middle argument of setstate which attempts to cast a nan to integer compare the python implementation with results from the original code create 2000 53 bit precision random floats compare only the last ten entries to show that the independent implementations are tracking here is the main function needed to create the list of expected random numbers void main void int i unsigned long init 4 61731 24903 614 42143 length 4 init_by_array init length for i 0 i 2000 i printf 15f genrand_res53 if i 5 4 printf n like test_referenceimplementation but checks for exact bit level equality this should pass on any box where c double contains at least 53 bits of precision the underlying algorithm suffers no rounding errors all results are exact this is most interesting to run in debug mode just to make sure nothing blows up under the covers a dynamically resized array is allocated consuming space proportional to the number of bits in the seed unfortunately that s a quadratic time algorithm so don t make this horribly big about 10k bytes this should pass whenever a c double has 53 bit precision the randrange routine should build up the required number of bits in stages so that all bit positions are active verify cross platform repeatability verify use of getrandbits by randrange use same seed as in the cross platform repeatability test in test_getrandbits above if randrange uses getrandbits it should pick getrandbits 100 when called with a 100 bits stop argument check bitcount transition points 2 i and 2 i 1 1 show that k int 1 001 _log n 2 is equal to or one greater than the number of bits in n check an exact power of two check 1 below the next power of two check a little farther below the next power of two note the stronger assertion note the stronger assertion random _randbelow can only use random when the built in one has been overridden but no new getrandbits method was supplied population range too large n maxsize this might be going too far to test a single line but because of our noble aim of achieving 100 test coverage we need to write a case in which the following line in random _randbelow gets executed rem maxsize n limit maxsize rem maxsize r random while r limit r random this line therefore to guarantee that the while loop is executed at least once we need to mock random so that it returns a number greater than limit the first time it gets called the various ways of specifying weights should produce the same results american roulette mersenne twister randbytes is deterministic and does not depend on the endian and bitness randbytes 0 must not consume any entropy four randbytes 4 calls give the same output than randbytes 16 each randbytes 1 randbytes 2 or randbytes 3 call consumes 4 bytes of entropy there is a simple relation between randbytes and getrandbits test the documented strong equivalence to a sample with repeated elements we run this test on random random which makes deterministic selections for a given seed value reflection to right half of complex plane lanczos approximation with g 7 verify that distributions can handle a series of zero inputs use integration to test distribution average and standard deviation only works for distributions which do not consume variates in pairs cover all the code paths negative n negative p p 1 0 n 0 p 0 0 p 1 0 n 1 fast path n 1 fast path n 1 fast path n 1 fast path bg method very small p bg method p 0 5 and n p 1 25 bg method p 0 5 and n 1 p 1 25 btrs method p 0 5 and n p 25 btrs method p 0 5 and n 1 p 25 statistical tests chosen such that they are exceedingly unlikely to ever fail for correct code bg code path expected dist 31641 42188 21094 4688 391 btrs code path sum of c 20 c 21 c 22 c 23 c 24 expected to be 36 214 demonstrate the btrs works for huge values of n issue 17149 von mises variates were not consistently in the range 0 2 pi issue 17141 vonmisesvariate was hang for large kappas both alpha and beta must be 0 0 there are three different possibilities in the current implementation of random gammavariate depending on the value of alpha what we are going to do here is to fix the values returned by random to generate test cases that provide 100 line coverage of the method 1 alpha 1 0 we want the first random number to be outside the 1e 7 9999999 range so that the continue statement executes once the values of u1 and u2 will be 0 5 and 0 3 respectively 2 a alpha 1 the execution body of the while loop executes once then random random returns 0 45 which causes while to stop looping and the algorithm to terminate 2 b alpha 1 it must be equivalent of calling expovariate 1 0 beta 3 0 alpha 1 this is the most complex region of code to cover as there are multiple if else statements let s take a look at the source code and determine the values that we need accordingly while 1 u random b _e alpha _e p b u if p 1 0 a x p 1 0 alpha else b x _log b p alpha u1 random if p 1 0 c if u1 x alpha 1 0 d break elif u1 _exp x e break return x beta first we want a to be true for that we need that b random 1 0 r1 random 1 0 b we now get to the second if else branch and here since p 1 0 c is false and we take the elif branch e for it to be true so that the break is executed we need that r2 random _exp x r2 _exp p 1 0 alpha r2 _exp b r1 1 0 alpha 1 0 b _exp b r1 1 0 alpha these four random values result in the following trace a true e false next iteration of while a true e true while loop breaks let s now make a be false if this is the case when we get to the second if else p is greater than 1 so c evaluates to true we now encounter a second if statement d which in order to execute must satisfy the following condition r2 x alpha 1 0 r2 _log b p alpha alpha 1 0 r2 _log b b r1 alpha alpha 1 0 1 0 b epsilon so that a is false and these four values result in the following trace b and c true d false next iteration of while b and c true d true while loop breaks betavariate returns zero when the gamma distribution that it uses internally returns this same value sf bug 1486663 this used to erroneously raise a typeerror subclasses with an overridden random but only the original getrandbits method should not rely on getrandbits in for randrange but should use a getrandbits independent implementation instead subclass providing its own random and getrandbits methods like random systemrandom does keep relying on getrandbits for randrange subclass providing only random can only use random for randrange subclass defining getrandbits to complement its inherited random can now rely on getrandbits for randrange again subclass providing only random and inherited getrandbits random takes precedence following subclasses don t define random or getrandbits directly but inherit them from classes which are not subclasses of random tests validity but not completeness of the __all__ list test the global random instance gets reseeded in child child process parent process
import unittest
import unittest.mock
import random
import os
import time
import pickle
import warnings
import test.support

from functools import partial
from math import log, exp, pi, fsum, sin, factorial
from test import support
from fractions import Fraction
from collections import abc, Counter

class TestBasicOps:
    
    
    

    def randomlist(self, n):
        
        return [self.gen.random() for i in range(n)]

    def test_autoseed(self):
        self.gen.seed()
        state1 = self.gen.getstate()
        time.sleep(0.1)
        self.gen.seed()      
        state2 = self.gen.getstate()
        self.assertNotEqual(state1, state2)

    def test_saverestore(self):
        N = 1000
        self.gen.seed()
        state = self.gen.getstate()
        randseq = self.randomlist(N)
        self.gen.setstate(state)    
        self.assertEqual(randseq, self.randomlist(N))

    def test_seedargs(self):
        
        class MySeed(object):
            def __hash__(self):
                return -1729
        for arg in [None, 0, 1, -1, 10**20, -(10**20),
                    False, True, 3.14, 'a']:
            self.gen.seed(arg)

        for arg in [1+2j, tuple('abc'), MySeed()]:
            with self.assertRaises(TypeError):
                self.gen.seed(arg)

        for arg in [list(range(3)), dict(one=1)]:
            self.assertRaises(TypeError, self.gen.seed, arg)
        self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
        self.assertRaises(TypeError, type(self.gen), [])

    def test_seed_no_mutate_bug_44018(self):
        a = bytearray(b'1234')
        self.gen.seed(a)
        self.assertEqual(a, bytearray(b'1234'))

    @unittest.mock.patch('random._urandom') 
    def test_seed_when_randomness_source_not_found(self, urandom_mock):
        
        
        
        
        
        urandom_mock.side_effect = NotImplementedError
        self.test_seedargs()

    def test_shuffle(self):
        shuffle = self.gen.shuffle
        lst = []
        shuffle(lst)
        self.assertEqual(lst, [])
        lst = [37]
        shuffle(lst)
        self.assertEqual(lst, [37])
        seqs = [list(range(n)) for n in range(10)]
        shuffled_seqs = [list(range(n)) for n in range(10)]
        for shuffled_seq in shuffled_seqs:
            shuffle(shuffled_seq)
        for (seq, shuffled_seq) in zip(seqs, shuffled_seqs):
            self.assertEqual(len(seq), len(shuffled_seq))
            self.assertEqual(set(seq), set(shuffled_seq))
        
        
        
        
        
        
        
        
        
        
        lst = list(range(1000))
        shuffled_lst = list(range(1000))
        shuffle(shuffled_lst)
        self.assertTrue(lst != shuffled_lst)
        shuffle(lst)
        self.assertTrue(lst != shuffled_lst)
        self.assertRaises(TypeError, shuffle, (1, 2, 3))

    def test_choice(self):
        choice = self.gen.choice
        with self.assertRaises(IndexError):
            choice([])
        self.assertEqual(choice([50]), 50)
        self.assertIn(choice([25, 75]), [25, 75])

    def test_choice_with_numpy(self):
        
        
        choice = self.gen.choice

        class NA(list):
            "Simulate numpy.array() behavior"
            def __bool__(self):
                raise RuntimeError

        with self.assertRaises(IndexError):
            choice(NA([]))
        self.assertEqual(choice(NA([50])), 50)
        self.assertIn(choice(NA([25, 75])), [25, 75])

    def test_sample(self):
        
        
        N = 100
        population = range(N)
        for k in range(N+1):
            s = self.gen.sample(population, k)
            self.assertEqual(len(s), k)
            uniq = set(s)
            self.assertEqual(len(uniq), k)
            self.assertTrue(uniq <= set(population))
        self.assertEqual(self.gen.sample([], 0), [])  
        
        self.assertRaises(ValueError, self.gen.sample, population, N+1)
        self.assertRaises(ValueError, self.gen.sample, [], -1)

    def test_sample_distribution(self):
        
        
        n = 5
        pop = range(n)
        trials = 10000  
        for k in range(n):
            expected = factorial(n) // factorial(n-k)
            perms = {}
            for i in range(trials):
                perms[tuple(self.gen.sample(pop, k))] = None
                if len(perms) == expected:
                    break
            else:
                self.fail()

    def test_sample_inputs(self):
        
        self.gen.sample(range(20), 2)
        self.gen.sample(range(20), 2)
        self.gen.sample(str('abcdefghijklmnopqrst'), 2)
        self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)

    def test_sample_on_dicts(self):
        self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)

    def test_sample_on_sets(self):
        with self.assertRaises(TypeError):
            population = {10, 20, 30, 40, 50, 60, 70}
            self.gen.sample(population, k=5)

    def test_sample_on_seqsets(self):
        class SeqSet(abc.Sequence, abc.Set):
            def __init__(self, items):
                self._items = items

            def __len__(self):
                return len(self._items)

            def __getitem__(self, index):
                return self._items[index]

        population = SeqSet([2, 4, 1, 3])
        with warnings.catch_warnings():
            warnings.simplefilter("error", DeprecationWarning)
            self.gen.sample(population, k=2)

    def test_sample_with_counts(self):
        sample = self.gen.sample

        
        colors = ['red', 'green', 'blue', 'orange', 'black', 'brown', 'amber']
        counts = [500,      200,     20,       10,       5,       0,       1 ]
        k = 700
        summary = Counter(sample(colors, counts=counts, k=k))
        self.assertEqual(sum(summary.values()), k)
        for color, weight in zip(colors, counts):
            self.assertLessEqual(summary[color], weight)
        self.assertNotIn('brown', summary)

        
        k = sum(counts)
        summary = Counter(sample(colors, counts=counts, k=k))
        self.assertEqual(sum(summary.values()), k)
        for color, weight in zip(colors, counts):
            self.assertLessEqual(summary[color], weight)
        self.assertNotIn('brown', summary)

        
        summary = Counter(sample(['x'], counts=[10], k=8))
        self.assertEqual(summary, Counter(x=8))

        
        nc = len(colors)
        summary = Counter(sample(colors, counts=[10]*nc, k=10*nc))
        self.assertEqual(summary, Counter(10*colors))

        
        with self.assertRaises(TypeError):
            sample(['red', 'green', 'blue'], counts=10, k=10)               
        with self.assertRaises(ValueError):
            sample(['red', 'green', 'blue'], counts=[-3, -7, -8], k=2)      
        with self.assertRaises(ValueError):
            sample(['red', 'green', 'blue'], counts=[0, 0, 0], k=2)         
        with self.assertRaises(ValueError):
            sample(['red', 'green'], counts=[10, 10], k=21)                 
        with self.assertRaises(ValueError):
            sample(['red', 'green', 'blue'], counts=[1, 2], k=2)            
        with self.assertRaises(ValueError):
            sample(['red', 'green', 'blue'], counts=[1, 2, 3, 4], k=2)      

    def test_choices(self):
        choices = self.gen.choices
        data = ['red', 'green', 'blue', 'yellow']
        str_data = 'abcd'
        range_data = range(4)
        set_data = set(range(4))

        
        for sample in [
            choices(data, k=5),
            choices(data, range(4), k=5),
            choices(k=5, population=data, weights=range(4)),
            choices(k=5, population=data, cum_weights=range(4)),
        ]:
            self.assertEqual(len(sample), 5)
            self.assertEqual(type(sample), list)
            self.assertTrue(set(sample) <= set(data))

        
        with self.assertRaises(TypeError):                               
            choices(2)

        self.assertEqual(choices(data, k=0), [])                         
        self.assertEqual(choices(data, k=-1), [])                        
        with self.assertRaises(TypeError):
            choices(data, k=2.5)                                         

        self.assertTrue(set(choices(str_data, k=5)) <= set(str_data))    
        self.assertTrue(set(choices(range_data, k=5)) <= set(range_data))  
        with self.assertRaises(TypeError):
            choices(set_data, k=2)                                       

        self.assertTrue(set(choices(data, None, k=5)) <= set(data))      
        self.assertTrue(set(choices(data, weights=None, k=5)) <= set(data))
        with self.assertRaises(ValueError):
            choices(data, [1,2], k=5)                                    
        with self.assertRaises(TypeError):
            choices(data, 10, k=5)                                       
        with self.assertRaises(TypeError):
            choices(data, [None]*4, k=5)                                 
        for weights in [
                [15, 10, 25, 30],                                                 
                [15.1, 10.2, 25.2, 30.3],                                         
                [Fraction(1, 3), Fraction(2, 6), Fraction(3, 6), Fraction(4, 6)], 
                [True, False, True, False]                                        
        ]:
            self.assertTrue(set(choices(data, weights, k=5)) <= set(data))

        with self.assertRaises(ValueError):
            choices(data, cum_weights=[1,2], k=5)                        
        with self.assertRaises(TypeError):
            choices(data, cum_weights=10, k=5)                           
        with self.assertRaises(TypeError):
            choices(data, cum_weights=[None]*4, k=5)                     
        with self.assertRaises(TypeError):
            choices(data, range(4), cum_weights=range(4), k=5)           
        for weights in [
                [15, 10, 25, 30],                                                 
                [15.1, 10.2, 25.2, 30.3],                                         
                [Fraction(1, 3), Fraction(2, 6), Fraction(3, 6), Fraction(4, 6)], 
        ]:
            self.assertTrue(set(choices(data, cum_weights=weights, k=5)) <= set(data))

        
        self.assertEqual(choices('abcd', [1, 0, 0, 0]), ['a'])
        self.assertEqual(choices('abcd', [0, 1, 0, 0]), ['b'])
        self.assertEqual(choices('abcd', [0, 0, 1, 0]), ['c'])
        self.assertEqual(choices('abcd', [0, 0, 0, 1]), ['d'])

        
        with self.assertRaises(IndexError):
            choices([], k=1)
        with self.assertRaises(IndexError):
            choices([], weights=[], k=1)
        with self.assertRaises(IndexError):
            choices([], cum_weights=[], k=5)

    def test_choices_subnormal(self):
        
        
        
        
        choices = self.gen.choices
        choices(population=[1, 2], weights=[1e-323, 1e-323], k=5000)

    def test_choices_with_all_zero_weights(self):
        
        with self.assertRaises(ValueError):
            self.gen.choices('AB', [0.0, 0.0])

    def test_choices_negative_total(self):
        with self.assertRaises(ValueError):
            self.gen.choices('ABC', [3, -5, 1])

    def test_choices_infinite_total(self):
        with self.assertRaises(ValueError):
            self.gen.choices('A', [float('inf')])
        with self.assertRaises(ValueError):
            self.gen.choices('AB', [0.0, float('inf')])
        with self.assertRaises(ValueError):
            self.gen.choices('AB', [-float('inf'), 123])
        with self.assertRaises(ValueError):
            self.gen.choices('AB', [0.0, float('nan')])
        with self.assertRaises(ValueError):
            self.gen.choices('AB', [float('-inf'), float('inf')])

    def test_gauss(self):
        
        
        

        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
            self.gen.seed(seed)
            x1 = self.gen.random()
            y1 = self.gen.gauss(0, 1)

            self.gen.seed(seed)
            x2 = self.gen.random()
            y2 = self.gen.gauss(0, 1)

            self.assertEqual(x1, x2)
            self.assertEqual(y1, y2)

    def test_getrandbits(self):
        
        for k in range(1, 1000):
            self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
        self.assertEqual(self.gen.getrandbits(0), 0)

        
        getbits = self.gen.getrandbits
        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
            all_bits = 2**span-1
            cum = 0
            cpl_cum = 0
            for i in range(100):
                v = getbits(span)
                cum |= v
                cpl_cum |= all_bits ^ v
            self.assertEqual(cum, all_bits)
            self.assertEqual(cpl_cum, all_bits)

        
        self.assertRaises(TypeError, self.gen.getrandbits)
        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
        self.assertRaises(ValueError, self.gen.getrandbits, -1)
        self.assertRaises(TypeError, self.gen.getrandbits, 10.1)

    def test_pickling(self):
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            state = pickle.dumps(self.gen, proto)
            origseq = [self.gen.random() for i in range(10)]
            newgen = pickle.loads(state)
            restoredseq = [newgen.random() for i in range(10)]
            self.assertEqual(origseq, restoredseq)

    def test_bug_1727780(self):
        
        
        
        files = [("randv2_32.pck", 780),
                 ("randv2_64.pck", 866),
                 ("randv3.pck", 343)]
        for file, value in files:
            with open(support.findfile(file),"rb") as f:
                r = pickle.load(f)
            self.assertEqual(int(r.random()*1000), value)

    def test_bug_9025(self):
        
        
        n = 100000
        randrange = self.gen.randrange
        k = sum(randrange(6755399441055744) % 3 == 2 for i in range(n))
        self.assertTrue(0.30 < k/n < .37, (k/n))

    def test_randbytes(self):
        
        for n in range(1, 10):
            data = self.gen.randbytes(n)
            self.assertEqual(type(data), bytes)
            self.assertEqual(len(data), n)

        self.assertEqual(self.gen.randbytes(0), b'')

        
        self.assertRaises(TypeError, self.gen.randbytes)
        self.assertRaises(TypeError, self.gen.randbytes, 1, 2)
        self.assertRaises(ValueError, self.gen.randbytes, -1)
        self.assertRaises(TypeError, self.gen.randbytes, 1.0)

    def test_mu_sigma_default_args(self):
        self.assertIsInstance(self.gen.normalvariate(), float)
        self.assertIsInstance(self.gen.gauss(), float)


try:
    random.SystemRandom().random()
except NotImplementedError:
    SystemRandom_available = False
else:
    SystemRandom_available = True

@unittest.skipUnless(SystemRandom_available, "random.SystemRandom not available")
class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase):
    gen = random.SystemRandom()

    def test_autoseed(self):
        
        self.gen.seed()

    def test_saverestore(self):
        self.assertRaises(NotImplementedError, self.gen.getstate)
        self.assertRaises(NotImplementedError, self.gen.setstate, None)

    def test_seedargs(self):
        
        self.gen.seed(100)

    def test_gauss(self):
        self.gen.gauss_next = None
        self.gen.seed(100)
        self.assertEqual(self.gen.gauss_next, None)

    def test_pickling(self):
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto)

    def test_53_bits_per_float(self):
        
        span = 2 ** 53
        cum = 0
        for i in range(100):
            cum |= int(self.gen.random() * span)
        self.assertEqual(cum, span-1)

    def test_bigrand(self):
        
        
        span = 2 ** 500
        cum = 0
        for i in range(100):
            r = self.gen.randrange(span)
            self.assertTrue(0 <= r < span)
            cum |= r
        self.assertEqual(cum, span-1)

    def test_bigrand_ranges(self):
        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
            start = self.gen.randrange(2 ** (i-2))
            stop = self.gen.randrange(2 ** i)
            if stop <= start:
                continue
            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)

    def test_rangelimits(self):
        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
            self.assertEqual(set(range(start,stop)),
                set([self.gen.randrange(start,stop) for i in range(100)]))

    def test_randrange_nonunit_step(self):
        rint = self.gen.randrange(0, 10, 2)
        self.assertIn(rint, (0, 2, 4, 6, 8))
        rint = self.gen.randrange(0, 2, 2)
        self.assertEqual(rint, 0)

    def test_randrange_errors(self):
        raises_value_error = partial(self.assertRaises, ValueError, self.gen.randrange)
        raises_type_error = partial(self.assertRaises, TypeError, self.gen.randrange)

        
        raises_value_error(3, 3)
        raises_value_error(-721)
        raises_value_error(0, 100, -12)

        
        raises_value_error(0, 42, 0)
        raises_type_error(0, 42, 0.0)
        raises_type_error(0, 0, 0.0)

        
        raises_type_error(3.14159)
        raises_type_error(3.0)
        raises_type_error(Fraction(3, 1))
        raises_type_error('3')
        raises_type_error(0, 2.71827)
        raises_type_error(0, 2.0)
        raises_type_error(0, Fraction(2, 1))
        raises_type_error(0, '2')
        raises_type_error(0, 2.71827, 2)

        
        raises_type_error(2.71827, 5)
        raises_type_error(2.0, 5)
        raises_type_error(Fraction(2, 1), 5)
        raises_type_error('2', 5)
        raises_type_error(2.71827, 5, 2)

        
        raises_type_error(0, 42, 3.14159)
        raises_type_error(0, 42, 3.0)
        raises_type_error(0, 42, Fraction(3, 1))
        raises_type_error(0, 42, '3')
        raises_type_error(0, 42, 1.0)
        raises_type_error(0, 0, 1.0)

    def test_randrange_step(self):
        
        randrange = self.gen.randrange
        with self.assertRaises(TypeError):
            randrange(1000, step=100)
        with self.assertRaises(TypeError):
            randrange(1000, None, step=100)

    def test_randbelow_logic(self, _log=log, int=int):
        
        
        
        for i in range(1, 1000):
            n = 1 << i 
            numbits = i+1
            k = int(1.00001 + _log(n, 2))
            self.assertEqual(k, numbits)
            self.assertEqual(n, 2**(k-1))

            n += n - 1      
            k = int(1.00001 + _log(n, 2))
            self.assertIn(k, [numbits, numbits+1])
            self.assertTrue(2**k > n > 2**(k-2))

            n -= n >> 15     
            k = int(1.00001 + _log(n, 2))
            self.assertEqual(k, numbits)        
            self.assertTrue(2**k > n > 2**(k-1))   


class TestRawMersenneTwister(unittest.TestCase):
    @test.support.cpython_only
    def test_bug_41052(self):
        
        import _random
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            r = _random.Random()
            self.assertRaises(TypeError, pickle.dumps, r, proto)

    @test.support.cpython_only
    def test_bug_42008(self):
        
        import _random
        r1 = _random.Random()
        r1.seed(8675309)
        r2 = _random.Random(8675309)
        self.assertEqual(r1.random(), r2.random())


class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
    gen = random.Random()

    def test_guaranteed_stable(self):
        
        self.gen.seed(3456147, version=1)
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
             '0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
        self.gen.seed("the quick brown fox", version=2)
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.1239ddfb11b7cp-3', '0x1.b3cbb5c51b120p-4',
             '0x1.8c4f55116b60fp-1', '0x1.63eb525174a27p-1'])

    def test_bug_27706(self):
        

        self.gen.seed('nofar', version=1)   
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5',
             '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6'])

        self.gen.seed('rachel', version=1)  
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3',
             '0x1.3052b9c072678p-2', '0x1.578f332106574p-3'])

        self.gen.seed('', version=1)        
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
             '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])

    def test_bug_31478(self):
        
        
        class BadInt(int):
            def __abs__(self):
                return None
        try:
            self.gen.seed(BadInt())
        except TypeError:
            pass

    def test_bug_31482(self):
        
        
        
        

        self.gen.seed(b'nofar', version=1)   
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5',
             '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6'])

        self.gen.seed(b'rachel', version=1)  
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3',
             '0x1.3052b9c072678p-2', '0x1.578f332106574p-3'])

        self.gen.seed(b'', version=1)        
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
             '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])

        b = b'\x00\x20\x40\x60\x80\xA0\xC0\xE0\xF0'
        self.gen.seed(b, version=1)         
        self.assertEqual([self.gen.random().hex() for i in range(4)],
            ['0x1.52c2fde444d23p-1', '0x1.875174f0daea4p-2',
             '0x1.9e9b2c50e5cd2p-1', '0x1.fa57768bd321cp-2'])

    def test_setstate_first_arg(self):
        self.assertRaises(ValueError, self.gen.setstate, (1, None, None))

    def test_setstate_middle_arg(self):
        start_state = self.gen.getstate()
        
        self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
        
        self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
        
        self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
        
        self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
        
        with self.assertRaises((ValueError, OverflowError)):
            self.gen.setstate((2, (1,)*624+(625,), None))
        with self.assertRaises((ValueError, OverflowError)):
            self.gen.setstate((2, (1,)*624+(-1,), None))
        
        bits100 = self.gen.getrandbits(100)
        self.gen.setstate(start_state)
        self.assertEqual(self.gen.getrandbits(100), bits100)

        
        
        
        
        state_values = self.gen.getstate()[1]
        state_values = list(state_values)
        state_values[-1] = float('nan')
        state = (int(x) for x in state_values)
        self.assertRaises(TypeError, self.gen.setstate, (2, state, None))

    def test_referenceImplementation(self):
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        expected = [0.45839803073713259,
                    0.86057815201978782,
                    0.92848331726782152,
                    0.35932681119782461,
                    0.081823493762449573,
                    0.14332226470169329,
                    0.084297823823520024,
                    0.53814864671831453,
                    0.089215024911993401,
                    0.78486196105372907]

        self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
        actual = self.randomlist(2000)[-10:]
        for a, e in zip(actual, expected):
            self.assertAlmostEqual(a,e,places=14)

    def test_strong_reference_implementation(self):
        
        
        
        
        from math import ldexp

        expected = [0x0eab3258d2231f,
                    0x1b89db315277a5,
                    0x1db622a5518016,
                    0x0b7f9af0d575bf,
                    0x029e4c4db82240,
                    0x04961892f5d673,
                    0x02b291598e4589,
                    0x11388382c15694,
                    0x02dad977c9e1fe,
                    0x191d96d4d334c6]
        self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
        actual = self.randomlist(2000)[-10:]
        for a, e in zip(actual, expected):
            self.assertEqual(int(ldexp(a, 53)), e)

    def test_long_seed(self):
        
        
        
        
        
        seed = (1 << (10000 * 8)) - 1  
        self.gen.seed(seed)

    def test_53_bits_per_float(self):
        
        span = 2 ** 53
        cum = 0
        for i in range(100):
            cum |= int(self.gen.random() * span)
        self.assertEqual(cum, span-1)

    def test_bigrand(self):
        
        
        span = 2 ** 500
        cum = 0
        for i in range(100):
            r = self.gen.randrange(span)
            self.assertTrue(0 <= r < span)
            cum |= r
        self.assertEqual(cum, span-1)

    def test_bigrand_ranges(self):
        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
            start = self.gen.randrange(2 ** (i-2))
            stop = self.gen.randrange(2 ** i)
            if stop <= start:
                continue
            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)

    def test_rangelimits(self):
        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
            self.assertEqual(set(range(start,stop)),
                set([self.gen.randrange(start,stop) for i in range(100)]))

    def test_getrandbits(self):
        super().test_getrandbits()

        
        self.gen.seed(1234567)
        self.assertEqual(self.gen.getrandbits(100),
                         97904845777343510404718956115)

    def test_randrange_uses_getrandbits(self):
        
        
        
        self.gen.seed(1234567)
        
        
        self.assertEqual(self.gen.randrange(2**99),
                         97904845777343510404718956115)

    def test_randbelow_logic(self, _log=log, int=int):
        
        
        
        for i in range(1, 1000):
            n = 1 << i 
            numbits = i+1
            k = int(1.00001 + _log(n, 2))
            self.assertEqual(k, numbits)
            self.assertEqual(n, 2**(k-1))

            n += n - 1      
            k = int(1.00001 + _log(n, 2))
            self.assertIn(k, [numbits, numbits+1])
            self.assertTrue(2**k > n > 2**(k-2))

            n -= n >> 15     
            k = int(1.00001 + _log(n, 2))
            self.assertEqual(k, numbits)        
            self.assertTrue(2**k > n > 2**(k-1))   

    def test_randbelow_without_getrandbits(self):
        
        
        maxsize = 1<<random.BPF
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", UserWarning)
            
            self.gen._randbelow_without_getrandbits(
                maxsize+1, maxsize=maxsize
            )
        self.gen._randbelow_without_getrandbits(5640, maxsize=maxsize)

        
        
        
        
        
        
        
        
        
        
        
        
        

        n = 42
        epsilon = 0.01
        limit = (maxsize - (maxsize % n)) / maxsize
        with unittest.mock.patch.object(random.Random, 'random') as random_mock:
            random_mock.side_effect = [limit + epsilon, limit - epsilon]
            self.gen._randbelow_without_getrandbits(n, maxsize=maxsize)
            self.assertEqual(random_mock.call_count, 2)

    def test_randrange_bug_1590891(self):
        start = 1000000000000
        stop = -100000000000000000000
        step = -200
        x = self.gen.randrange(start, stop, step)
        self.assertTrue(stop < x <= start)
        self.assertEqual((x+stop)%step, 0)

    def test_choices_algorithms(self):
        
        choices = self.gen.choices
        n = 104729

        self.gen.seed(8675309)
        a = self.gen.choices(range(n), k=10000)

        self.gen.seed(8675309)
        b = self.gen.choices(range(n), [1]*n, k=10000)
        self.assertEqual(a, b)

        self.gen.seed(8675309)
        c = self.gen.choices(range(n), cum_weights=range(1, n+1), k=10000)
        self.assertEqual(a, c)

        
        population = ['Red', 'Black', 'Green']
        weights = [18, 18, 2]
        cum_weights = [18, 36, 38]
        expanded_population = ['Red'] * 18 + ['Black'] * 18 + ['Green'] * 2

        self.gen.seed(9035768)
        a = self.gen.choices(expanded_population, k=10000)

        self.gen.seed(9035768)
        b = self.gen.choices(population, weights, k=10000)
        self.assertEqual(a, b)

        self.gen.seed(9035768)
        c = self.gen.choices(population, cum_weights=cum_weights, k=10000)
        self.assertEqual(a, c)

    def test_randbytes(self):
        super().test_randbytes()

        
        
        seed = 8675309
        expected = b'3\xa8\xf9f\xf4\xa4\xd06\x19\x8f\x9f\x82\x02oe\xf0'

        self.gen.seed(seed)
        self.assertEqual(self.gen.randbytes(16), expected)

        
        self.gen.seed(seed)
        self.assertEqual(self.gen.randbytes(0), b'')
        self.assertEqual(self.gen.randbytes(16), expected)

        
        self.gen.seed(seed)
        self.assertEqual(b''.join([self.gen.randbytes(4) for _ in range(4)]),
                         expected)

        
        
        self.gen.seed(seed)
        expected1 = expected[3::4]
        self.assertEqual(b''.join(self.gen.randbytes(1) for _ in range(4)),
                         expected1)

        self.gen.seed(seed)
        expected2 = b''.join(expected[i + 2: i + 4]
                             for i in range(0, len(expected), 4))
        self.assertEqual(b''.join(self.gen.randbytes(2) for _ in range(4)),
                         expected2)

        self.gen.seed(seed)
        expected3 = b''.join(expected[i + 1: i + 4]
                             for i in range(0, len(expected), 4))
        self.assertEqual(b''.join(self.gen.randbytes(3) for _ in range(4)),
                         expected3)

    def test_randbytes_getrandbits(self):
        
        seed = 2849427419
        gen2 = random.Random()
        self.gen.seed(seed)
        gen2.seed(seed)
        for n in range(9):
            self.assertEqual(self.gen.randbytes(n),
                             gen2.getrandbits(n * 8).to_bytes(n, 'little'))

    def test_sample_counts_equivalence(self):
        
        
        
        sample = self.gen.sample
        seed = self.gen.seed

        colors =  ['red', 'green', 'blue', 'orange', 'black', 'amber']
        counts = [500,      200,     20,       10,       5,       1 ]
        k = 700
        seed(8675309)
        s1 = sample(colors, counts=counts, k=k)
        seed(8675309)
        expanded = [color for (color, count) in zip(colors, counts) for i in range(count)]
        self.assertEqual(len(expanded), sum(counts))
        s2 = sample(expanded, k=k)
        self.assertEqual(s1, s2)

        pop = 'abcdefghi'
        counts = [10, 9, 8, 7, 6, 5, 4, 3, 2]
        seed(8675309)
        s1 = ''.join(sample(pop, counts=counts, k=30))
        expanded = ''.join([letter for (letter, count) in zip(pop, counts) for i in range(count)])
        seed(8675309)
        s2 = ''.join(sample(expanded, k=30))
        self.assertEqual(s1, s2)


def gamma(z, sqrt2pi=(2.0*pi)**0.5):
    
    if z < 0.5:
        return pi / sin(pi*z) / gamma(1.0-z)
    
    az = z + (7.0 - 0.5)
    return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([
        0.9999999999995183,
        676.5203681218835 / z,
        -1259.139216722289 / (z+1.0),
        771.3234287757674 / (z+2.0),
        -176.6150291498386 / (z+3.0),
        12.50734324009056 / (z+4.0),
        -0.1385710331296526 / (z+5.0),
        0.9934937113930748e-05 / (z+6.0),
        0.1659470187408462e-06 / (z+7.0),
    ])

class TestDistributions(unittest.TestCase):
    def test_zeroinputs(self):
        
        g = random.Random()
        x = [g.random() for i in range(50)] + [0.0]*5
        g.random = x[:].pop; g.uniform(1,10)
        g.random = x[:].pop; g.paretovariate(1.0)
        g.random = x[:].pop; g.expovariate(1.0)
        g.random = x[:].pop; g.expovariate()
        g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
        g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0)
        g.random = x[:].pop; g.normalvariate(0.0, 1.0)
        g.random = x[:].pop; g.gauss(0.0, 1.0)
        g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
        g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
        g.random = x[:].pop; g.gammavariate(0.01, 1.0)
        g.random = x[:].pop; g.gammavariate(1.0, 1.0)
        g.random = x[:].pop; g.gammavariate(200.0, 1.0)
        g.random = x[:].pop; g.betavariate(3.0, 3.0)
        g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0)

    def test_avg_std(self):
        
        
        g = random.Random()
        N = 5000
        x = [i/float(N) for i in range(1,N)]
        for variate, args, mu, sigmasqrd in [
                (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
                (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
                (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
                (g.vonmisesvariate, (1.23, 0), pi, pi**2/3),
                (g.paretovariate, (5.0,), 5.0/(5.0-1),
                                  5.0/((5.0-1)**2*(5.0-2))),
                (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
                                  gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
            g.random = x[:].pop
            y = []
            for i in range(len(x)):
                try:
                    y.append(variate(*args))
                except IndexError:
                    pass
            s1 = s2 = 0
            for e in y:
                s1 += e
                s2 += (e - mu) ** 2
            N = len(y)
            self.assertAlmostEqual(s1/N, mu, places=2,
                                   msg='%s%r' % (variate.__name__, args))
            self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2,
                                   msg='%s%r' % (variate.__name__, args))

    def test_constant(self):
        g = random.Random()
        N = 100
        for variate, args, expected in [
                (g.uniform, (10.0, 10.0), 10.0),
                (g.triangular, (10.0, 10.0), 10.0),
                (g.triangular, (10.0, 10.0, 10.0), 10.0),
                (g.expovariate, (float('inf'),), 0.0),
                (g.vonmisesvariate, (3.0, float('inf')), 3.0),
                (g.gauss, (10.0, 0.0), 10.0),
                (g.lognormvariate, (0.0, 0.0), 1.0),
                (g.lognormvariate, (-float('inf'), 0.0), 0.0),
                (g.normalvariate, (10.0, 0.0), 10.0),
                (g.binomialvariate, (0, 0.5), 0),
                (g.binomialvariate, (10, 0.0), 0),
                (g.binomialvariate, (10, 1.0), 10),
                (g.paretovariate, (float('inf'),), 1.0),
                (g.weibullvariate, (10.0, float('inf')), 10.0),
                (g.weibullvariate, (0.0, 10.0), 0.0),
            ]:
            for i in range(N):
                self.assertEqual(variate(*args), expected)

    def test_binomialvariate(self):
        B = random.binomialvariate

        
        with self.assertRaises(ValueError):
            B(n=-1)                            
        with self.assertRaises(ValueError):
            B(n=1, p=-0.5)                     
        with self.assertRaises(ValueError):
            B(n=1, p=1.5)                      
        self.assertEqual(B(0, 0.5), 0)         
        self.assertEqual(B(10, 0.0), 0)        
        self.assertEqual(B(10, 1.0), 10)       
        self.assertTrue(B(1, 0.3) in {0, 1})   
        self.assertTrue(B(1, 0.9) in {0, 1})   
        self.assertTrue(B(1, 0.0) in {0})      
        self.assertTrue(B(1, 1.0) in {1})      

        
        self.assertEqual(B(5, 1e-18), 0)

        
        self.assertTrue(B(5, 0.25) in set(range(6)))

        
        self.assertTrue(B(5, 0.75) in set(range(6)))

        
        self.assertTrue(B(100, 0.25) in set(range(101)))

        
        self.assertTrue(B(100, 0.75) in set(range(101)))

        
        

        
        
        c = Counter(B(4, 0.25) for i in range(100_000))
        self.assertTrue(29_641 <= c[0] <= 33_641, c)
        self.assertTrue(40_188 <= c[1] <= 44_188)
        self.assertTrue(19_094 <= c[2] <= 23_094)
        self.assertTrue(2_688  <= c[3] <= 6_688)
        self.assertEqual(set(c), {0, 1, 2, 3, 4})

        
        
        c = Counter(B(100, 0.25) for i in range(100_000))
        self.assertTrue(34_214 <= c[20]+c[21]+c[22]+c[23]+c[24] <= 38_214)
        self.assertTrue(set(c) <= set(range(101)))
        self.assertEqual(c.total(), 100_000)

        
        self.assertTrue(19_000_000 <= B(100_000_000, 0.2) <= 21_000_000)
        self.assertTrue(89_000_000 <= B(100_000_000, 0.9) <= 91_000_000)


    def test_von_mises_range(self):
        
        
        g = random.Random()
        N = 100
        for mu in 0.0, 0.1, 3.1, 6.2:
            for kappa in 0.0, 2.3, 500.0:
                for _ in range(N):
                    sample = g.vonmisesvariate(mu, kappa)
                    self.assertTrue(
                        0 <= sample <= random.TWOPI,
                        msg=("vonmisesvariate({}, {}) produced a result {} out"
                             " of range [0, 2*pi]").format(mu, kappa, sample))

    def test_von_mises_large_kappa(self):
        
        random.vonmisesvariate(0, 1e15)
        random.vonmisesvariate(0, 1e100)

    def test_gammavariate_errors(self):
        
        self.assertRaises(ValueError, random.gammavariate, -1, 3)
        self.assertRaises(ValueError, random.gammavariate, 0, 2)
        self.assertRaises(ValueError, random.gammavariate, 2, 0)
        self.assertRaises(ValueError, random.gammavariate, 1, -3)

    
    
    
    
    @unittest.mock.patch('random.Random.random')
    def test_gammavariate_alpha_greater_one(self, random_mock):

        
        
        
        
        random_mock.side_effect = [1e-8, 0.5, 0.3]
        returned_value = random.gammavariate(1.1, 2.3)
        self.assertAlmostEqual(returned_value, 2.53)

    @unittest.mock.patch('random.Random.random')
    def test_gammavariate_alpha_equal_one(self, random_mock):

        
        
        
        
        random_mock.side_effect = [0.45]
        returned_value = random.gammavariate(1.0, 3.14)
        self.assertAlmostEqual(returned_value, 1.877208182372648)

    @unittest.mock.patch('random.Random.random')
    def test_gammavariate_alpha_equal_one_equals_expovariate(self, random_mock):

        
        
        beta = 3.14
        random_mock.side_effect = [1e-8, 1e-8]
        gammavariate_returned_value = random.gammavariate(1.0, beta)
        expovariate_returned_value = random.expovariate(1.0 / beta)
        self.assertAlmostEqual(gammavariate_returned_value, expovariate_returned_value)

    @unittest.mock.patch('random.Random.random')
    def test_gammavariate_alpha_between_zero_and_one(self, random_mock):

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

        _e = random._e
        _exp = random._exp
        _log = random._log
        alpha = 0.35
        beta = 1.45
        b = (_e + alpha)/_e
        epsilon = 0.01

        r1 = 0.8859296441566 
        r2 = 0.3678794411714 

        
        
        
        random_mock.side_effect = [r1, r2 + epsilon, r1, r2]
        returned_value = random.gammavariate(alpha, beta)
        self.assertAlmostEqual(returned_value, 1.4499999999997544)

        
        
        
        
        
        
        
        r1 = 0.8959296441566 
        r2 = 0.9445400408898141

        
        
        
        random_mock.side_effect = [r1, r2 + epsilon, r1, r2]
        returned_value = random.gammavariate(alpha, beta)
        self.assertAlmostEqual(returned_value, 1.5830349561760781)

    @unittest.mock.patch('random.Random.gammavariate')
    def test_betavariate_return_zero(self, gammavariate_mock):
        
        
        gammavariate_mock.return_value = 0.0
        self.assertEqual(0.0, random.betavariate(2.71828, 3.14159))


class TestRandomSubclassing(unittest.TestCase):
    def test_random_subclass_with_kwargs(self):
        
        class Subclass(random.Random):
            def __init__(self, newarg=None):
                random.Random.__init__(self)
        Subclass(newarg=1)

    def test_subclasses_overriding_methods(self):
        
        
        

        
        
        
        class SubClass1(random.Random):
            def random(self):
                called.add('SubClass1.random')
                return random.Random.random(self)

            def getrandbits(self, n):
                called.add('SubClass1.getrandbits')
                return random.Random.getrandbits(self, n)
        called = set()
        SubClass1().randrange(42)
        self.assertEqual(called, {'SubClass1.getrandbits'})

        
        class SubClass2(random.Random):
            def random(self):
                called.add('SubClass2.random')
                return random.Random.random(self)
        called = set()
        SubClass2().randrange(42)
        self.assertEqual(called, {'SubClass2.random'})

        
        
        class SubClass3(SubClass2):
            def getrandbits(self, n):
                called.add('SubClass3.getrandbits')
                return random.Random.getrandbits(self, n)
        called = set()
        SubClass3().randrange(42)
        self.assertEqual(called, {'SubClass3.getrandbits'})

        
        
        class SubClass4(SubClass3):
            def random(self):
                called.add('SubClass4.random')
                return random.Random.random(self)
        called = set()
        SubClass4().randrange(42)
        self.assertEqual(called, {'SubClass4.random'})

        
        
        class Mixin1:
            def random(self):
                called.add('Mixin1.random')
                return random.Random.random(self)
        class Mixin2:
            def getrandbits(self, n):
                called.add('Mixin2.getrandbits')
                return random.Random.getrandbits(self, n)

        class SubClass5(Mixin1, random.Random):
            pass
        called = set()
        SubClass5().randrange(42)
        self.assertEqual(called, {'Mixin1.random'})

        class SubClass6(Mixin2, random.Random):
            pass
        called = set()
        SubClass6().randrange(42)
        self.assertEqual(called, {'Mixin2.getrandbits'})

        class SubClass7(Mixin1, Mixin2, random.Random):
            pass
        called = set()
        SubClass7().randrange(42)
        self.assertEqual(called, {'Mixin1.random'})

        class SubClass8(Mixin2, Mixin1, random.Random):
            pass
        called = set()
        SubClass8().randrange(42)
        self.assertEqual(called, {'Mixin2.getrandbits'})


class TestModule(unittest.TestCase):
    def testMagicConstants(self):
        self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
        self.assertAlmostEqual(random.TWOPI, 6.28318530718)
        self.assertAlmostEqual(random.LOG4, 1.38629436111989)
        self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)

    def test__all__(self):
        
        self.assertTrue(set(random.__all__) <= set(dir(random)))

    @test.support.requires_fork()
    def test_after_fork(self):
        
        r, w = os.pipe()
        pid = os.fork()
        if pid == 0:
            
            try:
                val = random.getrandbits(128)
                with open(w, "w") as f:
                    f.write(str(val))
            finally:
                os._exit(0)
        else:
            
            os.close(w)
            val = random.getrandbits(128)
            with open(r, "r") as f:
                child_val = eval(f.read())
            self.assertNotEqual(val, child_val)

            support.wait_process(pid, exitcode=0)


if __name__ == "__main__":
    unittest.main()