@@ -113,7 +113,7 @@ def test_named_expression_invalid_in_class_body(self):
113
113
"assignment expression within a comprehension cannot be used in a class body" ):
114
114
exec (code , {}, {})
115
115
116
- def test_named_expression_invalid_rebinding_comprehension_iteration_variable (self ):
116
+ def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable (self ):
117
117
cases = [
118
118
("Local reuse" , 'i' , "[i := 0 for i in range(5)]" ),
119
119
("Nested reuse" , 'j' , "[[(j := 0) for i in range(5)] for j in range(5)]" ),
@@ -130,7 +130,7 @@ def test_named_expression_invalid_rebinding_comprehension_iteration_variable(sel
130
130
with self .assertRaisesRegex (SyntaxError , msg ):
131
131
exec (code , {}, {})
132
132
133
- def test_named_expression_invalid_rebinding_comprehension_inner_loop (self ):
133
+ def test_named_expression_invalid_rebinding_list_comprehension_inner_loop (self ):
134
134
cases = [
135
135
("Inner reuse" , 'j' , "[i for i in range(5) if (j := 0) for j in range(5)]" ),
136
136
("Inner unpacking reuse" , 'j' , "[i for i in range(5) if (j := 0) for j, k in [(0, 1)]]" ),
@@ -145,7 +145,7 @@ def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
145
145
with self .assertRaisesRegex (SyntaxError , msg ):
146
146
exec (f"lambda: { code } " , {}) # Function scope
147
147
148
- def test_named_expression_invalid_comprehension_iterable_expression (self ):
148
+ def test_named_expression_invalid_list_comprehension_iterable_expression (self ):
149
149
cases = [
150
150
("Top level" , "[i for i in (i := range(5))]" ),
151
151
("Inside tuple" , "[i for i in (2, 3, i := range(5))]" ),
@@ -167,6 +167,60 @@ def test_named_expression_invalid_comprehension_iterable_expression(self):
167
167
with self .assertRaisesRegex (SyntaxError , msg ):
168
168
exec (f"lambda: { code } " , {}) # Function scope
169
169
170
+ def test_named_expression_invalid_rebinding_set_comprehension_iteration_variable (self ):
171
+ cases = [
172
+ ("Local reuse" , 'i' , "{i := 0 for i in range(5)}" ),
173
+ ("Nested reuse" , 'j' , "{{(j := 0) for i in range(5)} for j in range(5)}" ),
174
+ ("Reuse inner loop target" , 'j' , "{(j := 0) for i in range(5) for j in range(5)}" ),
175
+ ("Unpacking reuse" , 'i' , "{i := 0 for i, j in {(0, 1)}}" ),
176
+ ("Reuse in loop condition" , 'i' , "{i+1 for i in range(5) if (i := 0)}" ),
177
+ ("Unreachable reuse" , 'i' , "{False or (i:=0) for i in range(5)}" ),
178
+ ("Unreachable nested reuse" , 'i' ,
179
+ "{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}" ),
180
+ ]
181
+ for case , target , code in cases :
182
+ msg = f"assignment expression cannot rebind comprehension iteration variable '{ target } '"
183
+ with self .subTest (case = case ):
184
+ with self .assertRaisesRegex (SyntaxError , msg ):
185
+ exec (code , {}, {})
186
+
187
+ def test_named_expression_invalid_rebinding_set_comprehension_inner_loop (self ):
188
+ cases = [
189
+ ("Inner reuse" , 'j' , "{i for i in range(5) if (j := 0) for j in range(5)}" ),
190
+ ("Inner unpacking reuse" , 'j' , "{i for i in range(5) if (j := 0) for j, k in {(0, 1)}}" ),
191
+ ]
192
+ for case , target , code in cases :
193
+ msg = f"comprehension inner loop cannot rebind assignment expression target '{ target } '"
194
+ with self .subTest (case = case ):
195
+ with self .assertRaisesRegex (SyntaxError , msg ):
196
+ exec (code , {}) # Module scope
197
+ with self .assertRaisesRegex (SyntaxError , msg ):
198
+ exec (code , {}, {}) # Class scope
199
+ with self .assertRaisesRegex (SyntaxError , msg ):
200
+ exec (f"lambda: { code } " , {}) # Function scope
201
+
202
+ def test_named_expression_invalid_set_comprehension_iterable_expression (self ):
203
+ cases = [
204
+ ("Top level" , "{i for i in (i := range(5))}" ),
205
+ ("Inside tuple" , "{i for i in (2, 3, i := range(5))}" ),
206
+ ("Inside list" , "{i for i in {2, 3, i := range(5)}}" ),
207
+ ("Different name" , "{i for i in (j := range(5))}" ),
208
+ ("Lambda expression" , "{i for i in (lambda:(j := range(5)))()}" ),
209
+ ("Inner loop" , "{i for i in range(5) for j in (i := range(5))}" ),
210
+ ("Nested comprehension" , "{i for i in {j for j in (k := range(5))}}" ),
211
+ ("Nested comprehension condition" , "{i for i in {j for j in range(5) if (j := True)}}" ),
212
+ ("Nested comprehension body" , "{i for i in {(j := True) for j in range(5)}}" ),
213
+ ]
214
+ msg = "assignment expression cannot be used in a comprehension iterable expression"
215
+ for case , code in cases :
216
+ with self .subTest (case = case ):
217
+ with self .assertRaisesRegex (SyntaxError , msg ):
218
+ exec (code , {}) # Module scope
219
+ with self .assertRaisesRegex (SyntaxError , msg ):
220
+ exec (code , {}, {}) # Class scope
221
+ with self .assertRaisesRegex (SyntaxError , msg ):
222
+ exec (f"lambda: { code } " , {}) # Function scope
223
+
170
224
171
225
class NamedExpressionAssignmentTest (unittest .TestCase ):
172
226
0 commit comments