Skip to content

Commit 6ae5158

Browse files
authored
[3.13] GH-135171: Roll back all fixes for GH-127682 as they are not suitable for 3.13 (#135390)
1 parent 5f5b173 commit 6ae5158

File tree

7 files changed

+30
-72
lines changed

7 files changed

+30
-72
lines changed

Lib/test/test_coroutines.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,31 +2252,6 @@ def c():
22522252
# before fixing, visible stack from throw would be shorter than from send.
22532253
self.assertEqual(len_send, len_throw)
22542254

2255-
def test_call_aiter_once_in_comprehension(self):
2256-
2257-
class Iterator:
2258-
2259-
def __init__(self):
2260-
self.val = 0
2261-
2262-
async def __anext__(self):
2263-
if self.val == 2:
2264-
raise StopAsyncIteration
2265-
self.val += 1
2266-
return self.val
2267-
2268-
# No __aiter__ method
2269-
2270-
class C:
2271-
2272-
def __aiter__(self):
2273-
return Iterator()
2274-
2275-
async def run():
2276-
return [i async for i in C()]
2277-
2278-
self.assertEqual(run_async(run()), ([], [1,2]))
2279-
22802255

22812256
@unittest.skipIf(
22822257
support.is_emscripten or support.is_wasi,

Lib/test/test_dis.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ def bug1333982(x=[]):
184184
LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>)
185185
MAKE_FUNCTION
186186
LOAD_FAST 0 (x)
187+
GET_ITER
187188
CALL 0
188189
189190
%3d LOAD_CONST 2 (1)
@@ -764,6 +765,7 @@ def foo(x):
764765
MAKE_FUNCTION
765766
SET_FUNCTION_ATTRIBUTE 8 (closure)
766767
LOAD_DEREF 1 (y)
768+
GET_ITER
767769
CALL 0
768770
CALL 1
769771
RETURN_VALUE

Lib/test/test_generators.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -246,28 +246,6 @@ def loop():
246246
#This should not raise
247247
loop()
248248

249-
def test_genexpr_only_calls_dunder_iter_once(self):
250-
251-
class Iterator:
252-
253-
def __init__(self):
254-
self.val = 0
255-
256-
def __next__(self):
257-
if self.val == 2:
258-
raise StopIteration
259-
self.val += 1
260-
return self.val
261-
262-
# No __iter__ method
263-
264-
class C:
265-
266-
def __iter__(self):
267-
return Iterator()
268-
269-
self.assertEqual([1,2], list(i for i in C()))
270-
271249

272250
class ModifyUnderlyingIterableTest(unittest.TestCase):
273251
iterables = [

Lib/test/test_genexps.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@
123123
>>> list(g)
124124
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
125125
126+
Verify that the outermost for-expression makes an immediate check
127+
for iterability
128+
129+
>>> (i for i in 6)
130+
Traceback (most recent call last):
131+
File "<pyshell#4>", line 1, in -toplevel-
132+
(i for i in 6)
133+
TypeError: 'int' object is not iterable
134+
126135
Verify late binding for the outermost if-expression
127136
128137
>>> include = (2,4,6,8)

Lib/test/test_listcomps.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -750,28 +750,6 @@ def iter_raises():
750750
self.assertEqual(f.line[f.colno - indent : f.end_colno - indent],
751751
expected)
752752

753-
def test_only_calls_dunder_iter_once(self):
754-
755-
class Iterator:
756-
757-
def __init__(self):
758-
self.val = 0
759-
760-
def __next__(self):
761-
if self.val == 2:
762-
raise StopIteration
763-
self.val += 1
764-
return self.val
765-
766-
# No __iter__ method
767-
768-
class C:
769-
770-
def __iter__(self):
771-
return Iterator()
772-
773-
self.assertEqual([1,2], [i for i in C()])
774-
775753
__test__ = {'doctests' : doctests}
776754

777755
def load_tests(loader, tests, pattern):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Roll back changes to generator and list comprehensions that went into 3.13.4 to fix GH-127682, but which involved semantic and bytecode changes not appropriate for a bugfix release.

Python/compile.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5501,9 +5501,9 @@ compiler_async_comprehension_generator(struct compiler *c, location loc,
55015501
else {
55025502
/* Sub-iter - calculate on the fly */
55035503
VISIT(c, expr, gen->iter);
5504+
ADDOP(c, LOC(gen->iter), GET_AITER);
55045505
}
55055506
}
5506-
ADDOP(c, LOC(gen->iter), GET_AITER);
55075507

55085508
USE_LABEL(c, start);
55095509
/* Runtime will push a block here, so we need to account for that */
@@ -5790,6 +5790,19 @@ pop_inlined_comprehension_state(struct compiler *c, location loc,
57905790
return SUCCESS;
57915791
}
57925792

5793+
static inline int
5794+
compiler_comprehension_iter(struct compiler *c, comprehension_ty comp)
5795+
{
5796+
VISIT(c, expr, comp->iter);
5797+
if (comp->is_async) {
5798+
ADDOP(c, LOC(comp->iter), GET_AITER);
5799+
}
5800+
else {
5801+
ADDOP(c, LOC(comp->iter), GET_ITER);
5802+
}
5803+
return SUCCESS;
5804+
}
5805+
57935806
static int
57945807
compiler_comprehension(struct compiler *c, expr_ty e, int type,
57955808
identifier name, asdl_comprehension_seq *generators, expr_ty elt,
@@ -5811,7 +5824,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
58115824

58125825
outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
58135826
if (is_inlined) {
5814-
if (compiler_visit_expr(c, outermost->iter) < 0) {
5827+
if (compiler_comprehension_iter(c, outermost)) {
58155828
goto error;
58165829
}
58175830
if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
@@ -5897,7 +5910,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
58975910
}
58985911
Py_CLEAR(co);
58995912

5900-
VISIT(c, expr, outermost->iter);
5913+
if (compiler_comprehension_iter(c, outermost)) {
5914+
goto error;
5915+
}
59015916

59025917
ADDOP_I(c, loc, CALL, 0);
59035918

0 commit comments

Comments
 (0)