Skip to content

Commit 57289ff

Browse files
authored
Merge pull request RustPython#1964 from TheAnyKey/TheAnyKey/p38_named_expression_completion_step2
Py3.8 Named expression completion - error handling and scoping
2 parents 11a6635 + d17fcc4 commit 57289ff

File tree

3 files changed

+217
-77
lines changed

3 files changed

+217
-77
lines changed

Lib/test/test_named_expression.py

Lines changed: 83 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,136 @@
11
import unittest
22

3-
#This test is only applicable for Python 3.8 and later
4-
53
GLOBAL_VAR = None
64

75
class NamedExpressionInvalidTest(unittest.TestCase):
86

97
def test_named_expression_invalid_01(self):
108
code = """x := 0"""
119

12-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
13-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
10+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
11+
with self.assertRaises(SyntaxError):
1412
exec(code, {}, {})
1513

1614
def test_named_expression_invalid_02(self):
1715
code = """x = y := 0"""
1816

19-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
20-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
17+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
18+
with self.assertRaises(SyntaxError):
2119
exec(code, {}, {})
2220

2321
def test_named_expression_invalid_03(self):
2422
code = """y := f(x)"""
2523

26-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
27-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
24+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
25+
with self.assertRaises(SyntaxError):
26+
2827
exec(code, {}, {})
2928

3029
def test_named_expression_invalid_04(self):
3130
code = """y0 = y1 := f(x)"""
3231

33-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
34-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
32+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
33+
with self.assertRaises(SyntaxError):
3534
exec(code, {}, {})
3635

3736
def test_named_expression_invalid_06(self):
3837
code = """((a, b) := (1, 2))"""
3938

40-
#with self.assertRaisesRegex(SyntaxError, "cannot use assignment expressions with tuple"):
41-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
39+
#with self.assertRaisesRegex(SyntaxError, "cannot use assignment expressions with tuple"): # TODO RustPython
40+
with self.assertRaises(SyntaxError):
4241
exec(code, {}, {})
4342

4443
def test_named_expression_invalid_07(self):
4544
code = """def spam(a = b := 42): pass"""
4645

47-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
48-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
46+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
47+
with self.assertRaises(SyntaxError):
4948
exec(code, {}, {})
5049

5150
def test_named_expression_invalid_08(self):
5251
code = """def spam(a: b := 42 = 5): pass"""
5352

54-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
55-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
53+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
54+
with self.assertRaises(SyntaxError):
5655
exec(code, {}, {})
5756

5857
def test_named_expression_invalid_09(self):
5958
code = """spam(a=b := 'c')"""
60-
61-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
62-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
59+
60+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
61+
with self.assertRaises(SyntaxError):
6362
exec(code, {}, {})
6463

6564
def test_named_expression_invalid_10(self):
6665
code = """spam(x = y := f(x))"""
6766

68-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
69-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
67+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
68+
with self.assertRaises(SyntaxError):
7069
exec(code, {}, {})
7170

7271
def test_named_expression_invalid_11(self):
7372
code = """spam(a=1, b := 2)"""
7473

7574
#with self.assertRaisesRegex(SyntaxError,
76-
# "positional argument follows keyword argument"):
77-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
75+
# "positional argument follows keyword argument"): # TODO RustPython
76+
with self.assertRaises(SyntaxError):
7877
exec(code, {}, {})
7978

8079
def test_named_expression_invalid_12(self):
8180
code = """spam(a=1, (b := 2))"""
8281

8382
#with self.assertRaisesRegex(SyntaxError,
84-
# "positional argument follows keyword argument"):
85-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
83+
# "positional argument follows keyword argument"): # TODO RustPython
84+
with self.assertRaises(SyntaxError):
8685
exec(code, {}, {})
8786

8887
def test_named_expression_invalid_13(self):
8988
code = """spam(a=1, (b := 2))"""
9089

9190
#with self.assertRaisesRegex(SyntaxError,
92-
# "positional argument follows keyword argument"):
93-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
91+
# "positional argument follows keyword argument"): # TODO RustPython
92+
with self.assertRaises(SyntaxError):
9493
exec(code, {}, {})
9594

9695
def test_named_expression_invalid_14(self):
9796
code = """(x := lambda: y := 1)"""
9897

99-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
100-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
98+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
99+
with self.assertRaises(SyntaxError):
101100
exec(code, {}, {})
102101

103102
def test_named_expression_invalid_15(self):
104103
code = """(lambda: x := 1)"""
105104

