17db96d56Sopenharmony_ciimport unittest 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciGLOBAL_VAR = None 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciclass NamedExpressionInvalidTest(unittest.TestCase): 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci def test_named_expression_invalid_01(self): 87db96d56Sopenharmony_ci code = """x := 0""" 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 117db96d56Sopenharmony_ci exec(code, {}, {}) 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci def test_named_expression_invalid_02(self): 147db96d56Sopenharmony_ci code = """x = y := 0""" 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 177db96d56Sopenharmony_ci exec(code, {}, {}) 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci def test_named_expression_invalid_03(self): 207db96d56Sopenharmony_ci code = """y := f(x)""" 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 237db96d56Sopenharmony_ci exec(code, {}, {}) 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci def test_named_expression_invalid_04(self): 267db96d56Sopenharmony_ci code = """y0 = y1 := f(x)""" 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 297db96d56Sopenharmony_ci exec(code, {}, {}) 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci def test_named_expression_invalid_06(self): 327db96d56Sopenharmony_ci code = """((a, b) := (1, 2))""" 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "cannot use assignment expressions with tuple"): 357db96d56Sopenharmony_ci exec(code, {}, {}) 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci def test_named_expression_invalid_07(self): 387db96d56Sopenharmony_ci code = """def spam(a = b := 42): pass""" 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 417db96d56Sopenharmony_ci exec(code, {}, {}) 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci def test_named_expression_invalid_08(self): 447db96d56Sopenharmony_ci code = """def spam(a: b := 42 = 5): pass""" 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 477db96d56Sopenharmony_ci exec(code, {}, {}) 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci def test_named_expression_invalid_09(self): 507db96d56Sopenharmony_ci code = """spam(a=b := 'c')""" 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 537db96d56Sopenharmony_ci exec(code, {}, {}) 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci def test_named_expression_invalid_10(self): 567db96d56Sopenharmony_ci code = """spam(x = y := f(x))""" 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 597db96d56Sopenharmony_ci exec(code, {}, {}) 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci def test_named_expression_invalid_11(self): 627db96d56Sopenharmony_ci code = """spam(a=1, b := 2)""" 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 657db96d56Sopenharmony_ci "positional argument follows keyword argument"): 667db96d56Sopenharmony_ci exec(code, {}, {}) 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci def test_named_expression_invalid_12(self): 697db96d56Sopenharmony_ci code = """spam(a=1, (b := 2))""" 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 727db96d56Sopenharmony_ci "positional argument follows keyword argument"): 737db96d56Sopenharmony_ci exec(code, {}, {}) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci def test_named_expression_invalid_13(self): 767db96d56Sopenharmony_ci code = """spam(a=1, (b := 2))""" 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 797db96d56Sopenharmony_ci "positional argument follows keyword argument"): 807db96d56Sopenharmony_ci exec(code, {}, {}) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci def test_named_expression_invalid_14(self): 837db96d56Sopenharmony_ci code = """(x := lambda: y := 1)""" 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 867db96d56Sopenharmony_ci exec(code, {}, {}) 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci def test_named_expression_invalid_15(self): 897db96d56Sopenharmony_ci code = """(lambda: x := 1)""" 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 927db96d56Sopenharmony_ci "cannot use assignment expressions with lambda"): 937db96d56Sopenharmony_ci exec(code, {}, {}) 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci def test_named_expression_invalid_16(self): 967db96d56Sopenharmony_ci code = "[i + 1 for i in i := [1,2]]" 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, "invalid syntax"): 997db96d56Sopenharmony_ci exec(code, {}, {}) 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci def test_named_expression_invalid_17(self): 1027db96d56Sopenharmony_ci code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]" 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 1057db96d56Sopenharmony_ci "did you forget parentheses around the comprehension target?"): 1067db96d56Sopenharmony_ci exec(code, {}, {}) 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci def test_named_expression_invalid_in_class_body(self): 1097db96d56Sopenharmony_ci code = """class Foo(): 1107db96d56Sopenharmony_ci [(42, 1 + ((( j := i )))) for i in range(5)] 1117db96d56Sopenharmony_ci """ 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, 1147db96d56Sopenharmony_ci "assignment expression within a comprehension cannot be used in a class body"): 1157db96d56Sopenharmony_ci exec(code, {}, {}) 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable(self): 1187db96d56Sopenharmony_ci cases = [ 1197db96d56Sopenharmony_ci ("Local reuse", 'i', "[i := 0 for i in range(5)]"), 1207db96d56Sopenharmony_ci ("Nested reuse", 'j', "[[(j := 0) for i in range(5)] for j in range(5)]"), 1217db96d56Sopenharmony_ci ("Reuse inner loop target", 'j', "[(j := 0) for i in range(5) for j in range(5)]"), 1227db96d56Sopenharmony_ci ("Unpacking reuse", 'i', "[i := 0 for i, j in [(0, 1)]]"), 1237db96d56Sopenharmony_ci ("Reuse in loop condition", 'i', "[i+1 for i in range(5) if (i := 0)]"), 1247db96d56Sopenharmony_ci ("Unreachable reuse", 'i', "[False or (i:=0) for i in range(5)]"), 1257db96d56Sopenharmony_ci ("Unreachable nested reuse", 'i', 1267db96d56Sopenharmony_ci "[(i, j) for i in range(5) for j in range(5) if True or (i:=10)]"), 1277db96d56Sopenharmony_ci ] 1287db96d56Sopenharmony_ci for case, target, code in cases: 1297db96d56Sopenharmony_ci msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" 1307db96d56Sopenharmony_ci with self.subTest(case=case): 1317db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1327db96d56Sopenharmony_ci exec(code, {}, {}) 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci def test_named_expression_invalid_rebinding_list_comprehension_inner_loop(self): 1357db96d56Sopenharmony_ci cases = [ 1367db96d56Sopenharmony_ci ("Inner reuse", 'j', "[i for i in range(5) if (j := 0) for j in range(5)]"), 1377db96d56Sopenharmony_ci ("Inner unpacking reuse", 'j', "[i for i in range(5) if (j := 0) for j, k in [(0, 1)]]"), 1387db96d56Sopenharmony_ci ] 1397db96d56Sopenharmony_ci for case, target, code in cases: 1407db96d56Sopenharmony_ci msg = f"comprehension inner loop cannot rebind assignment expression target '{target}'" 1417db96d56Sopenharmony_ci with self.subTest(case=case): 1427db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1437db96d56Sopenharmony_ci exec(code, {}) # Module scope 1447db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1457db96d56Sopenharmony_ci exec(code, {}, {}) # Class scope 1467db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1477db96d56Sopenharmony_ci exec(f"lambda: {code}", {}) # Function scope 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci def test_named_expression_invalid_list_comprehension_iterable_expression(self): 1507db96d56Sopenharmony_ci cases = [ 1517db96d56Sopenharmony_ci ("Top level", "[i for i in (i := range(5))]"), 1527db96d56Sopenharmony_ci ("Inside tuple", "[i for i in (2, 3, i := range(5))]"), 1537db96d56Sopenharmony_ci ("Inside list", "[i for i in [2, 3, i := range(5)]]"), 1547db96d56Sopenharmony_ci ("Different name", "[i for i in (j := range(5))]"), 1557db96d56Sopenharmony_ci ("Lambda expression", "[i for i in (lambda:(j := range(5)))()]"), 1567db96d56Sopenharmony_ci ("Inner loop", "[i for i in range(5) for j in (i := range(5))]"), 1577db96d56Sopenharmony_ci ("Nested comprehension", "[i for i in [j for j in (k := range(5))]]"), 1587db96d56Sopenharmony_ci ("Nested comprehension condition", "[i for i in [j for j in range(5) if (j := True)]]"), 1597db96d56Sopenharmony_ci ("Nested comprehension body", "[i for i in [(j := True) for j in range(5)]]"), 1607db96d56Sopenharmony_ci ] 1617db96d56Sopenharmony_ci msg = "assignment expression cannot be used in a comprehension iterable expression" 1627db96d56Sopenharmony_ci for case, code in cases: 1637db96d56Sopenharmony_ci with self.subTest(case=case): 1647db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1657db96d56Sopenharmony_ci exec(code, {}) # Module scope 1667db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1677db96d56Sopenharmony_ci exec(code, {}, {}) # Class scope 1687db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1697db96d56Sopenharmony_ci exec(f"lambda: {code}", {}) # Function scope 1707db96d56Sopenharmony_ci 1717db96d56Sopenharmony_ci def test_named_expression_invalid_rebinding_set_comprehension_iteration_variable(self): 1727db96d56Sopenharmony_ci cases = [ 1737db96d56Sopenharmony_ci ("Local reuse", 'i', "{i := 0 for i in range(5)}"), 1747db96d56Sopenharmony_ci ("Nested reuse", 'j', "{{(j := 0) for i in range(5)} for j in range(5)}"), 1757db96d56Sopenharmony_ci ("Reuse inner loop target", 'j', "{(j := 0) for i in range(5) for j in range(5)}"), 1767db96d56Sopenharmony_ci ("Unpacking reuse", 'i', "{i := 0 for i, j in {(0, 1)}}"), 1777db96d56Sopenharmony_ci ("Reuse in loop condition", 'i', "{i+1 for i in range(5) if (i := 0)}"), 1787db96d56Sopenharmony_ci ("Unreachable reuse", 'i', "{False or (i:=0) for i in range(5)}"), 1797db96d56Sopenharmony_ci ("Unreachable nested reuse", 'i', 1807db96d56Sopenharmony_ci "{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}"), 1817db96d56Sopenharmony_ci ] 1827db96d56Sopenharmony_ci for case, target, code in cases: 1837db96d56Sopenharmony_ci msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" 1847db96d56Sopenharmony_ci with self.subTest(case=case): 1857db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1867db96d56Sopenharmony_ci exec(code, {}, {}) 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci def test_named_expression_invalid_rebinding_set_comprehension_inner_loop(self): 1897db96d56Sopenharmony_ci cases = [ 1907db96d56Sopenharmony_ci ("Inner reuse", 'j', "{i for i in range(5) if (j := 0) for j in range(5)}"), 1917db96d56Sopenharmony_ci ("Inner unpacking reuse", 'j', "{i for i in range(5) if (j := 0) for j, k in {(0, 1)}}"), 1927db96d56Sopenharmony_ci ] 1937db96d56Sopenharmony_ci for case, target, code in cases: 1947db96d56Sopenharmony_ci msg = f"comprehension inner loop cannot rebind assignment expression target '{target}'" 1957db96d56Sopenharmony_ci with self.subTest(case=case): 1967db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1977db96d56Sopenharmony_ci exec(code, {}) # Module scope 1987db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 1997db96d56Sopenharmony_ci exec(code, {}, {}) # Class scope 2007db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 2017db96d56Sopenharmony_ci exec(f"lambda: {code}", {}) # Function scope 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci def test_named_expression_invalid_set_comprehension_iterable_expression(self): 2047db96d56Sopenharmony_ci cases = [ 2057db96d56Sopenharmony_ci ("Top level", "{i for i in (i := range(5))}"), 2067db96d56Sopenharmony_ci ("Inside tuple", "{i for i in (2, 3, i := range(5))}"), 2077db96d56Sopenharmony_ci ("Inside list", "{i for i in {2, 3, i := range(5)}}"), 2087db96d56Sopenharmony_ci ("Different name", "{i for i in (j := range(5))}"), 2097db96d56Sopenharmony_ci ("Lambda expression", "{i for i in (lambda:(j := range(5)))()}"), 2107db96d56Sopenharmony_ci ("Inner loop", "{i for i in range(5) for j in (i := range(5))}"), 2117db96d56Sopenharmony_ci ("Nested comprehension", "{i for i in {j for j in (k := range(5))}}"), 2127db96d56Sopenharmony_ci ("Nested comprehension condition", "{i for i in {j for j in range(5) if (j := True)}}"), 2137db96d56Sopenharmony_ci ("Nested comprehension body", "{i for i in {(j := True) for j in range(5)}}"), 2147db96d56Sopenharmony_ci ] 2157db96d56Sopenharmony_ci msg = "assignment expression cannot be used in a comprehension iterable expression" 2167db96d56Sopenharmony_ci for case, code in cases: 2177db96d56Sopenharmony_ci with self.subTest(case=case): 2187db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 2197db96d56Sopenharmony_ci exec(code, {}) # Module scope 2207db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 2217db96d56Sopenharmony_ci exec(code, {}, {}) # Class scope 2227db96d56Sopenharmony_ci with self.assertRaisesRegex(SyntaxError, msg): 2237db96d56Sopenharmony_ci exec(f"lambda: {code}", {}) # Function scope 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ciclass NamedExpressionAssignmentTest(unittest.TestCase): 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci def test_named_expression_assignment_01(self): 2297db96d56Sopenharmony_ci (a := 10) 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci self.assertEqual(a, 10) 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci def test_named_expression_assignment_02(self): 2347db96d56Sopenharmony_ci a = 20 2357db96d56Sopenharmony_ci (a := a) 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci self.assertEqual(a, 20) 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci def test_named_expression_assignment_03(self): 2407db96d56Sopenharmony_ci (total := 1 + 2) 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci self.assertEqual(total, 3) 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci def test_named_expression_assignment_04(self): 2457db96d56Sopenharmony_ci (info := (1, 2, 3)) 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_ci self.assertEqual(info, (1, 2, 3)) 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci def test_named_expression_assignment_05(self): 2507db96d56Sopenharmony_ci (x := 1, 2) 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci self.assertEqual(x, 1) 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci def test_named_expression_assignment_06(self): 2557db96d56Sopenharmony_ci (z := (y := (x := 0))) 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci self.assertEqual(x, 0) 2587db96d56Sopenharmony_ci self.assertEqual(y, 0) 2597db96d56Sopenharmony_ci self.assertEqual(z, 0) 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci def test_named_expression_assignment_07(self): 2627db96d56Sopenharmony_ci (loc := (1, 2)) 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_ci self.assertEqual(loc, (1, 2)) 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci def test_named_expression_assignment_08(self): 2677db96d56Sopenharmony_ci if spam := "eggs": 2687db96d56Sopenharmony_ci self.assertEqual(spam, "eggs") 2697db96d56Sopenharmony_ci else: self.fail("variable was not assigned using named expression") 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci def test_named_expression_assignment_09(self): 2727db96d56Sopenharmony_ci if True and (spam := True): 2737db96d56Sopenharmony_ci self.assertTrue(spam) 2747db96d56Sopenharmony_ci else: self.fail("variable was not assigned using named expression") 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci def test_named_expression_assignment_10(self): 2777db96d56Sopenharmony_ci if (match := 10) == 10: 2787db96d56Sopenharmony_ci pass 2797db96d56Sopenharmony_ci else: self.fail("variable was not assigned using named expression") 2807db96d56Sopenharmony_ci 2817db96d56Sopenharmony_ci def test_named_expression_assignment_11(self): 2827db96d56Sopenharmony_ci def spam(a): 2837db96d56Sopenharmony_ci return a 2847db96d56Sopenharmony_ci input_data = [1, 2, 3] 2857db96d56Sopenharmony_ci res = [(x, y, x/y) for x in input_data if (y := spam(x)) > 0] 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci self.assertEqual(res, [(1, 1, 1.0), (2, 2, 1.0), (3, 3, 1.0)]) 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci def test_named_expression_assignment_12(self): 2907db96d56Sopenharmony_ci def spam(a): 2917db96d56Sopenharmony_ci return a 2927db96d56Sopenharmony_ci res = [[y := spam(x), x/y] for x in range(1, 5)] 2937db96d56Sopenharmony_ci 2947db96d56Sopenharmony_ci self.assertEqual(res, [[1, 1.0], [2, 1.0], [3, 1.0], [4, 1.0]]) 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci def test_named_expression_assignment_13(self): 2977db96d56Sopenharmony_ci length = len(lines := [1, 2]) 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci self.assertEqual(length, 2) 3007db96d56Sopenharmony_ci self.assertEqual(lines, [1,2]) 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ci def test_named_expression_assignment_14(self): 3037db96d56Sopenharmony_ci """ 3047db96d56Sopenharmony_ci Where all variables are positive integers, and a is at least as large 3057db96d56Sopenharmony_ci as the n'th root of x, this algorithm returns the floor of the n'th 3067db96d56Sopenharmony_ci root of x (and roughly doubling the number of accurate bits per 3077db96d56Sopenharmony_ci iteration): 3087db96d56Sopenharmony_ci """ 3097db96d56Sopenharmony_ci a = 9 3107db96d56Sopenharmony_ci n = 2 3117db96d56Sopenharmony_ci x = 3 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci while a > (d := x // a**(n-1)): 3147db96d56Sopenharmony_ci a = ((n-1)*a + d) // n 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci self.assertEqual(a, 1) 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci def test_named_expression_assignment_15(self): 3197db96d56Sopenharmony_ci while a := False: 3207db96d56Sopenharmony_ci pass # This will not run 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci self.assertEqual(a, False) 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ci def test_named_expression_assignment_16(self): 3257db96d56Sopenharmony_ci a, b = 1, 2 3267db96d56Sopenharmony_ci fib = {(c := a): (a := b) + (b := a + c) - b for __ in range(6)} 3277db96d56Sopenharmony_ci self.assertEqual(fib, {1: 2, 2: 3, 3: 5, 5: 8, 8: 13, 13: 21}) 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci def test_named_expression_assignment_17(self): 3307db96d56Sopenharmony_ci a = [1] 3317db96d56Sopenharmony_ci element = a[b:=0] 3327db96d56Sopenharmony_ci self.assertEqual(b, 0) 3337db96d56Sopenharmony_ci self.assertEqual(element, a[0]) 3347db96d56Sopenharmony_ci 3357db96d56Sopenharmony_ci def test_named_expression_assignment_18(self): 3367db96d56Sopenharmony_ci class TwoDimensionalList: 3377db96d56Sopenharmony_ci def __init__(self, two_dimensional_list): 3387db96d56Sopenharmony_ci self.two_dimensional_list = two_dimensional_list 3397db96d56Sopenharmony_ci 3407db96d56Sopenharmony_ci def __getitem__(self, index): 3417db96d56Sopenharmony_ci return self.two_dimensional_list[index[0]][index[1]] 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci a = TwoDimensionalList([[1], [2]]) 3447db96d56Sopenharmony_ci element = a[b:=0, c:=0] 3457db96d56Sopenharmony_ci self.assertEqual(b, 0) 3467db96d56Sopenharmony_ci self.assertEqual(c, 0) 3477db96d56Sopenharmony_ci self.assertEqual(element, a.two_dimensional_list[b][c]) 3487db96d56Sopenharmony_ci 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ciclass NamedExpressionScopeTest(unittest.TestCase): 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci def test_named_expression_scope_01(self): 3547db96d56Sopenharmony_ci code = """def spam(): 3557db96d56Sopenharmony_ci (a := 5) 3567db96d56Sopenharmony_ciprint(a)""" 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci with self.assertRaisesRegex(NameError, "name 'a' is not defined"): 3597db96d56Sopenharmony_ci exec(code, {}, {}) 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci def test_named_expression_scope_02(self): 3627db96d56Sopenharmony_ci total = 0 3637db96d56Sopenharmony_ci partial_sums = [total := total + v for v in range(5)] 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ci self.assertEqual(partial_sums, [0, 1, 3, 6, 10]) 3667db96d56Sopenharmony_ci self.assertEqual(total, 10) 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci def test_named_expression_scope_03(self): 3697db96d56Sopenharmony_ci containsOne = any((lastNum := num) == 1 for num in [1, 2, 3]) 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci self.assertTrue(containsOne) 3727db96d56Sopenharmony_ci self.assertEqual(lastNum, 1) 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci def test_named_expression_scope_04(self): 3757db96d56Sopenharmony_ci def spam(a): 3767db96d56Sopenharmony_ci return a 3777db96d56Sopenharmony_ci res = [[y := spam(x), x/y] for x in range(1, 5)] 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ci self.assertEqual(y, 4) 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci def test_named_expression_scope_05(self): 3827db96d56Sopenharmony_ci def spam(a): 3837db96d56Sopenharmony_ci return a 3847db96d56Sopenharmony_ci input_data = [1, 2, 3] 3857db96d56Sopenharmony_ci res = [(x, y, x/y) for x in input_data if (y := spam(x)) > 0] 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ci self.assertEqual(res, [(1, 1, 1.0), (2, 2, 1.0), (3, 3, 1.0)]) 3887db96d56Sopenharmony_ci self.assertEqual(y, 3) 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci def test_named_expression_scope_06(self): 3917db96d56Sopenharmony_ci res = [[spam := i for i in range(3)] for j in range(2)] 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci self.assertEqual(res, [[0, 1, 2], [0, 1, 2]]) 3947db96d56Sopenharmony_ci self.assertEqual(spam, 2) 3957db96d56Sopenharmony_ci 3967db96d56Sopenharmony_ci def test_named_expression_scope_07(self): 3977db96d56Sopenharmony_ci len(lines := [1, 2]) 3987db96d56Sopenharmony_ci 3997db96d56Sopenharmony_ci self.assertEqual(lines, [1, 2]) 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci def test_named_expression_scope_08(self): 4027db96d56Sopenharmony_ci def spam(a): 4037db96d56Sopenharmony_ci return a 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci def eggs(b): 4067db96d56Sopenharmony_ci return b * 2 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci res = [spam(a := eggs(b := h)) for h in range(2)] 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_ci self.assertEqual(res, [0, 2]) 4117db96d56Sopenharmony_ci self.assertEqual(a, 2) 4127db96d56Sopenharmony_ci self.assertEqual(b, 1) 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ci def test_named_expression_scope_09(self): 4157db96d56Sopenharmony_ci def spam(a): 4167db96d56Sopenharmony_ci return a 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci def eggs(b): 4197db96d56Sopenharmony_ci return b * 2 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_ci res = [spam(a := eggs(a := h)) for h in range(2)] 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci self.assertEqual(res, [0, 2]) 4247db96d56Sopenharmony_ci self.assertEqual(a, 2) 4257db96d56Sopenharmony_ci 4267db96d56Sopenharmony_ci def test_named_expression_scope_10(self): 4277db96d56Sopenharmony_ci res = [b := [a := 1 for i in range(2)] for j in range(2)] 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci self.assertEqual(res, [[1, 1], [1, 1]]) 4307db96d56Sopenharmony_ci self.assertEqual(a, 1) 4317db96d56Sopenharmony_ci self.assertEqual(b, [1, 1]) 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_ci def test_named_expression_scope_11(self): 4347db96d56Sopenharmony_ci res = [j := i for i in range(5)] 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci self.assertEqual(res, [0, 1, 2, 3, 4]) 4377db96d56Sopenharmony_ci self.assertEqual(j, 4) 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci def test_named_expression_scope_17(self): 4407db96d56Sopenharmony_ci b = 0 4417db96d56Sopenharmony_ci res = [b := i + b for i in range(5)] 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci self.assertEqual(res, [0, 1, 3, 6, 10]) 4447db96d56Sopenharmony_ci self.assertEqual(b, 10) 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci def test_named_expression_scope_18(self): 4477db96d56Sopenharmony_ci def spam(a): 4487db96d56Sopenharmony_ci return a 4497db96d56Sopenharmony_ci 4507db96d56Sopenharmony_ci res = spam(b := 2) 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci self.assertEqual(res, 2) 4537db96d56Sopenharmony_ci self.assertEqual(b, 2) 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci def test_named_expression_scope_19(self): 4567db96d56Sopenharmony_ci def spam(a): 4577db96d56Sopenharmony_ci return a 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_ci res = spam((b := 2)) 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci self.assertEqual(res, 2) 4627db96d56Sopenharmony_ci self.assertEqual(b, 2) 4637db96d56Sopenharmony_ci 4647db96d56Sopenharmony_ci def test_named_expression_scope_20(self): 4657db96d56Sopenharmony_ci def spam(a): 4667db96d56Sopenharmony_ci return a 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci res = spam(a=(b := 2)) 4697db96d56Sopenharmony_ci 4707db96d56Sopenharmony_ci self.assertEqual(res, 2) 4717db96d56Sopenharmony_ci self.assertEqual(b, 2) 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci def test_named_expression_scope_21(self): 4747db96d56Sopenharmony_ci def spam(a, b): 4757db96d56Sopenharmony_ci return a + b 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci res = spam(c := 2, b=1) 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci self.assertEqual(res, 3) 4807db96d56Sopenharmony_ci self.assertEqual(c, 2) 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_ci def test_named_expression_scope_22(self): 4837db96d56Sopenharmony_ci def spam(a, b): 4847db96d56Sopenharmony_ci return a + b 4857db96d56Sopenharmony_ci 4867db96d56Sopenharmony_ci res = spam((c := 2), b=1) 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci self.assertEqual(res, 3) 4897db96d56Sopenharmony_ci self.assertEqual(c, 2) 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci def test_named_expression_scope_23(self): 4927db96d56Sopenharmony_ci def spam(a, b): 4937db96d56Sopenharmony_ci return a + b 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_ci res = spam(b=(c := 2), a=1) 4967db96d56Sopenharmony_ci 4977db96d56Sopenharmony_ci self.assertEqual(res, 3) 4987db96d56Sopenharmony_ci self.assertEqual(c, 2) 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_ci def test_named_expression_scope_24(self): 5017db96d56Sopenharmony_ci a = 10 5027db96d56Sopenharmony_ci def spam(): 5037db96d56Sopenharmony_ci nonlocal a 5047db96d56Sopenharmony_ci (a := 20) 5057db96d56Sopenharmony_ci spam() 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_ci self.assertEqual(a, 20) 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci def test_named_expression_scope_25(self): 5107db96d56Sopenharmony_ci ns = {} 5117db96d56Sopenharmony_ci code = """a = 10 5127db96d56Sopenharmony_cidef spam(): 5137db96d56Sopenharmony_ci global a 5147db96d56Sopenharmony_ci (a := 20) 5157db96d56Sopenharmony_cispam()""" 5167db96d56Sopenharmony_ci 5177db96d56Sopenharmony_ci exec(code, ns, {}) 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_ci self.assertEqual(ns["a"], 20) 5207db96d56Sopenharmony_ci 5217db96d56Sopenharmony_ci def test_named_expression_variable_reuse_in_comprehensions(self): 5227db96d56Sopenharmony_ci # The compiler is expected to raise syntax error for comprehension 5237db96d56Sopenharmony_ci # iteration variables, but should be fine with rebinding of other 5247db96d56Sopenharmony_ci # names (e.g. globals, nonlocals, other assignment expressions) 5257db96d56Sopenharmony_ci 5267db96d56Sopenharmony_ci # The cases are all defined to produce the same expected result 5277db96d56Sopenharmony_ci # Each comprehension is checked at both function scope and module scope 5287db96d56Sopenharmony_ci rebinding = "[x := i for i in range(3) if (x := i) or not x]" 5297db96d56Sopenharmony_ci filter_ref = "[x := i for i in range(3) if x or not x]" 5307db96d56Sopenharmony_ci body_ref = "[x for i in range(3) if (x := i) or not x]" 5317db96d56Sopenharmony_ci nested_ref = "[j for i in range(3) if x or not x for j in range(3) if (x := i)][:-3]" 5327db96d56Sopenharmony_ci cases = [ 5337db96d56Sopenharmony_ci ("Rebind global", f"x = 1; result = {rebinding}"), 5347db96d56Sopenharmony_ci ("Rebind nonlocal", f"result, x = (lambda x=1: ({rebinding}, x))()"), 5357db96d56Sopenharmony_ci ("Filter global", f"x = 1; result = {filter_ref}"), 5367db96d56Sopenharmony_ci ("Filter nonlocal", f"result, x = (lambda x=1: ({filter_ref}, x))()"), 5377db96d56Sopenharmony_ci ("Body global", f"x = 1; result = {body_ref}"), 5387db96d56Sopenharmony_ci ("Body nonlocal", f"result, x = (lambda x=1: ({body_ref}, x))()"), 5397db96d56Sopenharmony_ci ("Nested global", f"x = 1; result = {nested_ref}"), 5407db96d56Sopenharmony_ci ("Nested nonlocal", f"result, x = (lambda x=1: ({nested_ref}, x))()"), 5417db96d56Sopenharmony_ci ] 5427db96d56Sopenharmony_ci for case, code in cases: 5437db96d56Sopenharmony_ci with self.subTest(case=case): 5447db96d56Sopenharmony_ci ns = {} 5457db96d56Sopenharmony_ci exec(code, ns) 5467db96d56Sopenharmony_ci self.assertEqual(ns["x"], 2) 5477db96d56Sopenharmony_ci self.assertEqual(ns["result"], [0, 1, 2]) 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci def test_named_expression_global_scope(self): 5507db96d56Sopenharmony_ci sentinel = object() 5517db96d56Sopenharmony_ci global GLOBAL_VAR 5527db96d56Sopenharmony_ci def f(): 5537db96d56Sopenharmony_ci global GLOBAL_VAR 5547db96d56Sopenharmony_ci [GLOBAL_VAR := sentinel for _ in range(1)] 5557db96d56Sopenharmony_ci self.assertEqual(GLOBAL_VAR, sentinel) 5567db96d56Sopenharmony_ci try: 5577db96d56Sopenharmony_ci f() 5587db96d56Sopenharmony_ci self.assertEqual(GLOBAL_VAR, sentinel) 5597db96d56Sopenharmony_ci finally: 5607db96d56Sopenharmony_ci GLOBAL_VAR = None 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_ci def test_named_expression_global_scope_no_global_keyword(self): 5637db96d56Sopenharmony_ci sentinel = object() 5647db96d56Sopenharmony_ci def f(): 5657db96d56Sopenharmony_ci GLOBAL_VAR = None 5667db96d56Sopenharmony_ci [GLOBAL_VAR := sentinel for _ in range(1)] 5677db96d56Sopenharmony_ci self.assertEqual(GLOBAL_VAR, sentinel) 5687db96d56Sopenharmony_ci f() 5697db96d56Sopenharmony_ci self.assertEqual(GLOBAL_VAR, None) 5707db96d56Sopenharmony_ci 5717db96d56Sopenharmony_ci def test_named_expression_nonlocal_scope(self): 5727db96d56Sopenharmony_ci sentinel = object() 5737db96d56Sopenharmony_ci def f(): 5747db96d56Sopenharmony_ci nonlocal_var = None 5757db96d56Sopenharmony_ci def g(): 5767db96d56Sopenharmony_ci nonlocal nonlocal_var 5777db96d56Sopenharmony_ci [nonlocal_var := sentinel for _ in range(1)] 5787db96d56Sopenharmony_ci g() 5797db96d56Sopenharmony_ci self.assertEqual(nonlocal_var, sentinel) 5807db96d56Sopenharmony_ci f() 5817db96d56Sopenharmony_ci 5827db96d56Sopenharmony_ci def test_named_expression_nonlocal_scope_no_nonlocal_keyword(self): 5837db96d56Sopenharmony_ci sentinel = object() 5847db96d56Sopenharmony_ci def f(): 5857db96d56Sopenharmony_ci nonlocal_var = None 5867db96d56Sopenharmony_ci def g(): 5877db96d56Sopenharmony_ci [nonlocal_var := sentinel for _ in range(1)] 5887db96d56Sopenharmony_ci g() 5897db96d56Sopenharmony_ci self.assertEqual(nonlocal_var, None) 5907db96d56Sopenharmony_ci f() 5917db96d56Sopenharmony_ci 5927db96d56Sopenharmony_ci def test_named_expression_scope_in_genexp(self): 5937db96d56Sopenharmony_ci a = 1 5947db96d56Sopenharmony_ci b = [1, 2, 3, 4] 5957db96d56Sopenharmony_ci genexp = (c := i + a for i in b) 5967db96d56Sopenharmony_ci 5977db96d56Sopenharmony_ci self.assertNotIn("c", locals()) 5987db96d56Sopenharmony_ci for idx, elem in enumerate(genexp): 5997db96d56Sopenharmony_ci self.assertEqual(elem, b[idx] + a) 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ci 6027db96d56Sopenharmony_ciif __name__ == "__main__": 6037db96d56Sopenharmony_ci unittest.main() 604