@@ -124,12 +124,53 @@ def test_named_expression_invalid_rebinding_list_comprehension_iteration_variabl
124
124
("Unreachable reuse" , 'i' , "[False or (i:=0) for i in range(5)]" ),
125
125
("Unreachable nested reuse" , 'i' ,
126
126
"[(i, j) for i in range(5) for j in range(5) if True or (i:=10)]" ),
127
+ # Regression tests from https://github.com/python/cpython/issues/87447
128
+ ("Complex expression: a" , "a" ,
129
+ "[(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
130
+ ("Complex expression: b" , "b" ,
131
+ "[(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
127
132
]
128
133
for case , target , code in cases :
129
134
msg = f"assignment expression cannot rebind comprehension iteration variable '{ target } '"
130
135
with self .subTest (case = case ):
131
136
with self .assertRaisesRegex (SyntaxError , msg ):
132
- exec (code , {}, {})
137
+ exec (code , {}) # Module scope
138
+ with self .assertRaisesRegex (SyntaxError , msg ):
139
+ exec (code , {}, {}) # Class scope
140
+ with self .assertRaisesRegex (SyntaxError , msg ):
141
+ exec (f"lambda: { code } " , {}) # Function scope
142
+
143
+ def test_named_expression_valid_rebinding_list_comprehension_iteration_variable (self ):
144
+ cases = [
145
+ # Regression tests from https://github.com/python/cpython/issues/87447
146
+ ("Complex expression: c" ,
147
+ "[(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
148
+ ("Complex expression: d" ,
149
+ "[(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
150
+ ("Complex expression: e" ,
151
+ "[(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
152
+ ("Complex expression: f" ,
153
+ "[(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
154
+ ("Complex expression: g" ,
155
+ "[(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
156
+ ("Complex expression: h" ,
157
+ "[(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
158
+ ("Complex expression: i" ,
159
+ "[(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
160
+ ("Complex expression: j" ,
161
+ "[(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j]" ),
162
+ ]
163
+ for case , code in cases :
164
+ with self .subTest (case = case ):
165
+ # Names used in snippets are not defined,
166
+ # but we are fine with it: just must not be a SyntaxError.
167
+ # Names used in snippets are not defined,
168
+ # but we are fine with it: just must not be a SyntaxError.
169
+ with self .assertRaises (NameError ):
170
+ exec (code , {}) # Module scope
171
+ with self .assertRaises (NameError ):
172
+ exec (code , {}, {}) # Class scope
173
+ exec (f"lambda: { code } " , {}) # Function scope
133
174
134
175
def test_named_expression_invalid_rebinding_list_comprehension_inner_loop (self ):
135
176
cases = [
@@ -178,12 +219,51 @@ def test_named_expression_invalid_rebinding_set_comprehension_iteration_variable
178
219
("Unreachable reuse" , 'i' , "{False or (i:=0) for i in range(5)}" ),
179
220
("Unreachable nested reuse" , 'i' ,
180
221
"{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}" ),
222
+ # Regression tests from https://github.com/python/cpython/issues/87447
223
+ ("Complex expression: a" , "a" ,
224
+ "{(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
225
+ ("Complex expression: b" , "b" ,
226
+ "{(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
181
227
]
182
228
for case , target , code in cases :
183
229
msg = f"assignment expression cannot rebind comprehension iteration variable '{ target } '"
184
230
with self .subTest (case = case ):
185
231
with self .assertRaisesRegex (SyntaxError , msg ):
186
- exec (code , {}, {})
232
+ exec (code , {}) # Module scope
233
+ with self .assertRaisesRegex (SyntaxError , msg ):
234
+ exec (code , {}, {}) # Class scope
235
+ with self .assertRaisesRegex (SyntaxError , msg ):
236
+ exec (f"lambda: { code } " , {}) # Function scope
237
+
238
+ def test_named_expression_valid_rebinding_set_comprehension_iteration_variable (self ):
239
+ cases = [
240
+ # Regression tests from https://github.com/python/cpython/issues/87447
241
+ ("Complex expression: c" ,
242
+ "{(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
243
+ ("Complex expression: d" ,
244
+ "{(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
245
+ ("Complex expression: e" ,
246
+ "{(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
247
+ ("Complex expression: f" ,
248
+ "{(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
249
+ ("Complex expression: g" ,
250
+ "{(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
251
+ ("Complex expression: h" ,
252
+ "{(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
253
+ ("Complex expression: i" ,
254
+ "{(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
255
+ ("Complex expression: j" ,
256
+ "{(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j}" ),
257
+ ]
258
+ for case , code in cases :
259
+ with self .subTest (case = case ):
260
+ # Names used in snippets are not defined,
261
+ # but we are fine with it: just must not be a SyntaxError.
262
+ with self .assertRaises (NameError ):
263
+ exec (code , {}) # Module scope
264
+ with self .assertRaises (NameError ):
265
+ exec (code , {}, {}) # Class scope
266
+ exec (f"lambda: { code } " , {}) # Function scope
187
267
188
268
def test_named_expression_invalid_rebinding_set_comprehension_inner_loop (self ):
189
269
cases = [
0 commit comments