@@ -1758,23 +1758,38 @@ def test_tee_recipe(self):
17581758
17591759 # Begin tee() recipe ###########################################
17601760
1761+ class _tee :
1762+
1763+ def __init__ (self , iterable ):
1764+ it = iter (iterable )
1765+ if isinstance (it , _tee ):
1766+ self .iterator = it .iterator
1767+ self .link = it .link
1768+ else :
1769+ self .iterator = it
1770+ self .link = [None , None ]
1771+
1772+ def __iter__ (self ):
1773+ return self
1774+
1775+ def __next__ (self ):
1776+ link = self .link
1777+ if link [1 ] is None :
1778+ link [0 ] = next (self .iterator )
1779+ link [1 ] = [None , None ]
1780+ value , self .link = link
1781+ return value
1782+
17611783 def tee (iterable , n = 2 ):
17621784 if n < 0 :
1763- raise ValueError ('n must be >= 0' )
1764- iterator = iter (iterable )
1765- shared_link = [None , None ]
1766- return tuple (_tee (iterator , shared_link ) for _ in range (n ))
1767-
1768- def _tee (iterator , link ):
1769- try :
1770- while True :
1771- if link [1 ] is None :
1772- link [0 ] = next (iterator )
1773- link [1 ] = [None , None ]
1774- value , link = link
1775- yield value
1776- except StopIteration :
1777- return
1785+ raise ValueError
1786+ if n == 0 :
1787+ return ()
1788+ first = _tee (iterable )
1789+ result = [first ]
1790+ for _ in range (n - 1 ):
1791+ result .append (_tee (first ))
1792+ return tuple (result )
17781793
17791794 # End tee() recipe #############################################
17801795
@@ -1820,12 +1835,10 @@ def _tee(iterator, link):
18201835 self .assertRaises (TypeError , tee , [1 ,2 ], 'x' )
18211836 self .assertRaises (TypeError , tee , [1 ,2 ], 3 , 'x' )
18221837
1823- # Tests not applicable to the tee() recipe
1824- if False :
1825- # tee object should be instantiable
1826- a , b = tee ('abc' )
1827- c = type (a )('def' )
1828- self .assertEqual (list (c ), list ('def' ))
1838+ # tee object should be instantiable
1839+ a , b = tee ('abc' )
1840+ c = type (a )('def' )
1841+ self .assertEqual (list (c ), list ('def' ))
18291842
18301843 # test long-lagged and multi-way split
18311844 a , b , c = tee (range (2000 ), 3 )
@@ -1846,21 +1859,19 @@ def _tee(iterator, link):
18461859 self .assertEqual (len (result ), n )
18471860 self .assertEqual ([list (x ) for x in result ], [list ('abc' )]* n )
18481861
1862+ # tee objects are independent (see bug gh-123884)
1863+ a , b = tee ('abc' )
1864+ c , d = tee (a )
1865+ e , f = tee (c )
1866+ self .assertTrue (len ({a , b , c , d , e , f }) == 6 )
18491867
1850- # Tests not applicable to the tee() recipe
1851- if False :
1852- # tee pass-through to copyable iterator
1853- a , b = tee ('abc' )
1854- c , d = tee (a )
1855- self .assertTrue (a is c )
1856-
1857- # test tee_new
1858- t1 , t2 = tee ('abc' )
1859- tnew = type (t1 )
1860- self .assertRaises (TypeError , tnew )
1861- self .assertRaises (TypeError , tnew , 10 )
1862- t3 = tnew (t1 )
1863- self .assertTrue (list (t1 ) == list (t2 ) == list (t3 ) == list ('abc' ))
1868+ # test tee_new
1869+ t1 , t2 = tee ('abc' )
1870+ tnew = type (t1 )
1871+ self .assertRaises (TypeError , tnew )
1872+ self .assertRaises (TypeError , tnew , 10 )
1873+ t3 = tnew (t1 )
1874+ self .assertTrue (list (t1 ) == list (t2 ) == list (t3 ) == list ('abc' ))
18641875
18651876 # test that tee objects are weak referencable
18661877 a , b = tee (range (10 ))
0 commit comments