blob: e15111cf383984853a74381fedc5ee25d28af5a0 [file] [log] [blame]
Emily Morehouse8f59ee02019-01-24 16:49:56 -07001import os
2import unittest
3
4
5class NamedExpressionInvalidTest(unittest.TestCase):
6
7 def test_named_expression_invalid_01(self):
8 code = """x := 0"""
9
10 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
11 exec(code, {}, {})
12
13 def test_named_expression_invalid_02(self):
14 code = """x = y := 0"""
15
16 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
17 exec(code, {}, {})
18
19 def test_named_expression_invalid_03(self):
20 code = """y := f(x)"""
21
22 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
23 exec(code, {}, {})
24
25 def test_named_expression_invalid_04(self):
26 code = """y0 = y1 := f(x)"""
27
28 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
29 exec(code, {}, {})
30
31 def test_named_expression_invalid_06(self):
32 code = """((a, b) := (1, 2))"""
33
34 with self.assertRaisesRegex(SyntaxError, "cannot use named assignment with tuple"):
35 exec(code, {}, {})
36
37 def test_named_expression_invalid_07(self):
38 code = """def spam(a = b := 42): pass"""
39
40 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
41 exec(code, {}, {})
42
43 def test_named_expression_invalid_08(self):
44 code = """def spam(a: b := 42 = 5): pass"""
45
46 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
47 exec(code, {}, {})
48
49 def test_named_expression_invalid_09(self):
50 code = """spam(a=b := 'c')"""
51
52 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
53 exec(code, {}, {})
54
55 def test_named_expression_invalid_10(self):
56 code = """spam(x = y := f(x))"""
57
58 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
59 exec(code, {}, {})
60
61 def test_named_expression_invalid_11(self):
62 code = """spam(a=1, b := 2)"""
63
64 with self.assertRaisesRegex(SyntaxError,
65 "positional argument follows keyword argument"):
66 exec(code, {}, {})
67
68 def test_named_expression_invalid_12(self):
69 code = """spam(a=1, (b := 2))"""
70
71 with self.assertRaisesRegex(SyntaxError,
72 "positional argument follows keyword argument"):
73 exec(code, {}, {})
74
75 def test_named_expression_invalid_13(self):
76 code = """spam(a=1, (b := 2))"""
77
78 with self.assertRaisesRegex(SyntaxError,
79 "positional argument follows keyword argument"):
80 exec(code, {}, {})
81
82 def test_named_expression_invalid_14(self):
83 code = """(x := lambda: y := 1)"""
84
85 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
86 exec(code, {}, {})
87
88 def test_named_expression_invalid_15(self):
89 code = """(lambda: x := 1)"""
90
91 with self.assertRaisesRegex(SyntaxError,
92 "cannot use named assignment with lambda"):
93 exec(code, {}, {})
94
95 def test_named_expression_invalid_16(self):
96 code = "[i + 1 for i in i := [1,2]]"
97
98 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
99 exec(code, {}, {})
100
101 def test_named_expression_invalid_17(self):
102 code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]"
103
104 with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
105 exec(code, {}, {})
106
107 def test_named_expression_invalid_18(self):
108 code = """class Foo():
109 [(42, 1 + ((( j := i )))) for i in range(5)]
110 """
111
112 with self.assertRaisesRegex(TargetScopeError,
113 "named expression within a comprehension cannot be used in a class body"):
114 exec(code, {}, {})
115
116
117class NamedExpressionAssignmentTest(unittest.TestCase):
118
119 def test_named_expression_assignment_01(self):
120 (a := 10)
121
122 self.assertEqual(a, 10)
123
124 def test_named_expression_assignment_02(self):
125 a = 20
126 (a := a)
127
128 self.assertEqual(a, 20)
129
130 def test_named_expression_assignment_03(self):
131 (total := 1 + 2)
132
133 self.assertEqual(total, 3)
134
135 def test_named_expression_assignment_04(self):
136 (info := (1, 2, 3))
137
138 self.assertEqual(info, (1, 2, 3))
139
140 def test_named_expression_assignment_05(self):
141 (x := 1, 2)
142
143 self.assertEqual(x, 1)
144
145 def test_named_expression_assignment_06(self):
146 (z := (y := (x := 0)))
147
148 self.assertEqual(x, 0)
149 self.assertEqual(y, 0)
150 self.assertEqual(z, 0)
151
152 def test_named_expression_assignment_07(self):
153 (loc := (1, 2))
154
155 self.assertEqual(loc, (1, 2))
156
157 def test_named_expression_assignment_08(self):
158 if spam := "eggs":
159 self.assertEqual(spam, "eggs")
160 else: self.fail("variable was not assigned using named expression")
161
162 def test_named_expression_assignment_09(self):
163 if True and (spam := True):
164 self.assertTrue(spam)
165 else: self.fail("variable was not assigned using named expression")
166
167 def test_named_expression_assignment_10(self):
Joannah Nanjekye075de6c2019-02-01 22:58:43 +0300168 if (match := 10) == 10:
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700169 pass
170 else: self.fail("variable was not assigned using named expression")
171
172 def test_named_expression_assignment_11(self):
173 def spam(a):
174 return a
175 input_data = [1, 2, 3]
176 res = [(x, y, x/y) for x in input_data if (y := spam(x)) > 0]
177
178 self.assertEqual(res, [(1, 1, 1.0), (2, 2, 1.0), (3, 3, 1.0)])
179
180 def test_named_expression_assignment_12(self):
181 def spam(a):
182 return a
183 res = [[y := spam(x), x/y] for x in range(1, 5)]
184
185 self.assertEqual(res, [[1, 1.0], [2, 1.0], [3, 1.0], [4, 1.0]])
186
187 def test_named_expression_assignment_13(self):
188 length = len(lines := [1, 2])
189
190 self.assertEqual(length, 2)
191 self.assertEqual(lines, [1,2])
192
193 def test_named_expression_assignment_14(self):
194 """
195 Where all variables are positive integers, and a is at least as large
196 as the n'th root of x, this algorithm returns the floor of the n'th
197 root of x (and roughly doubling the number of accurate bits per
Emily Morehouseac190812019-02-01 15:27:38 -0700198 iteration):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700199 """
200 a = 9
201 n = 2
202 x = 3
203
204 while a > (d := x // a**(n-1)):
205 a = ((n-1)*a + d) // n
206
207 self.assertEqual(a, 1)
208
Emily Morehouseac190812019-02-01 15:27:38 -0700209 def test_named_expression_assignment_15(self):
210 while a := False:
211 pass # This will not run
212
213 self.assertEqual(a, False)
214
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700215
216class NamedExpressionScopeTest(unittest.TestCase):
217
218 def test_named_expression_scope_01(self):
219 code = """def spam():
220 (a := 5)
221print(a)"""
222
223 with self.assertRaisesRegex(NameError, "name 'a' is not defined"):
224 exec(code, {}, {})
225
226 def test_named_expression_scope_02(self):
227 total = 0
228 partial_sums = [total := total + v for v in range(5)]
229
230 self.assertEqual(partial_sums, [0, 1, 3, 6, 10])
231 self.assertEqual(total, 10)
232
233 def test_named_expression_scope_03(self):
234 containsOne = any((lastNum := num) == 1 for num in [1, 2, 3])
235
236 self.assertTrue(containsOne)
237 self.assertEqual(lastNum, 1)
238
239 def test_named_expression_scope_04(self):
240 def spam(a):
241 return a
242 res = [[y := spam(x), x/y] for x in range(1, 5)]
243
244 self.assertEqual(y, 4)
245
246 def test_named_expression_scope_05(self):
247 def spam(a):
248 return a
249 input_data = [1, 2, 3]
250 res = [(x, y, x/y) for x in input_data if (y := spam(x)) > 0]
251
252 self.assertEqual(res, [(1, 1, 1.0), (2, 2, 1.0), (3, 3, 1.0)])
253 self.assertEqual(y, 3)
254
255 def test_named_expression_scope_06(self):
256 res = [[spam := i for i in range(3)] for j in range(2)]
257
258 self.assertEqual(res, [[0, 1, 2], [0, 1, 2]])
259 self.assertEqual(spam, 2)
260
261 def test_named_expression_scope_07(self):
262 len(lines := [1, 2])
263
264 self.assertEqual(lines, [1, 2])
265
266 def test_named_expression_scope_08(self):
267 def spam(a):
268 return a
269
270 def eggs(b):
271 return b * 2
272
273 res = [spam(a := eggs(b := h)) for h in range(2)]
274
275 self.assertEqual(res, [0, 2])
276 self.assertEqual(a, 2)
277 self.assertEqual(b, 1)
278
279 def test_named_expression_scope_09(self):
280 def spam(a):
281 return a
282
283 def eggs(b):
284 return b * 2
285
286 res = [spam(a := eggs(a := h)) for h in range(2)]
287
288 self.assertEqual(res, [0, 2])
289 self.assertEqual(a, 2)
290
291 def test_named_expression_scope_10(self):
292 res = [b := [a := 1 for i in range(2)] for j in range(2)]
293
294 self.assertEqual(res, [[1, 1], [1, 1]])
295 self.assertEqual(a, 1)
296 self.assertEqual(b, [1, 1])
297
298 def test_named_expression_scope_11(self):
299 res = [j := i for i in range(5)]
300
301 self.assertEqual(res, [0, 1, 2, 3, 4])
302 self.assertEqual(j, 4)
303
304 def test_named_expression_scope_12(self):
305 res = [i := i for i in range(5)]
306
307 self.assertEqual(res, [0, 1, 2, 3, 4])
308 self.assertEqual(i, 4)
309
310 def test_named_expression_scope_13(self):
311 res = [i := 0 for i, j in [(1, 2), (3, 4)]]
312
313 self.assertEqual(res, [0, 0])
314 self.assertEqual(i, 0)
315
316 def test_named_expression_scope_14(self):
317 res = [(i := 0, j := 1) for i, j in [(1, 2), (3, 4)]]
318
319 self.assertEqual(res, [(0, 1), (0, 1)])
320 self.assertEqual(i, 0)
321 self.assertEqual(j, 1)
322
323 def test_named_expression_scope_15(self):
324 res = [(i := i, j := j) for i, j in [(1, 2), (3, 4)]]
325
326 self.assertEqual(res, [(1, 2), (3, 4)])
327 self.assertEqual(i, 3)
328 self.assertEqual(j, 4)
329
330 def test_named_expression_scope_16(self):
331 res = [(i := j, j := i) for i, j in [(1, 2), (3, 4)]]
332
333 self.assertEqual(res, [(2, 2), (4, 4)])
334 self.assertEqual(i, 4)
335 self.assertEqual(j, 4)
336
337 def test_named_expression_scope_17(self):
338 b = 0
339 res = [b := i + b for i in range(5)]
340
341 self.assertEqual(res, [0, 1, 3, 6, 10])
342 self.assertEqual(b, 10)
343
344 def test_named_expression_scope_18(self):
345 def spam(a):
346 return a
347
348 res = spam(b := 2)
349
350 self.assertEqual(res, 2)
351 self.assertEqual(b, 2)
352
353 def test_named_expression_scope_19(self):
354 def spam(a):
355 return a
356
357 res = spam((b := 2))
358
359 self.assertEqual(res, 2)
360 self.assertEqual(b, 2)
361
362 def test_named_expression_scope_20(self):
363 def spam(a):
364 return a
365
366 res = spam(a=(b := 2))
367
368 self.assertEqual(res, 2)
369 self.assertEqual(b, 2)
370
371 def test_named_expression_scope_21(self):
372 def spam(a, b):
373 return a + b
374
375 res = spam(c := 2, b=1)
376
377 self.assertEqual(res, 3)
378 self.assertEqual(c, 2)
379
380 def test_named_expression_scope_22(self):
381 def spam(a, b):
382 return a + b
383
384 res = spam((c := 2), b=1)
385
386 self.assertEqual(res, 3)
387 self.assertEqual(c, 2)
388
389 def test_named_expression_scope_23(self):
390 def spam(a, b):
391 return a + b
392
393 res = spam(b=(c := 2), a=1)
394
395 self.assertEqual(res, 3)
396 self.assertEqual(c, 2)
397
398 def test_named_expression_scope_24(self):
399 a = 10
400 def spam():
401 nonlocal a
402 (a := 20)
403 spam()
404
405 self.assertEqual(a, 20)
406
407 def test_named_expression_scope_25(self):
408 ns = {}
409 code = """a = 10
410def spam():
411 global a
412 (a := 20)
413spam()"""
414
415 exec(code, ns, {})
416
417 self.assertEqual(ns["a"], 20)
418
419
420if __name__ == "__main__":
421 unittest.main()