Skip to content

Commit 73cbfb2

Browse files
authored
Merge pull request RustPython#4376 from fanninpm/test-named-expressions-3.11
Update test_named_expressions.py to CPython 3.11
2 parents f97a80e + 3d903ef commit 73cbfb2

File tree

1 file changed

+97
-26
lines changed

1 file changed

+97
-26
lines changed

Lib/test/test_named_expressions.py

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,13 @@ def test_named_expression_invalid_16(self):
102102
with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
103103
exec(code, {}, {})
104104

105+
# TODO: RUSTPYTHON
106+
@unittest.expectedFailure
105107
def test_named_expression_invalid_17(self):
106108
code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]"
107109

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

111114
def test_named_expression_invalid_in_class_body(self):
@@ -119,7 +122,7 @@ def test_named_expression_invalid_in_class_body(self):
119122

120123
# TODO: RUSTPYTHON
121124
@unittest.expectedFailure # wrong error message
122-
def test_named_expression_invalid_rebinding_comprehension_iteration_variable(self):
125+
def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable(self):
123126
cases = [
124127
("Local reuse", 'i', "[i := 0 for i in range(5)]"),
125128
("Nested reuse", 'j', "[[(j := 0) for i in range(5)] for j in range(5)]"),
@@ -138,7 +141,7 @@ def test_named_expression_invalid_rebinding_comprehension_iteration_variable(sel
138141

139142
# TODO: RUSTPYTHON
140143
@unittest.expectedFailure # wrong error message
141-
def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
144+
def test_named_expression_invalid_rebinding_list_comprehension_inner_loop(self):
142145
cases = [
143146
("Inner reuse", 'j', "[i for i in range(5) if (j := 0) for j in range(5)]"),
144147
("Inner unpacking reuse", 'j', "[i for i in range(5) if (j := 0) for j, k in [(0, 1)]]"),
@@ -153,7 +156,7 @@ def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
153156
with self.assertRaisesRegex(SyntaxError, msg):
154157
exec(f"lambda: {code}", {}) # Function scope
155158

156-
def test_named_expression_invalid_comprehension_iterable_expression(self):
159+
def test_named_expression_invalid_list_comprehension_iterable_expression(self):
157160
cases = [
158161
("Top level", "[i for i in (i := range(5))]"),
159162
("Inside tuple", "[i for i in (2, 3, i := range(5))]"),
@@ -175,6 +178,64 @@ def test_named_expression_invalid_comprehension_iterable_expression(self):
175178
with self.assertRaisesRegex(SyntaxError, msg):
176179
exec(f"lambda: {code}", {}) # Function scope
177180

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

179240
class NamedExpressionAssignmentTest(unittest.TestCase):
180241

@@ -279,6 +340,29 @@ def test_named_expression_assignment_16(self):
279340
fib = {(c := a): (a := b) + (b := a + c) - b for __ in range(6)}
280341
self.assertEqual(fib, {1: 2, 2: 3, 3: 5, 5: 8, 8: 13, 13: 21})
281342

343+
# TODO: RUSTPYTHON, SyntaxError
344+
# def test_named_expression_assignment_17(self):
345+
# a = [1]
346+
# element = a[b:=0]
347+
# self.assertEqual(b, 0)
348+
# self.assertEqual(element, a[0])
349+
350+
# TODO: RUSTPYTHON, SyntaxError
351+
# def test_named_expression_assignment_18(self):
352+
# class TwoDimensionalList:
353+
# def __init__(self, two_dimensional_list):
354+
# self.two_dimensional_list = two_dimensional_list
355+
356+
# def __getitem__(self, index):
357+
# return self.two_dimensional_list[index[0]][index[1]]
358+
359+
# a = TwoDimensionalList([[1], [2]])
360+
# element = a[b:=0, c:=0]
361+
# self.assertEqual(b, 0)
362+
# self.assertEqual(c, 0)
363+
# self.assertEqual(element, a.two_dimensional_list[b][c])
364+
365+
282366

283367
class NamedExpressionScopeTest(unittest.TestCase):
284368

@@ -325,16 +409,6 @@ def test_named_expression_scope_06(self):
325409
self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
326410
self.assertEqual(spam, 2)
327411

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-
338412
def test_named_expression_scope_07(self):
339413
len(lines := [1, 2])
340414

@@ -372,18 +446,6 @@ def test_named_expression_scope_10(self):
372446
self.assertEqual(a, 1)
373447
self.assertEqual(b, [1, 1])
374448

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-
387449
def test_named_expression_scope_11(self):
388450
res = [j := i for i in range(5)]
389451

@@ -543,6 +605,15 @@ def g():
543605
self.assertEqual(nonlocal_var, None)
544606
f()
545607

608+
def test_named_expression_scope_in_genexp(self):
609+
a = 1
610+
b = [1, 2, 3, 4]
611+
genexp = (c := i + a for i in b)
612+
613+
self.assertNotIn("c", locals())
614+
for idx, elem in enumerate(genexp):
615+
self.assertEqual(elem, b[idx] + a)
616+
546617

547618
if __name__ == "__main__":
548619
unittest.main()

0 commit comments

Comments
 (0)