Skip to content

Commit 67b9300

Browse files
committed
Update test_named_expressions.py to CPython 3.11
1 parent 1d8269f commit 67b9300

File tree

1 file changed

+89
-26
lines changed

1 file changed

+89
-26
lines changed

Lib/test/test_named_expressions.py

+89-26
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def test_named_expression_invalid_16(self):
105105
def test_named_expression_invalid_17(self):
106106
code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]"
107107

108-
with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
108+
with self.assertRaisesRegex(SyntaxError,
109+
"did you forget parentheses around the comprehension target?"):
109110
exec(code, {}, {})
110111

111112
def test_named_expression_invalid_in_class_body(self):
@@ -119,7 +120,7 @@ def test_named_expression_invalid_in_class_body(self):
119120

120121
# TODO: RUSTPYTHON
121122
@unittest.expectedFailure # wrong error message
122-
def test_named_expression_invalid_rebinding_comprehension_iteration_variable(self):
123+
def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable(self):
123124
cases = [
124125
("Local reuse", 'i', "[i := 0 for i in range(5)]"),
125126
("Nested reuse", 'j', "[[(j := 0) for i in range(5)] for j in range(5)]"),
@@ -138,7 +139,7 @@ def test_named_expression_invalid_rebinding_comprehension_iteration_variable(sel
138139

139140
# TODO: RUSTPYTHON
140141
@unittest.expectedFailure # wrong error message
141-
def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
142+
def test_named_expression_invalid_rebinding_list_comprehension_inner_loop(self):
142143
cases = [
143144
("Inner reuse", 'j', "[i for i in range(5) if (j := 0) for j in range(5)]"),
144145
("Inner unpacking reuse", 'j', "[i for i in range(5) if (j := 0) for j, k in [(0, 1)]]"),
@@ -153,7 +154,7 @@ def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
153154
with self.assertRaisesRegex(SyntaxError, msg):
154155
exec(f"lambda: {code}", {}) # Function scope
155156

156-
def test_named_expression_invalid_comprehension_iterable_expression(self):
157+
def test_named_expression_invalid_list_comprehension_iterable_expression(self):
157158
cases = [
158159
("Top level", "[i for i in (i := range(5))]"),
159160
("Inside tuple", "[i for i in (2, 3, i := range(5))]"),
@@ -175,6 +176,60 @@ def test_named_expression_invalid_comprehension_iterable_expression(self):
175176
with self.assertRaisesRegex(SyntaxError, msg):
176177
exec(f"lambda: {code}", {}) # Function scope
177178

179+
def test_named_expression_invalid_rebinding_set_comprehension_iteration_variable(self):
180+
cases = [
181+
("Local reuse", 'i', "{i := 0 for i in range(5)}"),
182+
("Nested reuse", 'j', "{{(j := 0) for i in range(5)} for j in range(5)}"),
183+
("Reuse inner loop target", 'j', "{(j := 0) for i in range(5) for j in range(5)}"),
184+
("Unpacking reuse", 'i', "{i := 0 for i, j in {(0, 1)}}"),
185+
("Reuse in loop condition", 'i', "{i+1 for i in range(5) if (i := 0)}"),
186+
("Unreachable reuse", 'i', "{False or (i:=0) for i in range(5)}"),
187+
("Unreachable nested reuse", 'i',
188+
"{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}"),
189+
]
190+
for case, target, code in cases:
191+
msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'"
192+
with self.subTest(case=case):
193+
with self.assertRaisesRegex(SyntaxError, msg):
194+
exec(code, {}, {})
195+
196+
def test_named_expression_invalid_rebinding_set_comprehension_inner_loop(self):
197+
cases = [
198+
("Inner reuse", 'j', "{i for i in range(5) if (j := 0) for j in range(5)}"),
199+
("Inner unpacking reuse", 'j', "{i for i in range(5) if (j := 0) for j, k in {(0, 1)}}"),
200+
]
201+
for case, target, code in cases:
202+
msg = f"comprehension inner loop cannot rebind assignment expression target '{target}'"
203+
with self.subTest(case=case):
204+
with self.assertRaisesRegex(SyntaxError, msg):
205+
exec(code, {}) # Module scope
206+
with self.assertRaisesRegex(SyntaxError, msg):
207+
exec(code, {}, {}) # Class scope
208+
with self.assertRaisesRegex(SyntaxError, msg):
209+
exec(f"lambda: {code}", {}) # Function scope
210+
211+
def test_named_expression_invalid_set_comprehension_iterable_expression(self):
212+
cases = [
213+
("Top level", "{i for i in (i := range(5))}"),
214+
("Inside tuple", "{i for i in (2, 3, i := range(5))}"),
215+
("Inside list", "{i for i in {2, 3, i := range(5)}}"),
216+
("Different name", "{i for i in (j := range(5))}"),
217+
("Lambda expression", "{i for i in (lambda:(j := range(5)))()}"),
218+
("Inner loop", "{i for i in range(5) for j in (i := range(5))}"),
219+
("Nested comprehension", "{i for i in {j for j in (k := range(5))}}"),
220+
("Nested comprehension condition", "{i for i in {j for j in range(5) if (j := True)}}"),
221+
("Nested comprehension body", "{i for i in {(j := True) for j in range(5)}}"),
222+
]
223+
msg = "assignment expression cannot be used in a comprehension iterable expression"
224+
for case, code in cases:
225+
with self.subTest(case=case):
226+
with self.assertRaisesRegex(SyntaxError, msg):
227+
exec(code, {}) # Module scope
228+
with self.assertRaisesRegex(SyntaxError, msg):
229+
exec(code, {}, {}) # Class scope
230+
with self.assertRaisesRegex(SyntaxError, msg):
231+
exec(f"lambda: {code}", {}) # Function scope
232+
178233

179234
class NamedExpressionAssignmentTest(unittest.TestCase):
180235

@@ -279,6 +334,27 @@ def test_named_expression_assignment_16(self):
279334
fib = {(c := a): (a := b) + (b := a + c) - b for __ in range(6)}
280335
self.assertEqual(fib, {1: 2, 2: 3, 3: 5, 5: 8, 8: 13, 13: 21})
281336

337+
def test_named_expression_assignment_17(self):
338+
a = [1]
339+
element = a[b:=0]
340+
self.assertEqual(b, 0)
341+
self.assertEqual(element, a[0])
342+
343+
def test_named_expression_assignment_18(self):
344+
class TwoDimensionalList:
345+
def __init__(self, two_dimensional_list):
346+
self.two_dimensional_list = two_dimensional_list
347+
348+
def __getitem__(self, index):
349+
return self.two_dimensional_list[index[0]][index[1]]
350+
351+
a = TwoDimensionalList([[1], [2]])
352+
element = a[b:=0, c:=0]
353+
self.assertEqual(b, 0)
354+
self.assertEqual(c, 0)
355+
self.assertEqual(element, a.two_dimensional_list[b][c])
356+
357+
282358

283359
class NamedExpressionScopeTest(unittest.TestCase):
284360

@@ -325,16 +401,6 @@ def test_named_expression_scope_06(self):
325401
self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
326402
self.assertEqual(spam, 2)
327403

328-
# modified version of test_named_expression_scope_6, where locals
329-
# assigned before to make them known in scop. THis is required due
330-
# to some shortcommings in RPs name handling.
331-
def test_named_expression_scope_06_rp_modified(self):
332-
spam=0
333-
res = [[spam := i for i in range(3)] for j in range(2)]
334-
335-
self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
336-
self.assertEqual(spam, 2)
337-
338404
def test_named_expression_scope_07(self):
339405
len(lines := [1, 2])
340406

@@ -372,18 +438,6 @@ def test_named_expression_scope_10(self):
372438
self.assertEqual(a, 1)
373439
self.assertEqual(b, [1, 1])
374440

375-
# modified version of test_named_expression_scope_10, where locals
376-
# assigned before to make them known in scop. THis is required due
377-
# to some shortcommings in RPs name handling.
378-
def test_named_expression_scope_10_rp_modified(self):
379-
a=0
380-
b=0
381-
res = [b := [a := 1 for i in range(2)] for j in range(2)]
382-
383-
self.assertEqual(res, [[1, 1], [1, 1]])
384-
self.assertEqual(b, [1, 1])
385-
self.assertEqual(a, 1)
386-
387441
def test_named_expression_scope_11(self):
388442
res = [j := i for i in range(5)]
389443

@@ -543,6 +597,15 @@ def g():
543597
self.assertEqual(nonlocal_var, None)
544598
f()
545599

600+
def test_named_expression_scope_in_genexp(self):
601+
a = 1
602+
b = [1, 2, 3, 4]
603+
genexp = (c := i + a for i in b)
604+
605+
self.assertNotIn("c", locals())
606+
for idx, elem in enumerate(genexp):
607+
self.assertEqual(elem, b[idx] + a)
608+
546609

547610
if __name__ == "__main__":
548611
unittest.main()

0 commit comments

Comments
 (0)