From: Mark Shannon Date: Mon, 8 Jul 2024 13:20:13 +0000 (+0100) Subject: GH-121012: Set index to -1 when list iterators become exhausted in tier 2 (GH-121483) X-Git-Tag: v3.14.0a1~1201 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ad6067bd4556afddc86004f8e350aa672fda217;p=thirdparty%2FPython%2Fcpython.git GH-121012: Set index to -1 when list iterators become exhausted in tier 2 (GH-121483) --- diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 4d2d54705fc8..ad7accf2099f 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -299,6 +299,15 @@ class ListTest(list_tests.CommonTest): lst = [X(), X()] X() in lst + def test_tier2_invalidates_iterator(self): + # GH-121012 + for _ in range(100): + a = [1, 2, 3] + it = iter(a) + for _ in it: + pass + a.append(4) + self.assertEqual(list(it), []) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst b/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst new file mode 100644 index 000000000000..7b04eb68b037 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-07-08-10-31-08.gh-issue-121012.M5hHk-.rst @@ -0,0 +1,2 @@ +Tier 2 execution now ensures that list iterators remain exhausted, once they +become exhausted. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 76587a4f0dc6..84241c64ffae 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2967,7 +2967,10 @@ dummy_func( assert(Py_TYPE(iter_o) == &PyListIter_Type); PyListObject *seq = it->it_seq; EXIT_IF(seq == NULL); - EXIT_IF((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)); + if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) { + it->it_index = -1; + EXIT_IF(1); + } } op(_ITER_NEXT_LIST, (iter -- iter, next)) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 3b999465aac8..8f6bc75b528d 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3055,8 +3055,11 @@ JUMP_TO_JUMP_TARGET(); } if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); + it->it_index = -1; + if (1) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); + } } break; }