@@ -113,7 +113,7 @@ def test_named_expression_invalid_in_class_body(self):
113113 "assignment expression within a comprehension cannot be used in a class body" ):
114114 exec (code , {}, {})
115115
116- def test_named_expression_invalid_rebinding_comprehension_iteration_variable (self ):
116+ def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable (self ):
117117 cases = [
118118 ("Local reuse" , 'i' , "[i := 0 for i in range(5)]" ),
119119 ("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
130130 with self .assertRaisesRegex (SyntaxError , msg ):
131131 exec (code , {}, {})
132132
133- def test_named_expression_invalid_rebinding_comprehension_inner_loop (self ):
133+ def test_named_expression_invalid_rebinding_list_comprehension_inner_loop (self ):
134134 cases = [
135135 ("Inner reuse" , 'j' , "[i for i in range(5) if (j := 0) for j in range(5)]" ),
136136 ("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):
145145 with self .assertRaisesRegex (SyntaxError , msg ):
146146 exec (f"lambda: { code } " , {}) # Function scope
147147
148- def test_named_expression_invalid_comprehension_iterable_expression (self ):
148+ def test_named_expression_invalid_list_comprehension_iterable_expression (self ):
149149 cases = [
150150 ("Top level" , "[i for i in (i := range(5))]" ),
151151 ("Inside tuple" , "[i for i in (2, 3, i := range(5))]" ),
@@ -167,6 +167,60 @@ def test_named_expression_invalid_comprehension_iterable_expression(self):
167167 with self .assertRaisesRegex (SyntaxError , msg ):
168168 exec (f"lambda: { code } " , {}) # Function scope
169169
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+
170224
171225class NamedExpressionAssignmentTest (unittest .TestCase ):
172226
0 commit comments