Title: Incorrect optimization in itertools.tee() · Issue #123884 · python/cpython · GitHub
Open Graph Title: Incorrect optimization in itertools.tee() · Issue #123884 · python/cpython
X Title: Incorrect optimization in itertools.tee() · Issue #123884 · python/cpython
Description: Bug description: To save a memory allocation, the code path for a tee-in-a-tee incorrectly reuses the outer tee object as the first tee object in the result tuple. This is incorrect. All tee objects in the result tuple should have the sa...
Open Graph Description: Bug description: To save a memory allocation, the code path for a tee-in-a-tee incorrectly reuses the outer tee object as the first tee object in the result tuple. This is incorrect. All tee object...
X Description: Bug description: To save a memory allocation, the code path for a tee-in-a-tee incorrectly reuses the outer tee object as the first tee object in the result tuple. This is incorrect. All tee object...
Opengraph URL: https://github.com/python/cpython/issues/123884
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Incorrect optimization in itertools.tee()","articleBody":"**Bug description**:\r\n\r\nTo save a memory allocation, the code path for a tee-in-a-tee incorrectly reuses the outer tee object as the first tee object in the result tuple. This is incorrect. All tee objects in the result tuple should have the same behavior. They are supposed to be \"n independent iterators\". However, the first one is not independent and it has different behaviors from the others. This is an unfortunate side-effect of an early incorrect optimization. I've now seen this affect real code. It surprising, unhelpful, undocumented, and hard to debug.\r\n\r\n**Demonstration**:\r\n\r\n```python\r\nfrom itertools import tee\r\n\r\ndef demo(i):\r\n it = iter('abcdefghi')\r\n [outer_tee] = tee(it, 1)\r\n inner_tee = tee(outer_tee, 10)[i]\r\n return next(inner_tee), next(outer_tee)\r\n\r\nprint('These should all give the same result:')\r\nfor i in range(10):\r\n print(i, demo(i))\r\n```\r\n\r\nThis outputs:\r\n\r\n```\r\nThese should all give the same result:\r\n0 ('a', 'b')\r\n1 ('a', 'a')\r\n2 ('a', 'a')\r\n3 ('a', 'a')\r\n4 ('a', 'a')\r\n5 ('a', 'a')\r\n6 ('a', 'a')\r\n7 ('a', 'a')\r\n8 ('a', 'a')\r\n9 ('a', 'a')\r\n```\r\n\r\nThere is a test for the optimization -- it wasn't an accident. However, the optimization itself is a bug against the published specification in the docs and against general expectations. \r\n\r\n```\r\n a, b = tee('abc')\r\n c, d = tee(a)\r\n self.assertTrue(a is c)\r\n```\r\n\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-124490\n* gh-125081\n* gh-125153\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/rhettinger","@type":"Person","name":"rhettinger"},"datePublished":"2024-09-09T21:30:56.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":9},"url":"https://github.com/123884/cpython/issues/123884"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:91f6802a-902e-5738-23ec-562a38e4a2e8 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B7E8:378C0F:21DBBAB:2E7F98D:696AC322 |
| html-safe-nonce | ec34da92c65852d4b77a29b992fb4c4440a74d8099de1160a508850366e4ada5 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCN0U4OjM3OEMwRjoyMURCQkFCOjJFN0Y5OEQ6Njk2QUMzMjIiLCJ2aXNpdG9yX2lkIjoiODU1MTc1ODIxNDMxNzM5MjY3NCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | d978714ae58aace6d0cb7f7dbc70f7047280c740ab46ef3fbcf35259f241b4fd |
| hovercard-subject-tag | issue:2514961180 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/123884/issue_layout |
| twitter:image | https://opengraph.githubassets.com/f8401c34c0a2ca0a191b453c8f02b38fe9a6ee1c5b8b34bde5868da046767af4/python/cpython/issues/123884 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/f8401c34c0a2ca0a191b453c8f02b38fe9a6ee1c5b8b34bde5868da046767af4/python/cpython/issues/123884 |
| og:image:alt | Bug description: To save a memory allocation, the code path for a tee-in-a-tee incorrectly reuses the outer tee object as the first tee object in the result tuple. This is incorrect. All tee object... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | rhettinger |
| hostname | github.com |
| expected-hostname | github.com |
| None | 986b6a1d774985095564e64d6963d11f094da3d0e2bfda2ab1a27d63662eb033 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 89ad2112b9c4e11df6a0c13c8c1f8eedd36b0977 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width