Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
gh-123884 Tee of tee was not producing n independent iterators#124490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
6ce5cb02a7a4d3e397bfd8e2315c4e4fad41a56697ee064e7f2f0a6e6153e70File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1249,10 +1249,11 @@ def test_tee(self): | ||
| self.assertEqual(len(result), n) | ||
| self.assertEqual([list(x) for x in result], [list('abc')]*n) | ||
| # tee pass-through to copyable iterator | ||
| # tee objects are independent (see bug gh-123884) | ||
| a, b = tee('abc') | ||
| c, d = tee(a) | ||
| self.assertTrue(a is c) | ||
| e, f = tee(c) | ||
| self.assertTrue(len({a, b, c, d, e, f}) == 6) | ||
| # test tee_new | ||
| t1, t2 = tee('abc') | ||
| @@ -1759,21 +1760,36 @@ def test_tee_recipe(self): | ||
| def tee(iterable, n=2): | ||
| if n < 0: | ||
| raise ValueError('n must be >= 0') | ||
| iterator = iter(iterable) | ||
| shared_link = [None, None] | ||
| return tuple(_tee(iterator, shared_link) for _ in range(n)) | ||
| raise ValueError | ||
rhettinger marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| if n == 0: | ||
| return () | ||
| iterator = _tee(iterable) | ||
| result = [iterator] | ||
| for _ in range(n - 1): | ||
| result.append(_tee(iterator)) | ||
| return tuple(result) | ||
| class _tee: | ||
| def __init__(self, iterable): | ||
| it = iter(iterable) | ||
| if isinstance(it, _tee): | ||
| self.iterator = it.iterator | ||
| self.link = it.link | ||
| else: | ||
| self.iterator = it | ||
| self.link = [None, None] | ||
| def _tee(iterator, link): | ||
| try: | ||
| while True: | ||
| if link[1] is None: | ||
| link[0] = next(iterator) | ||
| link[1] = [None, None] | ||
| value, link = link | ||
| yield value | ||
| except StopIteration: | ||
| return | ||
| def __iter__(self): | ||
| return self | ||
| def __next__(self): | ||
| link = self.link | ||
| if link[1] is None: | ||
| link[0] = next(self.iterator) | ||
| link[1] = [None, None] | ||
| value, self.link = link | ||
| return value | ||
| # End tee() recipe ############################################# | ||
| @@ -1819,12 +1835,10 @@ def _tee(iterator, link): | ||
| self.assertRaises(TypeError, tee, [1,2], 'x') | ||
| self.assertRaises(TypeError, tee, [1,2], 3, 'x') | ||
| # Tests not applicable to the tee() recipe | ||
| if False: | ||
| # tee object should be instantiable | ||
| a, b = tee('abc') | ||
| c = type(a)('def') | ||
| self.assertEqual(list(c), list('def')) | ||
| # tee object should be instantiable | ||
| a, b = tee('abc') | ||
| c = type(a)('def') | ||
| self.assertEqual(list(c), list('def')) | ||
| # test long-lagged and multi-way split | ||
| a, b, c = tee(range(2000), 3) | ||
| @@ -1845,21 +1859,19 @@ def _tee(iterator, link): | ||
| self.assertEqual(len(result), n) | ||
| self.assertEqual([list(x) for x in result], [list('abc')]*n) | ||
| # tee objects are independent (see bug gh-123884) | ||
| a, b = tee('abc') | ||
| c, d = tee(a) | ||
| e, f = tee(c) | ||
| self.assertTrue(len({a, b, c, d, e, f}) == 6) | ||
| # Tests not applicable to the tee() recipe | ||
| if False: | ||
| # tee pass-through to copyable iterator | ||
| a, b = tee('abc') | ||
| c, d = tee(a) | ||
| self.assertTrue(a is c) | ||
| # test tee_new | ||
| t1, t2 = tee('abc') | ||
| tnew = type(t1) | ||
| self.assertRaises(TypeError, tnew) | ||
| self.assertRaises(TypeError, tnew, 10) | ||
| t3 = tnew(t1) | ||
| self.assertTrue(list(t1) == list(t2) == list(t3) == list('abc')) | ||
| # test tee_new | ||
| t1, t2 = tee('abc') | ||
| tnew = type(t1) | ||
| self.assertRaises(TypeError, tnew) | ||
| self.assertRaises(TypeError, tnew, 10) | ||
| t3 = tnew(t1) | ||
| self.assertTrue(list(t1) == list(t2) == list(t3) == list('abc')) | ||
| # test that tee objects are weak referencable | ||
| a, b = tee(range(10)) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Fixed bug in itertools.tee() handling of other tee inputs (a tee in a tee). | ||
| The output now has the promised *n* independent new iterators. Formerly, | ||
| the first iterator was identical (not independent) to the input iterator. | ||
| This would sometimes give surprising results. |
Uh oh!
There was an error while loading. Please reload this page.