106105
#with self.assertRaisesRegex(SyntaxError,
107-
# "cannot use assignment expressions with lambda"):
108-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
106+
# "cannot use assignment expressions with lambda"): # TODO RustPython
107+
with self.assertRaises(SyntaxError):
109108
exec(code, {}, {})
110109

111110
def test_named_expression_invalid_16(self):
112111
code = "[i + 1 for i in i := [1,2]]"
113112

114-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
115-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
113+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
114+
with self.assertRaises(SyntaxError):
116115
exec(code, {}, {})
117116

118117
def test_named_expression_invalid_17(self):
119118
code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]"
120119

121-
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
122-
with self.assertRaises(SyntaxError): # TODO: RUSTPYTHON
120+
#with self.assertRaisesRegex(SyntaxError, "invalid syntax"): # TODO RustPython
121+
with self.assertRaises(SyntaxError):
123122
exec(code, {}, {})
124123

125-
@unittest.expectedFailure # TODO: RUSTPYTHON
126124
def test_named_expression_invalid_in_class_body(self):
127125
code = """class Foo():
128126
[(42, 1 + ((( j := i )))) for i in range(5)]
129127
"""
130128

131-
with self.assertRaisesRegex(SyntaxError,
132-
"assignment expression within a comprehension cannot be used in a class body"):
129+
#with self.assertRaisesRegex(SyntaxError,
130+
# "assignment expression within a comprehension cannot be used in a class body"): # TODO RustPython
131+
with self.assertRaises(SyntaxError):
133132
exec(code, {}, {})
134133

135-
@unittest.expectedFailure # TODO: RUSTPYTHON
136134
def test_named_expression_invalid_rebinding_comprehension_iteration_variable(self):
137135
cases = [
138136
("Local reuse", 'i', "[i := 0 for i in range(5)]"),
@@ -145,28 +143,30 @@ def test_named_expression_invalid_rebinding_comprehension_iteration_variable(sel
145143
"[(i, j) for i in range(5) for j in range(5) if True or (i:=10)]"),
146144
]
147145
for case, target, code in cases:
148-
msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'"
146+
#msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'"
149147
with self.subTest(case=case):
148+
#with self.assertRaisesRegex(SyntaxError, msg): #TODO RustPython
150149
with self.assertRaises(SyntaxError):
151150
exec(code, {}, {})
152151

153-
@unittest.expectedFailure # TODO: RUSTPYTHON
154152
def test_named_expression_invalid_rebinding_comprehension_inner_loop(self):
155153
cases = [
156154
("Inner reuse", 'j', "[i for i in range(5) if (j := 0) for j in range(5)]"),
157155
("Inner unpacking reuse", 'j', "[i for i in range(5) if (j := 0) for j, k in [(0, 1)]]"),
158156
]
159157
for case, target, code in cases:
160-
msg = f"comprehension inner loop cannot rebind assignment expression target '{target}'"
158+
#msg = f"comprehension inner loop cannot rebind assignment expression target '{target}'"
161159
with self.subTest(case=case):
162-
with self.assertRaisesRegex(SyntaxError, msg):
160+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
161+
with self.assertRaises(SyntaxError):
163162
exec(code, {}) # Module scope
164-
with self.assertRaisesRegex(SyntaxError, msg):
163+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
164+
with self.assertRaises(SyntaxError):
165165
exec(code, {}, {}) # Class scope
166-
with self.assertRaisesRegex(SyntaxError, msg):
166+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
167+
with self.assertRaises(SyntaxError):
167168
exec(f"lambda: {code}", {}) # Function scope
168169

169-
@unittest.expectedFailure # TODO: RUSTPYTHON
170170
def test_named_expression_invalid_comprehension_iterable_expression(self):
171171
cases = [
172172
("Top level", "[i for i in (i := range(5))]"),
@@ -179,14 +179,17 @@ def test_named_expression_invalid_comprehension_iterable_expression(self):
179179
("Nested comprehension condition", "[i for i in [j for j in range(5) if (j := True)]]"),
180180
("Nested comprehension body", "[i for i in [(j := True) for j in range(5)]]"),
181181
]
182-
msg = "assignment expression cannot be used in a comprehension iterable expression"
182+
#msg = "assignment expression cannot be used in a comprehension iterable expression"
183183
for case, code in cases:
184184
with self.subTest(case=case):
185-
with self.assertRaisesRegex(SyntaxError, msg):
185+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
186+
with self.assertRaises(SyntaxError):
186187
exec(code, {}) # Module scope
187-
with self.assertRaisesRegex(SyntaxError, msg):
188+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
189+
with self.assertRaises(SyntaxError):
188190
exec(code, {}, {}) # Class scope
189-
with self.assertRaisesRegex(SyntaxError, msg):
191+
#with self.assertRaisesRegex(SyntaxError, msg): # TODO RustPython
192+
with self.assertRaises(SyntaxError):
190193
exec(f"lambda: {code}", {}) # Function scope
191194

