test iterators test result of triple loop too big to inline helper classes main test suite helper to check that an iterator returns a given sequence helper to check that a for loop generates a given sequence helper to check picklability cannot assert type equality because dict iterators unpickle as list iterators self assertequaltypeitorg typeit test basic use of iter function test that iteriterx is the same as iterx test that for loops over iterators work test several independent iterators over the same list test triple list comprehension using iterators test triple list comprehension without iterators test a class with iter in a for loop test a class with iter with explicit iter test for loop on a sequence class without iter test iter on a sequence class without iter initial iterator running iterator empty iterator exhausted iterator this is a reproducer of issue 101765 where iter reduce calls could lead to a segfault or systemerror depending on the order of c argument evaluation which is undefined backup builtins here we exhaust our iterator possibly changing its itseq pointer to null the reduce call should correctly get the pointers after this call del is required here to not prematurely call eq from the hash collision with the old key the returned value of reduce should not only be valid but also empty as it was exhausted during eq i e xyz returns iter pyevalgetbuiltin is also called for reversed in a branch of listiterreducegeneral restore original builtins need to suppress keyerrors in case a failed test deletes the key without setting anything del is required here to not invoke our custom eq from the hash collision with the old key test a newstyle class with iter but no next method test twoargument iter with callable instance test twoargument iter with function test twoargument iter with function that raises stopiteration gh101892 test twoargument iter with a function that exhausts its associated iterator but forgets to either return a sentinel value or raise stopiteration exhaust an iterator without raising stopiteration listiterator def spam touching the iterator with exhaust below will call spam once again so protect against recursion if spam isrecursivecall return nomore spam isrecursivecall true exhaustspam iterator return hasmore spam isrecursivecall false spam iterator iterspam nomore with self assertraisesstopiteration nextspam iterator test exception propagation through function iterator def testexceptionfunctionself def spamstate0 i state0 state0 i1 if i 10 raise runtimeerror return i res try for x in iterspam 20 res appendx except runtimeerror self assertequalres listrange10 else self failshould have raised runtimeerror test exception propagation through sequence iterator def testexceptionsequenceself class mysequenceclasssequenceclass def getitemself i if i 10 raise runtimeerror return sequenceclass getitemself i res try for x in mysequenceclass20 res appendx except runtimeerror self assertequalres listrange10 else self failshould have raised runtimeerror test for stopiteration from getitem def teststopsequenceself class mysequenceclasssequenceclass def getitemself i if i 10 raise stopiteration return sequenceclass getitemself i self checkforloopmysequenceclass20 listrange10 picklefalse test a big range def testiterbigrangeself self checkforloopiterrange10000 listrange10000 test an empty list def testiteremptyself self checkforloopiter test a tuple def testitertupleself self checkforloopiter0 1 2 3 4 5 6 7 8 9 listrange10 test a range def testiterrangeself self checkforloopiterrange10 listrange10 test a string def testiterstringself self checkforloopiterabcde a b c d e test a directory def testiterdictself dict for i in range10 dicti none self checkforloopdict listdict keys test a file def testiterfileself f opentestfn w encodingutf8 try for i in range5 f writedn i finally f close f opentestfn r encodingutf8 try self checkforloopf 0n 1n 2n 3n 4n picklefalse self checkforloopf picklefalse finally f close try unlinktestfn except oserror pass test list s use of iterators def testbuiltinlistself self assertequallistsequenceclass5 listrange5 self assertequallistsequenceclass0 self assertequallist d one 1 two 2 three 3 self assertequallistd listd keys self assertraisestypeerror list list self assertraisestypeerror list 42 f opentestfn w encodingutf8 try for i in range5 f writedn i finally f close f opentestfn r encodingutf8 try self assertequallistf 0n 1n 2n 3n 4n f seek0 0 self assertequallistf 0n 1n 2n 3n 4n finally f close try unlinktestfn except oserror pass test tuples s use of iterators def testbuiltintupleself self assertequaltuplesequenceclass5 0 1 2 3 4 self assertequaltuplesequenceclass0 self assertequaltuple self assertequaltuple self assertequaltupleabc a b c d one 1 two 2 three 3 self assertequaltupled tupled keys self assertraisestypeerror tuple list self assertraisestypeerror tuple 42 f opentestfn w encodingutf8 try for i in range5 f writedn i finally f close f opentestfn r encodingutf8 try self assertequaltuplef 0n 1n 2n 3n 4n f seek0 0 self assertequaltuplef 0n 1n 2n 3n 4n finally f close try unlinktestfn except oserror pass test filter s use of iterators def testbuiltinfilterself self assertequallistfilternone sequenceclass5 listrange1 5 self assertequallistfilternone sequenceclass0 self assertequallistfilternone self assertequallistfilternone abc a b c d one 1 two 2 three 3 self assertequallistfilternone d listd keys self assertraisestypeerror filter none list self assertraisestypeerror filter none 42 class boolean def initself truth self truth truth def boolself return self truth btrue booleantrue bfalse booleanfalse class seq def initself args self vals args def iterself class seqiter def initself vals self vals vals self i 0 def iterself return self def nextself i self i self i i 1 if i lenself vals return self valsi else raise stopiteration return seqiterself vals seq seqbtrue bfalse 25 self assertequallistfilterlambda x not x seq bfalse25 self assertequallistfilterlambda x not x iterseq bfalse25 test max and min s use of iterators def testbuiltinmaxminself self assertequalmaxsequenceclass5 4 self assertequalminsequenceclass5 0 self assertequalmax8 1 8 self assertequalmin8 1 1 d one 1 two 2 three 3 self assertequalmaxd two self assertequalmind one self assertequalmaxd values 3 self assertequalminiterd values 1 f opentestfn w encodingutf8 try f writemedium linen f writextra large linen f writeittybitty linen finally f close f opentestfn r encodingutf8 try self assertequalminf ittybitty linen f seek0 0 self assertequalmaxf xtra large linen finally f close try unlinktestfn except oserror pass test map s use of iterators def testbuiltinmapself self assertequallistmaplambda x x1 sequenceclass5 listrange1 6 d one 1 two 2 three 3 self assertequallistmaplambda k dd k dk d listd items dkeys listd keys expected i lend and dkeysi or none i i lend and dkeysi or none for i in range3 f opentestfn w encodingutf8 try for i in range10 f writexy i n line i has len 2i1 finally f close f opentestfn r encodingutf8 try self assertequallistmaplen f listrange1 21 2 finally f close try unlinktestfn except oserror pass test zip s use of iterators def testbuiltinzipself self assertequallistzip self assertequallistzip self assertequallistzip1 2 ab 1 a 2 b self assertraisestypeerror zip none self assertraisestypeerror zip range10 42 self assertraisestypeerror zip range10 zip self assertequallistzipiteratingsequenceclass3 0 1 2 self assertequallistzipsequenceclass3 0 1 2 d one 1 two 2 three 3 self assertequallistd items listzipd d values generate all ints starting at constructor arg class intsfrom def initself start self i start def iterself return self def nextself i self i self i i1 return i f opentestfn w encodingutf8 try f writean bbbn ccn finally f close f opentestfn r encodingutf8 try self assertequallistzipintsfrom0 f intsfrom100 0 an 100 1 bbbn 99 2 ccn 98 finally f close try unlinktestfn except oserror pass self assertequallistziprange5 i for i in range5 classes that lie about their lengths class noguesslen5 def getitemself i if i 5 raise indexerror return i class guess3len5noguesslen5 def lenself return 3 class guess30len5noguesslen5 def lenself return 30 def lzipargs return listzipargs self assertequallenguess3len5 3 self assertequallenguess30len5 30 self assertequallzipnoguesslen5 lziprange5 self assertequallzipguess3len5 lziprange5 self assertequallzipguess30len5 lziprange5 expected i i for i in range5 for x in noguesslen5 guess3len5 guess30len5 for y in noguesslen5 guess3len5 guess30len5 self assertequallzipx y expected def testunicodejoinendcaseself this class inserts a unicode object into its argument s natural iteration in the 3rd position class ohphooey def initself seq self it iterseq self i 0 def iterself return self def nextself i self i self i i1 if i 2 return fooled you return nextself it f opentestfn w encodingutf8 try f writean bn cn finally f close f opentestfn r encodingutf8 nasty string joins can t know whether unicode join is needed until it s seen all of s s elements but in this case f s iterator cannot be restarted so what we re testing here is whether string join can manage to remember everything it s seen and pass that on to unicode join try got joinohphooeyf self assertequalgot an bn fooled you cn finally f close try unlinktestfn except oserror pass test iterators with x in y and x not in y def testinandnotinself for sc5 in iteratingsequenceclass5 sequenceclass5 for i in range5 self assertini sc5 for i in abc 1 5 42 42 3 4 1 1 312j sc5 self assertnotini sc5 self assertinalwayseq iteratorproxyclassiter1 self assertinalwayseq sequenceproxyclass1 self assertnotinalwayseq iteratorproxyclassiternevereq self assertnotinalwayseq sequenceproxyclassnevereq self assertinnevereq iteratorproxyclassiteralwayseq self assertinnevereq sequenceproxyclassalwayseq self assertraisestypeerror lambda 3 in 12 self assertraisestypeerror lambda 3 not in map self assertraiseszerodivisionerror lambda 3 in baditerableclass d one 1 two 2 three 3 1j 2j for k in d self assertink d self assertnotink d values for v in d values self assertinv d values self assertnotinv d for k v in d items self assertink v d items self assertnotinv k d items f opentestfn w encodingutf8 try f writean bn cn finally f close f opentestfn r encodingutf8 try for chunk in abc f seek0 0 self assertnotinchunk f f seek0 0 self assertinchunk n f finally f close try unlinktestfn except oserror pass test iterators with operator countof pysequencecount def testcountofself from operator import countof self assertequalcountof1 2 2 3 2 5 2 3 self assertequalcountof1 2 2 3 2 5 2 3 self assertequalcountof122325 2 3 self assertequalcountof122325 6 0 self assertraisestypeerror countof 42 1 self assertraisestypeerror countof countof countof d one 3 two 3 three 3 1j 2j for k in d self assertequalcountofd k 1 self assertequalcountofd values 3 3 self assertequalcountofd values 2j 1 self assertequalcountofd values 1j 0 f opentestfn w encodingutf8 try f writean bn cn bn finally f close f opentestfn r encodingutf8 try for letter count in a 1 b 2 c 1 d 0 f seek0 0 self assertequalcountoff letter n count finally f close try unlinktestfn except oserror pass test iterators with operator indexof pysequenceindex def testindexofself from operator import indexof self assertequalindexof1 2 2 3 2 5 1 0 self assertequalindexof1 2 2 3 2 5 2 1 self assertequalindexof1 2 2 3 2 5 3 3 self assertequalindexof1 2 2 3 2 5 5 5 self assertraisesvalueerror indexof 1 2 2 3 2 5 0 self assertraisesvalueerror indexof 1 2 2 3 2 5 6 self assertequalindexof122325 2 1 self assertequalindexof122325 5 5 self assertraisesvalueerror indexof 122325 6 self assertraisestypeerror indexof 42 1 self assertraisestypeerror indexof indexof indexof self assertraiseszerodivisionerror indexof baditerableclass 1 f opentestfn w encodingutf8 try f writean bn cn dn en finally f close f opentestfn r encodingutf8 try fiter iterf self assertequalindexoffiter bn 1 self assertequalindexoffiter dn 1 self assertequalindexoffiter en 0 self assertraisesvalueerror indexof fiter an finally f close try unlinktestfn except oserror pass iclass iteratingsequenceclass3 for i in range3 self assertequalindexoficlass i i self assertraisesvalueerror indexof iclass 1 test iterators with file writelines def testwritelinesself f opentestfn w encodingutf8 try self assertraisestypeerror f writelines none self assertraisestypeerror f writelines 42 f writelines1n 2n f writelines3n 4n f writelines 5n none f writelines try a big chunk too class iterator def initself start finish self start start self finish finish self i self start def nextself if self i self finish raise stopiteration result strself i n self i 1 return result def iterself return self class whatever def initself start finish self start start self finish finish def iterself return iteratorself start self finish f writelineswhatever6 62000 f close f opentestfn encodingutf8 expected stri n for i in range1 2006 self assertequallistf expected finally f close try unlinktestfn except oserror pass test iterators on rhs of unpacking assignments def testunpackiterself a b 1 2 self assertequala b 1 2 a b c iteratingsequenceclass3 self assertequala b c 0 1 2 try too many values a b iteratingsequenceclass3 except valueerror pass else self failshould have raised valueerror try not enough values a b c iteratingsequenceclass2 except valueerror pass else self failshould have raised valueerror try not iterable a b c len except typeerror pass else self failshould have raised typeerror a b c 1 42 2 42 3 42 values self assertequala b c 42 42 42 f opentestfn w encodingutf8 lines an bbn cccn try for line in lines f writeline finally f close f opentestfn r encodingutf8 try a b c f self assertequala b c lines finally f close try unlinktestfn except oserror pass a b c iteratingsequenceclass2 42 24 self assertequala b c 0 1 42 cpythononly def testrefcountingbehaviorself class cobject count 0 def newcls cls count 1 return object newcls def delself cls self class assert cls count 0 cls count 1 x c self assertequalc count 1 del x self assertequalc count 0 l c c c self assertequalc count 3 try a b iterl except valueerror pass del l self assertequalc count 0 make sure stopiteration is a sink state this tests various things that weren t sink states in python 2 2 1 plus various things that always were fine def testsinkstatelistself this used to fail a listrange5 b itera self assertequallistb listrange5 a extendrange5 10 self assertequallistb def testsinkstatetupleself a 0 1 2 3 4 b itera self assertequallistb listrange5 self assertequallistb def testsinkstatestringself a abcde b itera self assertequallistb a b c d e self assertequallistb def testsinkstatesequenceself this used to fail a sequenceclass5 b itera self assertequallistb listrange5 a n 10 self assertequallistb def testsinkstatecallableself this used to fail def spamstate0 i state0 state0 i1 if i 10 raise assertionerrorshouldn t have gotten this far return i b iterspam 5 self assertequallistb listrange5 self assertequallistb def testsinkstatedictself xxx for a more thorough test see towards the end of http mail python orgpipermailpythondev2002july026512 html a 1 1 2 2 0 0 4 4 3 3 for b in itera a keys a items a values b itera self assertequallenlistb 5 self assertequallistb def testsinkstateyieldself def gen for i in range5 yield i b gen self assertequallistb listrange5 self assertequallistb def testsinkstaterangeself a range5 b itera self assertequallistb listrange5 self assertequallistb def testsinkstateenumerateself a range5 e enumeratea b itere self assertequallistb listziprange5 range5 self assertequallistb def test3720self avoid a crash when an iterator deletes its next method class baditeratorobject def iterself return self def nextself del baditerator next return 1 try for i in baditerator pass except typeerror pass def testextendinglistwithiteratordoesnotsegfaultself the code to extend a list with an iterator has a fair amount of nontrivial logic in terms of guessing how much memory to allocate in advance stealing refs and then shrinking at the end this is a basic smoke test for that scenario def gen for i in range500 yield i lst 0 500 for i in range240 lst pop0 lst extendgen self assertequallenlst 760 cpythononly def testiteroverflowself test for the issue 22939 it iterunlimitedsequenceclass manually set itindex to pyssizetmax2 without a loop it setstatesys maxsize 2 self assertequalnextit sys maxsize 2 self assertequalnextit sys maxsize 1 with self assertraisesoverflowerror nextit check that overflow error is always raised with self assertraisesoverflowerror nextit def testiternegsetstateself it iterunlimitedsequenceclass it setstate42 self assertequalnextit 0 self assertequalnextit 1 def testfreeafteriteratingself checkfreeafteriteratingself iter sequenceclass 0 def testerroriterself for typ in defaultiterclass noiterclass self assertraisestypeerror iter typ self assertraiseszerodivisionerror iter baditerableclass if name main unittest main test iterators test result of triple loop too big to inline helper classes emergency stop main test suite helper to check that an iterator returns a given sequence helper to check that a for loop generates a given sequence helper to check picklability cannot assert type equality because dict iterators unpickle as list iterators self assertequal type itorg type it test basic use of iter function test that iter iter x is the same as iter x test that for loops over iterators work test several independent iterators over the same list test triple list comprehension using iterators test triple list comprehension without iterators test a class with __iter__ in a for loop test a class with __iter__ with explicit iter test for loop on a sequence class without __iter__ test iter on a sequence class without __iter__ initial iterator running iterator empty iterator exhausted iterator exhaust the iterator not exhausted this is a reproducer of issue 101765 where iter __reduce__ calls could lead to a segfault or systemerror depending on the order of c argument evaluation which is undefined backup builtins here we exhaust our iterator possibly changing its it_seq pointer to null the __reduce__ call should correctly get the pointers after this call del is required here to not prematurely call __eq__ from the hash collision with the old key genericalias the returned value of __reduce__ should not only be valid but also empty as it was exhausted during __eq__ i e xyz returns iter _pyeval_getbuiltin is also called for reversed in a branch of listiter_reduce_general restore original builtins need to suppress keyerrors in case a failed test deletes the key without setting anything del is required here to not invoke our custom __eq__ from the hash collision with the old key test a new_style class with __iter__ but no next method test two argument iter with callable instance test two argument iter with function test two argument iter with function that raises stopiteration gh 101892 test two argument iter with a function that exhausts its associated iterator but forgets to either return a sentinel value or raise stopiteration exhaust an iterator without raising stopiteration touching the iterator with exhaust below will call spam once again so protect against recursion test exception propagation through function iterator test exception propagation through sequence iterator test for stopiteration from __getitem__ test a big range test an empty list test a tuple test a range test a string test a directory test a file test list s use of iterators test tuples s use of iterators test filter s use of iterators test max and min s use of iterators test map s use of iterators line i has len 2 i 1 test zip s use of iterators generate all ints starting at constructor arg classes that lie about their lengths this class inserts a unicode object into its argument s natural iteration in the 3rd position nasty string join s can t know whether unicode join is needed until it s seen all of s s elements but in this case f s iterator cannot be restarted so what we re testing here is whether string join can manage to remember everything it s seen and pass that on to unicode join test iterators with x in y and x not in y test iterators with operator countof pysequence_count test iterators with operator indexof pysequence_index test iterators with file writelines try a big chunk too test iterators on rhs of unpacking assignments too many values not enough values not iterable make sure stopiteration is a sink state this tests various things that weren t sink states in python 2 2 1 plus various things that always were fine this used to fail this used to fail this used to fail xxx for a more thorough test see towards the end of http mail python org pipermail python dev 2002 july 026512 html avoid a crash when an iterator deletes its next method the code to extend a list with an iterator has a fair amount of nontrivial logic in terms of guessing how much memory to allocate in advance stealing refs and then shrinking at the end this is a basic smoke test for that scenario test for the issue 22939 manually set it_index to py_ssize_t_max 2 without a loop check that overflow error is always raised
import sys
import unittest
from test.support import cpython_only
from test.support.os_helper import TESTFN, unlink
from test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ
import pickle
import collections.abc
import functools
import contextlib
import builtins


TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
            (0, 1, 0), (0, 1, 1), (0, 1, 2),
            (0, 2, 0), (0, 2, 1), (0, 2, 2),

            (1, 0, 0), (1, 0, 1), (1, 0, 2),
            (1, 1, 0), (1, 1, 1), (1, 1, 2),
            (1, 2, 0), (1, 2, 1), (1, 2, 2),

            (2, 0, 0), (2, 0, 1), (2, 0, 2),
            (2, 1, 0), (2, 1, 1), (2, 1, 2),
            (2, 2, 0), (2, 2, 1), (2, 2, 2)]



class BasicIterClass:
    def __init__(self, n):
        self.n = n
        self.i = 0
    def __next__(self):
        res = self.i
        if res >= self.n:
            raise StopIteration
        self.i = res + 1
        return res
    def __iter__(self):
        return self

class IteratingSequenceClass:
    def __init__(self, n):
        self.n = n
    def __iter__(self):
        return BasicIterClass(self.n)

class IteratorProxyClass:
    def __init__(self, i):
        self.i = i
    def __next__(self):
        return next(self.i)
    def __iter__(self):
        return self

class SequenceClass:
    def __init__(self, n):
        self.n = n
    def __getitem__(self, i):
        if 0 <= i < self.n:
            return i
        else:
            raise IndexError

