@@ -1642,10 +1642,11 @@ def test_tee(self):
16421642 self .assertEqual (len (result ), n )
16431643 self .assertEqual ([list (x ) for x in result ], [list ('abc' )]* n )
16441644
1645- # tee pass-through to copyable iterator
1645+ # tee objects are independent (see bug gh-123884)
16461646 a , b = tee ('abc' )
16471647 c , d = tee (a )
1648- self .assertTrue (a is c )
1648+ e , f = tee (c )
1649+ self .assertTrue (len ({a , b , c , d , e , f }) == 6 )
16491650
16501651 # test tee_new
16511652 t1 , t2 = tee ('abc' )
@@ -2072,21 +2073,36 @@ def test_tee_recipe(self):
20722073
20732074 def tee (iterable , n = 2 ):
20742075 if n < 0 :
2075- raise ValueError ('n must be >= 0' )
2076- iterator = iter (iterable )
2077- shared_link = [None , None ]
2078- return tuple (_tee (iterator , shared_link ) for _ in range (n ))
2076+ raise ValueError
2077+ if n == 0 :
2078+ return ()
2079+ iterator = _tee (iterable )
2080+ result = [iterator ]
2081+ for _ in range (n - 1 ):
2082+ result .append (_tee (iterator ))
2083+ return tuple (result )
2084+
2085+ class _tee :
2086+
2087+ def __init__ (self , iterable ):
2088+ it = iter (iterable )
2089+ if isinstance (it , _tee ):
2090+ self .iterator = it .iterator
2091+ self .link = it .link
2092+ else :
2093+ self .iterator = it
2094+ self .link = [None , None ]
20792095
2080- def _tee ( iterator , link ):
2081- try :
2082- while True :
2083- if link [ 1 ] is None :
2084- link [ 0 ] = next ( iterator )
2085- link [1 ] = [ None , None ]
2086- value , link = link
2087- yield value
2088- except StopIteration :
2089- return
2096+ def __iter__ ( self ):
2097+ return self
2098+
2099+ def __next__ ( self ) :
2100+ link = self . link
2101+ if link [1 ] is None :
2102+ link [ 0 ] = next ( self . iterator )
2103+ link [ 1 ] = [ None , None ]
2104+ value , self . link = link
2105+ return value
20902106
20912107 # End tee() recipe #############################################
20922108
@@ -2132,12 +2148,10 @@ def _tee(iterator, link):
21322148 self .assertRaises (TypeError , tee , [1 ,2 ], 'x' )
21332149 self .assertRaises (TypeError , tee , [1 ,2 ], 3 , 'x' )
21342150
2135- # Tests not applicable to the tee() recipe
2136- if False :
2137- # tee object should be instantiable
2138- a , b = tee ('abc' )
2139- c = type (a )('def' )
2140- self .assertEqual (list (c ), list ('def' ))
2151+ # tee object should be instantiable
2152+ a , b = tee ('abc' )
2153+ c = type (a )('def' )
2154+ self .assertEqual (list (c ), list ('def' ))
21412155
21422156 # test long-lagged and multi-way split
21432157 a , b , c = tee (range (2000 ), 3 )
@@ -2158,21 +2172,19 @@ def _tee(iterator, link):
21582172 self .assertEqual (len (result ), n )
21592173 self .assertEqual ([list (x ) for x in result ], [list ('abc' )]* n )
21602174
2175+ # tee objects are independent (see bug gh-123884)
2176+ a , b = tee ('abc' )
2177+ c , d = tee (a )
2178+ e , f = tee (c )
2179+ self .assertTrue (len ({a , b , c , d , e , f }) == 6 )
21612180
2162- # Tests not applicable to the tee() recipe
2163- if False :
2164- # tee pass-through to copyable iterator
2165- a , b = tee ('abc' )
2166- c , d = tee (a )
2167- self .assertTrue (a is c )
2168-
2169- # test tee_new
2170- t1 , t2 = tee ('abc' )
2171- tnew = type (t1 )
2172- self .assertRaises (TypeError , tnew )
2173- self .assertRaises (TypeError , tnew , 10 )
2174- t3 = tnew (t1 )
2175- self .assertTrue (list (t1 ) == list (t2 ) == list (t3 ) == list ('abc' ))
2181+ # test tee_new
2182+ t1 , t2 = tee ('abc' )
2183+ tnew = type (t1 )
2184+ self .assertRaises (TypeError , tnew )
2185+ self .assertRaises (TypeError , tnew , 10 )
2186+ t3 = tnew (t1 )
2187+ self .assertTrue (list (t1 ) == list (t2 ) == list (t3 ) == list ('abc' ))
21762188
21772189 # test that tee objects are weak referencable
21782190 a , b = tee (range (10 ))
0 commit comments