192195

@@ -199,9 +202,9 @@ def test_named_expression_assignment_01(self):
199202

200203
def test_named_expression_assignment_02(self):
201204
a = 20
202-
(a := a+10)
205+
(a := a)
203206

204-
self.assertEqual(a, 30)
207+
self.assertEqual(a, 20)
205208

206209
def test_named_expression_assignment_03(self):
207210
(total := 1 + 2)
@@ -320,20 +323,10 @@ def test_named_expression_scope_03(self):
320323
def test_named_expression_scope_04(self):
321324
def spam(a):
322325
return a
323-
324-
y=1
325326
res = [[y := spam(x), x/y] for x in range(1, 5)]
326327

327328
self.assertEqual(y, 4)
328329

329-
def test_named_expression_scope_04a(self):
330-
def spam(a):
331-
return a
332-
y=1
333-
res = [y := spam(x//y) for x in range(1, 5)]
334-
335-
self.assertEqual(y, 4)
336-
337330
def test_named_expression_scope_05(self):
338331
def spam(a):
339332
return a
@@ -343,14 +336,25 @@ def spam(a):
343336
self.assertEqual(res, [(1, 1, 1.0), (2, 2, 1.0), (3, 3, 1.0)])
344337
self.assertEqual(y, 3)
345338

346-
# TODO: RUSTPYTHON,
347-
@unittest.expectedFailure # TODO: RUSTPYTHON
339+
# TODO RustPython, added test_named_expression_scope_06_rp_modified as
340+
# minimaly modified variant of this test.
341+
@unittest.expectedFailure
348342
def test_named_expression_scope_06(self):
349343
res = [[spam := i for i in range(3)] for j in range(2)]
350344

351345
self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
352346
self.assertEqual(spam, 2)
353347

348+
# modified version of test_named_expression_scope_6, where locals
349+
# assigned before to make them known in scop. THis is required due
350+
# to some shortcommings in RPs name handling.
351+
def test_named_expression_scope_06_rp_modified(self):
352+
spam=0
353+
res = [[spam := i for i in range(3)] for j in range(2)]
354+
355+
self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
356+
self.assertEqual(spam, 2)
357+
354358
def test_named_expression_scope_07(self):
355359
len(lines := [1, 2])
356360

@@ -381,11 +385,23 @@ def eggs(b):
381385
self.assertEqual(res, [0, 2])
382386
self.assertEqual(a, 2)
383387

384-
# TODO: RUSTPYTHON,
388+
# TODO RustPython, added test_named_expression_scope_10_rp_modified
385389
@unittest.expectedFailure
386390
def test_named_expression_scope_10(self):
387391
res = [b := [a := 1 for i in range(2)] for j in range(2)]
388392

393+
self.assertEqual(res, [[1, 1], [1, 1]])
394+
self.assertEqual(a, 1)
395+
self.assertEqual(b, [1, 1])
396+
397+
# modified version of test_named_expression_scope_10, where locals
398+
# assigned before to make them known in scop. THis is required due
399+
# to some shortcommings in RPs name handling.
400+
def test_named_expression_scope_10_rp_modified(self):
401+
a=0
402+
b=0
403+
res = [b := [a := 1 for i in range(2)] for j in range(2)]
404+
389405
self.assertEqual(res, [[1, 1], [1, 1]])
390406
self.assertEqual(b, [1, 1])
391407
self.assertEqual(a, 1)
@@ -395,7 +411,7 @@ def test_named_expression_scope_11(self):
395411

396412
self.assertEqual(res, [0, 1, 2, 3, 4])
397413
self.assertEqual(j, 4)
398-
414+
399415
def test_named_expression_scope_17(self):
400416
b = 0
401417
res = [b := i + b for i in range(5)]
@@ -552,4 +568,4 @@ def g():
552568

553569

554570
if __name__ == "__main__":
555-
unittest.main()
571+
unittest.main()

0 commit comments

Comments
 (0)