class SequenceProxyClass:
    def __init__(self, s):
        self.s = s
    def __getitem__(self, i):
        return self.s[i]

class UnlimitedSequenceClass:
    def __getitem__(self, i):
        return i

class DefaultIterClass:
    pass

class NoIterClass:
    def __getitem__(self, i):
        return i
    __iter__ = None

class BadIterableClass:
    def __iter__(self):
        raise ZeroDivisionError

class CallableIterClass:
    def __init__(self):
        self.i = 0
    def __call__(self):
        i = self.i
        self.i = i + 1
        if i > 100:
            raise IndexError 
        return i

class EmptyIterClass:
    def __len__(self):
        return 0
    def __getitem__(self, i):
        raise StopIteration



class TestCase(unittest.TestCase):

    
    def check_iterator(self, it, seq, pickle=True):
        if pickle:
            self.check_pickle(it, seq)
        res = []
        while 1:
            try:
                val = next(it)
            except StopIteration:
                break
            res.append(val)
        self.assertEqual(res, seq)

    
    def check_for_loop(self, expr, seq, pickle=True):
        if pickle:
            self.check_pickle(iter(expr), seq)
        res = []
        for val in expr:
            res.append(val)
        self.assertEqual(res, seq)

    
    def check_pickle(self, itorg, seq):
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            d = pickle.dumps(itorg, proto)
            it = pickle.loads(d)
            
            
            
            self.assertTrue(isinstance(it, collections.abc.Iterator))
            self.assertEqual(list(it), seq)

            it = pickle.loads(d)
            try:
                next(it)
            except StopIteration:
                continue
            d = pickle.dumps(it, proto)
            it = pickle.loads(d)
            self.assertEqual(list(it), seq[1:])

    
    def test_iter_basic(self):
        self.check_iterator(iter(range(10)), list(range(10)))

    
    def test_iter_idempotency(self):
        seq = list(range(10))
        it = iter(seq)
        it2 = iter(it)
        self.assertTrue(it is it2)

    
    def test_iter_for_loop(self):
        self.check_for_loop(iter(range(10)), list(range(10)))

    
    def test_iter_independence(self):
        seq = range(3)
        res = []
        for i in iter(seq):
            for j in iter(seq):
                for k in iter(seq):
                    res.append((i, j, k))
        self.assertEqual(res, TRIPLETS)

    
    def test_nested_comprehensions_iter(self):
        seq = range(3)
        res = [(i, j, k)
               for i in iter(seq) for j in iter(seq) for k in iter(seq)]
        self.assertEqual(res, TRIPLETS)

    
    def test_nested_comprehensions_for(self):
        seq = range(3)
        res = [(i, j, k) for i in seq for j in seq for k in seq]
        self.assertEqual(res, TRIPLETS)

    
    def test_iter_class_for(self):
        self.check_for_loop(IteratingSequenceClass(10), list(range(10)))

    
    def test_iter_class_iter(self):
        self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))

    
    def test_seq_class_for(self):
        self.check_for_loop(SequenceClass(10), list(range(10)))

    
    def test_seq_class_iter(self):
        self.check_iterator(iter(SequenceClass(10)), list(range(10)))

    def test_mutating_seq_class_iter_pickle(self):
        orig = SequenceClass(5)
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            
            itorig = iter(orig)
            d = pickle.dumps((itorig, orig), proto)
            it, seq = pickle.loads(d)
            seq.n = 7
            self.assertIs(type(it), type(itorig))
            self.assertEqual(list(it), list(range(7)))

            
            next(itorig)
            d = pickle.dumps((itorig, orig), proto)
            it, seq = pickle.loads(d)
            seq.n = 7
            self.assertIs(type(it), type(itorig))
            self.assertEqual(list(it), list(range(1, 7)))

            
            for i in range(1, 5):
                next(itorig)
            d = pickle.dumps((itorig, orig), proto)
            it, seq = pickle.loads(d)
            seq.n = 7
            self.assertIs(type(it), type(itorig))
            self.assertEqual(list(it), list(range(5, 7)))

            
            self.assertRaises(StopIteration, next, itorig)
            d = pickle.dumps((itorig, orig), proto)
            it, seq = pickle.loads(d)
            seq.n = 7
            self.assertTrue(isinstance(it, collections.abc.Iterator))
            self.assertEqual(list(it), [])

    def test_mutating_seq_class_exhausted_iter(self):
        a = SequenceClass(5)
        exhit = iter(a)
        empit = iter(a)
        for x in exhit:  
            next(empit)  
        a.n = 7
        self.assertEqual(list(exhit), [])
        self.assertEqual(list(empit), [5, 6])
        self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6])

    def test_reduce_mutating_builtins_iter(self):
        
        
        

        
        builtins_dict = builtins.__dict__
        orig = {"iter": iter, "reversed": reversed}

        def run(builtin_name, item, sentinel=None):
            it = iter(item) if sentinel is None else iter(item, sentinel)

            class CustomStr:
                def __init__(self, name, iterator):
                    self.name = name
                    self.iterator = iterator
                def __hash__(self):
                    return hash(self.name)
                def __eq__(self, other):
                    
                    
                    
                    
                    list(self.iterator)
                    return other == self.name

            
            
            
            del builtins_dict[builtin_name]
            builtins_dict[CustomStr(builtin_name, it)] = orig[builtin_name]

            return it.__reduce__()

        types = [
            (EmptyIterClass(),),
            (bytes(8),),
            (bytearray(8),),
            ((1, 2, 3),),
            (lambda: 0, 0),
            (tuple[int],)  
        ]

        try:
            run_iter = functools.partial(run, "iter")
            
            
            
            self.assertEqual(run_iter("xyz"), (orig["iter"], ("",)))
            self.assertEqual(run_iter([1, 2, 3]), (orig["iter"], ([],)))

            
            
            self.assertEqual(
                run("reversed", orig["reversed"](list(range(8)))),
                (iter, ([],))
            )

            for case in types:
                self.assertEqual(run_iter(*case), (orig["iter"], ((),)))
        finally:
            
            for key, func in orig.items():
                
                
                with contextlib.suppress(KeyError):
                    
                    
                    
                    del builtins_dict[key]
                builtins_dict[key] = func

    
    def test_new_style_iter_class(self):
        class IterClass(object):
            def __iter__(self):
                return self
        self.assertRaises(TypeError, iter, IterClass())

    
    def test_iter_callable(self):
        self.check_iterator(iter(CallableIterClass(), 10), list(range(10)), pickle=True)

    
    def test_iter_function(self):
        def spam(state=[0]):
            i = state[0]
            state[0] = i+1
            return i
        self.check_iterator(iter(spam, 10), list(range(10)), pickle=False)

    
    def test_iter_function_stop(self):
        def spam(state=[0]):
            i = state[0]
            if i == 10:
                raise StopIteration
            state[0] = i+1
            return i
        self.check_iterator(iter(spam, 20), list(range(10)), pickle=False)

    def test_iter_function_concealing_reentrant_exhaustion(self):
        
        
        
        HAS_MORE = 1
        NO_MORE = 2

        def exhaust(iterator):
            
            list(iterator)

        def spam():
            
            
            if spam.is_recursive_call:
                return NO_MORE
            spam.is_recursive_call = True
            exhaust(spam.iterator)
            return HAS_MORE

        spam.is_recursive_call = False
        spam.iterator = iter(spam, NO_MORE)
        with self.assertRaises(StopIteration):
            next(spam.iterator)

    
    def test_exception_function(self):
        def spam(state=[0]):
            i = state[0]
            state[0] = i+1
            if i == 10:
                raise RuntimeError
            return i
        res = []
        try:
            for x in iter(spam, 20):
                res.append(x)
        except RuntimeError:
            self.assertEqual(res, list(range(10)))
        else:
            self.fail("should have raised RuntimeError")

    
    def test_exception_sequence(self):
        class MySequenceClass(SequenceClass):
            def __getitem__(self, i):
                if i == 10:
                    raise RuntimeError
                return SequenceClass.__getitem__(self, i)
        res = []
        try:
            for x in MySequenceClass(20):
                res.append(x)
        except RuntimeError:
            self.assertEqual(res, list(range(10)))
        else:
            self.fail("should have raised RuntimeError")

    
    def test_stop_sequence(self):
        class MySequenceClass(SequenceClass):
            def __getitem__(self, i):
                if i == 10:
                    raise StopIteration
                return SequenceClass.__getitem__(self, i)
        self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False)

    
    def test_iter_big_range(self):
        self.check_for_loop(iter(range(10000)), list(range(10000)))

    
    def test_iter_empty(self):
        self.check_for_loop(iter([]), [])

    
    def test_iter_tuple(self):
        self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10)))

    
    def test_iter_range(self):
        self.check_for_loop(iter(range(10)), list(range(10)))

    
    def test_iter_string(self):
        self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])

    
    def test_iter_dict(self):
        dict = {}
        for i in range(10):
            dict[i] = None
        self.check_for_loop(dict, list(dict.keys()))

    
    def test_iter_file(self):
        f = open(TESTFN, "w", encoding="utf-8")
        try:
            for i in range(5):
                f.write("%d\n" % i)
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False)
            self.check_for_loop(f, [], pickle=False)
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_builtin_list(self):
        self.assertEqual(list(SequenceClass(5)), list(range(5)))
        self.assertEqual(list(SequenceClass(0)), [])
        self.assertEqual(list(()), [])

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(list(d), list(d.keys()))

        self.assertRaises(TypeError, list, list)
        self.assertRaises(TypeError, list, 42)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            for i in range(5):
                f.write("%d\n" % i)
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
            f.seek(0, 0)
            self.assertEqual(list(f),
                             ["0\n", "1\n", "2\n", "3\n", "4\n"])
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_builtin_tuple(self):
        self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
        self.assertEqual(tuple(SequenceClass(0)), ())
        self.assertEqual(tuple([]), ())
        self.assertEqual(tuple(()), ())
        self.assertEqual(tuple("abc"), ("a", "b", "c"))

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(tuple(d), tuple(d.keys()))

        self.assertRaises(TypeError, tuple, list)
        self.assertRaises(TypeError, tuple, 42)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            for i in range(5):
                f.write("%d\n" % i)
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
            f.seek(0, 0)
            self.assertEqual(tuple(f),
                             ("0\n", "1\n", "2\n", "3\n", "4\n"))
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_builtin_filter(self):
        self.assertEqual(list(filter(None, SequenceClass(5))),
                         list(range(1, 5)))
        self.assertEqual(list(filter(None, SequenceClass(0))), [])
        self.assertEqual(list(filter(None, ())), [])
        self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(list(filter(None, d)), list(d.keys()))

        self.assertRaises(TypeError, filter, None, list)
        self.assertRaises(TypeError, filter, None, 42)

        class Boolean:
            def __init__(self, truth):
                self.truth = truth
            def __bool__(self):
                return self.truth
        bTrue = Boolean(True)
        bFalse = Boolean(False)

        class Seq:
            def __init__(self, *args):
                self.vals = args
            def __iter__(self):
                class SeqIter:
                    def __init__(self, vals):
                        self.vals = vals
                        self.i = 0
                    def __iter__(self):
                        return self
                    def __next__(self):
                        i = self.i
                        self.i = i + 1
                        if i < len(self.vals):
                            return self.vals[i]
                        else:
                            raise StopIteration
                return SeqIter(self.vals)

        seq = Seq(*([bTrue, bFalse] * 25))
        self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
        self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)

    
    def test_builtin_max_min(self):
        self.assertEqual(max(SequenceClass(5)), 4)
        self.assertEqual(min(SequenceClass(5)), 0)
        self.assertEqual(max(8, -1), 8)
        self.assertEqual(min(8, -1), -1)

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(max(d), "two")
        self.assertEqual(min(d), "one")
        self.assertEqual(max(d.values()), 3)
        self.assertEqual(min(iter(d.values())), 1)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("medium line\n")
            f.write("xtra large line\n")
            f.write("itty-bitty line\n")
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.assertEqual(min(f), "itty-bitty line\n")
            f.seek(0, 0)
            self.assertEqual(max(f), "xtra large line\n")
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_builtin_map(self):
        self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
                         list(range(1, 6)))

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
                         list(d.items()))
        dkeys = list(d.keys())
        expected = [(i < len(d) and dkeys[i] or None,
                     i,
                     i < len(d) and dkeys[i] or None)
                    for i in range(3)]

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            for i in range(10):
                f.write("xy" * i + "\n") 
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_builtin_zip(self):
        self.assertEqual(list(zip()), [])
        self.assertEqual(list(zip(*[])), [])
        self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])

        self.assertRaises(TypeError, zip, None)
        self.assertRaises(TypeError, zip, range(10), 42)
        self.assertRaises(TypeError, zip, range(10), zip)

        self.assertEqual(list(zip(IteratingSequenceClass(3))),
                         [(0,), (1,), (2,)])
        self.assertEqual(list(zip(SequenceClass(3))),
                         [(0,), (1,), (2,)])

        d = {"one": 1, "two": 2, "three": 3}
        self.assertEqual(list(d.items()), list(zip(d, d.values())))

        
        class IntsFrom:
            def __init__(self, start):
                self.i = start

            def __iter__(self):
                return self

            def __next__(self):
                i = self.i
                self.i = i+1
                return i

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("a\n" "bbb\n" "cc\n")
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
                             [(0, "a\n", -100),
                              (1, "bbb\n", -99),
                              (2, "cc\n", -98)])
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

        self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])

        
        class NoGuessLen5:
            def __getitem__(self, i):
                if i >= 5:
                    raise IndexError
                return i

        class Guess3Len5(NoGuessLen5):
            def __len__(self):
                return 3

        class Guess30Len5(NoGuessLen5):
            def __len__(self):
                return 30

        def lzip(*args):
            return list(zip(*args))

        self.assertEqual(len(Guess3Len5()), 3)
        self.assertEqual(len(Guess30Len5()), 30)
        self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
        self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
        self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))

        expected = [(i, i) for i in range(5)]
        for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
            for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
                self.assertEqual(lzip(x, y), expected)

    def test_unicode_join_endcase(self):

        
        
        class OhPhooey:
            def __init__(self, seq):
                self.it = iter(seq)
                self.i = 0

            def __iter__(self):
                return self

            def __next__(self):
                i = self.i
                self.i = i+1
                if i == 2:
                    return "fooled you!"
                return next(self.it)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("a\n" + "b\n" + "c\n")
        finally:
            f.close()

        f = open(TESTFN, "r", encoding="utf-8")
        
        
        
        
        
        try:
            got = " - ".join(OhPhooey(f))
            self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_in_and_not_in(self):
        for sc5 in IteratingSequenceClass(5), SequenceClass(5):
            for i in range(5):
                self.assertIn(i, sc5)
            for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
                self.assertNotIn(i, sc5)

        self.assertIn(ALWAYS_EQ, IteratorProxyClass(iter([1])))
        self.assertIn(ALWAYS_EQ, SequenceProxyClass([1]))
        self.assertNotIn(ALWAYS_EQ, IteratorProxyClass(iter([NEVER_EQ])))
        self.assertNotIn(ALWAYS_EQ, SequenceProxyClass([NEVER_EQ]))
        self.assertIn(NEVER_EQ, IteratorProxyClass(iter([ALWAYS_EQ])))
        self.assertIn(NEVER_EQ, SequenceProxyClass([ALWAYS_EQ]))

        self.assertRaises(TypeError, lambda: 3 in 12)
        self.assertRaises(TypeError, lambda: 3 not in map)
        self.assertRaises(ZeroDivisionError, lambda: 3 in BadIterableClass())

        d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
        for k in d:
            self.assertIn(k, d)
            self.assertNotIn(k, d.values())
        for v in d.values():
            self.assertIn(v, d.values())
            self.assertNotIn(v, d)
        for k, v in d.items():
            self.assertIn((k, v), d.items())
            self.assertNotIn((v, k), d.items())

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("a\n" "b\n" "c\n")
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            for chunk in "abc":
                f.seek(0, 0)
                self.assertNotIn(chunk, f)
                f.seek(0, 0)
                self.assertIn((chunk + "\n"), f)
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_countOf(self):
        from operator import countOf
        self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
        self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
        self.assertEqual(countOf("122325", "2"), 3)
        self.assertEqual(countOf("122325", "6"), 0)

        self.assertRaises(TypeError, countOf, 42, 1)
        self.assertRaises(TypeError, countOf, countOf, countOf)

        d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
        for k in d:
            self.assertEqual(countOf(d, k), 1)
        self.assertEqual(countOf(d.values(), 3), 3)
        self.assertEqual(countOf(d.values(), 2j), 1)
        self.assertEqual(countOf(d.values(), 1j), 0)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("a\n" "b\n" "c\n" "b\n")
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
                f.seek(0, 0)
                self.assertEqual(countOf(f, letter + "\n"), count)
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

    
    def test_indexOf(self):
        from operator import indexOf
        self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
        self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
        self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
        self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
        self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
        self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)

        self.assertEqual(indexOf("122325", "2"), 1)
        self.assertEqual(indexOf("122325", "5"), 5)
        self.assertRaises(ValueError, indexOf, "122325", "6")

        self.assertRaises(TypeError, indexOf, 42, 1)
        self.assertRaises(TypeError, indexOf, indexOf, indexOf)
        self.assertRaises(ZeroDivisionError, indexOf, BadIterableClass(), 1)

        f = open(TESTFN, "w", encoding="utf-8")
        try:
            f.write("a\n" "b\n" "c\n" "d\n" "e\n")
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            fiter = iter(f)
            self.assertEqual(indexOf(fiter, "b\n"), 1)
            self.assertEqual(indexOf(fiter, "d\n"), 1)
            self.assertEqual(indexOf(fiter, "e\n"), 0)
            self.assertRaises(ValueError, indexOf, fiter, "a\n")
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

        iclass = IteratingSequenceClass(3)
        for i in range(3):
            self.assertEqual(indexOf(iclass, i), i)
        self.assertRaises(ValueError, indexOf, iclass, -1)

    
    def test_writelines(self):
        f = open(TESTFN, "w", encoding="utf-8")

        try:
            self.assertRaises(TypeError, f.writelines, None)
            self.assertRaises(TypeError, f.writelines, 42)

            f.writelines(["1\n", "2\n"])
            f.writelines(("3\n", "4\n"))
            f.writelines({'5\n': None})
            f.writelines({})

            
            class Iterator:
                def __init__(self, start, finish):
                    self.start = start
                    self.finish = finish
                    self.i = self.start

                def __next__(self):
                    if self.i >= self.finish:
                        raise StopIteration
                    result = str(self.i) + '\n'
                    self.i += 1
                    return result

                def __iter__(self):
                    return self

            class Whatever:
                def __init__(self, start, finish):
                    self.start = start
                    self.finish = finish

                def __iter__(self):
                    return Iterator(self.start, self.finish)

            f.writelines(Whatever(6, 6+2000))
            f.close()

            f = open(TESTFN, encoding="utf-8")
            expected = [str(i) + "\n" for i in range(1, 2006)]
            self.assertEqual(list(f), expected)

        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass


    
    def test_unpack_iter(self):
        a, b = 1, 2
        self.assertEqual((a, b), (1, 2))

        a, b, c = IteratingSequenceClass(3)
        self.assertEqual((a, b, c), (0, 1, 2))

        try:    
            a, b = IteratingSequenceClass(3)
        except ValueError:
            pass
        else:
            self.fail("should have raised ValueError")

        try:    
            a, b, c = IteratingSequenceClass(2)
        except ValueError:
            pass
        else:
            self.fail("should have raised ValueError")

        try:    
            a, b, c = len
        except TypeError:
            pass
        else:
            self.fail("should have raised TypeError")

        a, b, c = {1: 42, 2: 42, 3: 42}.values()
        self.assertEqual((a, b, c), (42, 42, 42))

        f = open(TESTFN, "w", encoding="utf-8")
        lines = ("a\n", "bb\n", "ccc\n")
        try:
            for line in lines:
                f.write(line)
        finally:
            f.close()
        f = open(TESTFN, "r", encoding="utf-8")
        try:
            a, b, c = f
            self.assertEqual((a, b, c), lines)
        finally:
            f.close()
            try:
                unlink(TESTFN)
            except OSError:
                pass

        (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
        self.assertEqual((a, b, c), (0, 1, 42))


    @cpython_only
    def test_ref_counting_behavior(self):
        class C(object):
            count = 0
            def __new__(cls):
                cls.count += 1
                return object.__new__(cls)
            def __del__(self):
                cls = self.__class__
                assert cls.count > 0
                cls.count -= 1
        x = C()
        self.assertEqual(C.count, 1)
        del x
        self.assertEqual(C.count, 0)
        l = [C(), C(), C()]
        self.assertEqual(C.count, 3)
        try:
            a, b = iter(l)
        except ValueError:
            pass
        del l
        self.assertEqual(C.count, 0)


    
    
    

    def test_sinkstate_list(self):
        
        a = list(range(5))
        b = iter(a)
        self.assertEqual(list(b), list(range(5)))
        a.extend(range(5, 10))
        self.assertEqual(list(b), [])

    def test_sinkstate_tuple(self):
        a = (0, 1, 2, 3, 4)
        b = iter(a)
        self.assertEqual(list(b), list(range(5)))
        self.assertEqual(list(b), [])

    def test_sinkstate_string(self):
        a = "abcde"
        b = iter(a)
        self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
        self.assertEqual(list(b), [])

    def test_sinkstate_sequence(self):
        
        a = SequenceClass(5)
        b = iter(a)
        self.assertEqual(list(b), list(range(5)))
        a.n = 10
        self.assertEqual(list(b), [])

    def test_sinkstate_callable(self):
        
        def spam(state=[0]):
            i = state[0]
            state[0] = i+1
            if i == 10:
                raise AssertionError("shouldn't have gotten this far")
            return i
        b = iter(spam, 5)
        self.assertEqual(list(b), list(range(5)))
        self.assertEqual(list(b), [])

    def test_sinkstate_dict(self):
        
        
        a = {1:1, 2:2, 0:0, 4:4, 3:3}
        for b in iter(a), a.keys(), a.items(), a.values():
            b = iter(a)
            self.assertEqual(len(list(b)), 5)
            self.assertEqual(list(b), [])

    def test_sinkstate_yield(self):
        def gen():
            for i in range(5):
                yield i
        b = gen()
        self.assertEqual(list(b), list(range(5)))
        self.assertEqual(list(b), [])

    def test_sinkstate_range(self):
        a = range(5)
        b = iter(a)
        self.assertEqual(list(b), list(range(5)))
        self.assertEqual(list(b), [])

    def test_sinkstate_enumerate(self):
        a = range(5)
        e = enumerate(a)
        b = iter(e)
        self.assertEqual(list(b), list(zip(range(5), range(5))))
        self.assertEqual(list(b), [])

    def test_3720(self):
        
        class BadIterator(object):
            def __iter__(self):
                return self
            def __next__(self):
                del BadIterator.__next__
                return 1

        try:
            for i in BadIterator() :
                pass
        except TypeError:
            pass

    def test_extending_list_with_iterator_does_not_segfault(self):
        
        
        
        
        
        def gen():
            for i in range(500):
                yield i
        lst = [0] * 500
        for i in range(240):
            lst.pop(0)
        lst.extend(gen())
        self.assertEqual(len(lst), 760)

    @cpython_only
    def test_iter_overflow(self):
        
        it = iter(UnlimitedSequenceClass())
        
        it.__setstate__(sys.maxsize - 2)
        self.assertEqual(next(it), sys.maxsize - 2)
        self.assertEqual(next(it), sys.maxsize - 1)
        with self.assertRaises(OverflowError):
            next(it)
        
        with self.assertRaises(OverflowError):
            next(it)

    def test_iter_neg_setstate(self):
        it = iter(UnlimitedSequenceClass())
        it.__setstate__(-42)
        self.assertEqual(next(it), 0)
        self.assertEqual(next(it), 1)

    def test_free_after_iterating(self):
        check_free_after_iterating(self, iter, SequenceClass, (0,))

    def test_error_iter(self):
        for typ in (DefaultIterClass, NoIterClass):
            self.assertRaises(TypeError, iter, typ())
        self.assertRaises(ZeroDivisionError, iter, BadIterableClass())


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