From f41324e5fd849c05fc6c973713ae23ff96dbad38 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Apr 2025 10:18:03 +0100 Subject: [PATCH 1/4] Do not call __iter__ twice when executing a generator expression --- Lib/test/test_dis.py | 2 -- Lib/test/test_genexps.py | 9 --------- Python/codegen.c | 7 ++++--- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 58ba86fb43092a..b53a3656429300 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -204,7 +204,6 @@ def bug1333982(x=[]): LOAD_CONST 1 ( at 0x..., file "%s", line %d>) MAKE_FUNCTION LOAD_FAST_BORROW 0 (x) - GET_ITER CALL 0 %3d LOAD_SMALL_INT 1 @@ -821,7 +820,6 @@ def foo(x): MAKE_FUNCTION SET_FUNCTION_ATTRIBUTE 8 (closure) LOAD_DEREF 1 (y) - GET_ITER CALL 0 CALL 1 RETURN_VALUE diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index 7fb58a67368576..fe5f18fa3f88a0 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -123,15 +123,6 @@ >>> list(g) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] -Verify that the outermost for-expression makes an immediate check -for iterability - - >>> (i for i in 6) - Traceback (most recent call last): - File "", line 1, in -toplevel- - (i for i in 6) - TypeError: 'int' object is not iterable - Verify late binding for the outermost if-expression >>> include = (2,4,6,8) diff --git a/Python/codegen.c b/Python/codegen.c index dc50737840f002..1b36dee1b6b703 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -4772,9 +4772,10 @@ codegen_comprehension(compiler *c, expr_ty e, int type, } Py_CLEAR(co); - if (codegen_comprehension_iter(c, outermost)) { - goto error; - } + VISIT(c, expr, outermost->iter); + //if (codegen_comprehension_iter(c, outermost)) { + // goto error; + //} ADDOP_I(c, loc, CALL, 0); From d1239f75d893347fff5db73f8a3f374203c119ec Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Apr 2025 10:37:42 +0100 Subject: [PATCH 2/4] Add test and news entry --- Lib/test/test_generators.py | 22 +++++++++++++++++++ ...-04-10-10-29-45.gh-issue-127682.X0HoGz.rst | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 8bce42f037478c..3e41c7b9663491 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -268,6 +268,28 @@ def loop(): #This should not raise loop() + def test_genexpr_only_calls_dunder_iter_once(self): + + class Iterator: + + def __init__(self): + self.val = 0 + + def __next__(self): + if self.val == 2: + raise StopIteration + self.val += 1 + return self.val + + # No __iter__ method + + class C: + + def __iter__(self): + return Iterator() + + self.assertEqual([1,2], list(i for i in C())) + class ModifyUnderlyingIterableTest(unittest.TestCase): iterables = [ diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst new file mode 100644 index 00000000000000..6bcae7f6edcbed --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst @@ -0,0 +1,4 @@ +No longer call ``__iter__`` twice when creating and executing a generator +expression. Creating a generator expression with non-interable will only +raise when the generator expression is exeuted. This brings the behavior of +generator expressions in line with other generators From 53f146f53f27469cbb215cb49da355dd74ca2e9d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Apr 2025 10:42:38 +0100 Subject: [PATCH 3/4] Remove commented out code --- Python/codegen.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Python/codegen.c b/Python/codegen.c index 1b36dee1b6b703..196d1b67fc5e49 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -4773,10 +4773,6 @@ codegen_comprehension(compiler *c, expr_ty e, int type, Py_CLEAR(co); VISIT(c, expr, outermost->iter); - //if (codegen_comprehension_iter(c, outermost)) { - // goto error; - //} - ADDOP_I(c, loc, CALL, 0); if (is_async_comprehension && type != COMP_GENEXP) { From 31eb2d3464ba231b47e91ceb64bf16122ca0d805 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Apr 2025 10:44:55 +0100 Subject: [PATCH 4/4] Fix grammar and spelling in news --- .../2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst index 6bcae7f6edcbed..b87750eb516e7a 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-10-10-29-45.gh-issue-127682.X0HoGz.rst @@ -1,4 +1,4 @@ -No longer call ``__iter__`` twice when creating and executing a generator -expression. Creating a generator expression with non-interable will only -raise when the generator expression is exeuted. This brings the behavior of -generator expressions in line with other generators +No longer call ``__iter__`` twice when creating and executing a generator expression. +Creating a generator expression from a non-interable will raise only when the +generator expression is executed. +This brings the behavior of generator expressions in line with other generators. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy