https://github.com/python/cpython/commit/25684e71310642ffd20b45eea9b5226a1fa809a5
commit: 25684e71310642ffd20b45eea9b5226a1fa809a5
branch: main
author: Nikita Sobolev <[email protected]>
committer: sobolevn <[email protected]>
date: 2024-03-13T21:12:40+03:00
summary:
gh-100746: Improve `test_named_expressions.py` (#116713)
files:
M Lib/test/test_named_expressions.py
diff --git a/Lib/test/test_named_expressions.py
b/Lib/test/test_named_expressions.py
index f2017bdffcf968..cf44080670dc2e 100644
--- a/Lib/test/test_named_expressions.py
+++ b/Lib/test/test_named_expressions.py
@@ -298,6 +298,72 @@ def
test_named_expression_invalid_set_comprehension_iterable_expression(self):
with self.assertRaisesRegex(SyntaxError, msg):
exec(f"lambda: {code}", {}) # Function scope
+ def
test_named_expression_invalid_rebinding_dict_comprehension_iteration_variable(self):
+ cases = [
+ ("Key reuse", 'i', "{(i := 0): 1 for i in range(5)}"),
+ ("Value reuse", 'i', "{1: (i := 0) for i in range(5)}"),
+ ("Both reuse", 'i', "{(i := 0): (i := 0) for i in range(5)}"),
+ ("Nested reuse", 'j', "{{(j := 0): 1 for i in range(5)} for j in
range(5)}"),
+ ("Reuse inner loop target", 'j', "{(j := 0): 1 for i in range(5)
for j in range(5)}"),
+ ("Unpacking key reuse", 'i', "{(i := 0): 1 for i, j in {(0, 1)}}"),
+ ("Unpacking value reuse", 'i', "{1: (i := 0) for i, j in {(0,
1)}}"),
+ ("Reuse in loop condition", 'i', "{i+1: 1 for i in range(5) if (i
:= 0)}"),
+ ("Unreachable reuse", 'i', "{(False or (i:=0)): 1 for i in
range(5)}"),
+ ("Unreachable nested reuse", 'i',
+ "{i: j for i in range(5) for j in range(5) if True or
(i:=10)}"),
+ # Regression tests from
https://github.com/python/cpython/issues/87447
+ ("Complex expression: a", "a",
+ "{(a := 1): 1 for a, (*b, c[d+e::f(g)], h.i) in j}"),
+ ("Complex expression: b", "b",
+ "{(b := 1): 1 for a, (*b, c[d+e::f(g)], h.i) in j}"),
+ ]
+ for case, target, code in cases:
+ msg = f"assignment expression cannot rebind comprehension
iteration variable '{target}'"
+ with self.subTest(case=case):
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}) # Module scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}, {}) # Class scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(f"lambda: {code}", {}) # Function scope
+
+ def
test_named_expression_invalid_rebinding_dict_comprehension_inner_loop(self):
+ cases = [
+ ("Inner reuse", 'j', "{i: 1 for i in range(5) if (j := 0) for j in
range(5)}"),
+ ("Inner unpacking reuse", 'j', "{i: 1 for i in range(5) if (j :=
0) for j, k in {(0, 1)}}"),
+ ]
+ for case, target, code in cases:
+ msg = f"comprehension inner loop cannot rebind assignment
expression target '{target}'"
+ with self.subTest(case=case):
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}) # Module scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}, {}) # Class scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(f"lambda: {code}", {}) # Function scope
+
+ def
test_named_expression_invalid_dict_comprehension_iterable_expression(self):
+ cases = [
+ ("Top level", "{i: 1 for i in (i := range(5))}"),
+ ("Inside tuple", "{i: 1 for i in (2, 3, i := range(5))}"),
+ ("Inside list", "{i: 1 for i in [2, 3, i := range(5)]}"),
+ ("Different name", "{i: 1 for i in (j := range(5))}"),
+ ("Lambda expression", "{i: 1 for i in (lambda:(j :=
range(5)))()}"),
+ ("Inner loop", "{i: 1 for i in range(5) for j in (i :=
range(5))}"),
+ ("Nested comprehension", "{i: 1 for i in {j: 2 for j in (k :=
range(5))}}"),
+ ("Nested comprehension condition", "{i: 1 for i in {j: 2 for j in
range(5) if (j := True)}}"),
+ ("Nested comprehension body", "{i: 1 for i in {(j := True) for j
in range(5)}}"),
+ ]
+ msg = "assignment expression cannot be used in a comprehension
iterable expression"
+ for case, code in cases:
+ with self.subTest(case=case):
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}) # Module scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(code, {}, {}) # Class scope
+ with self.assertRaisesRegex(SyntaxError, msg):
+ exec(f"lambda: {code}", {}) # Function scope
+
def test_named_expression_invalid_mangled_class_variables(self):
code = """class Foo:
def bar(self):
@@ -361,7 +427,7 @@ def test_named_expression_assignment_09(self):
def test_named_expression_assignment_10(self):
if (match := 10) == 10:
- pass
+ self.assertEqual(match, 10)
else: self.fail("variable was not assigned using named expression")
def test_named_expression_assignment_11(self):
@@ -403,7 +469,7 @@ def test_named_expression_assignment_14(self):
def test_named_expression_assignment_15(self):
while a := False:
- pass # This will not run
+ self.fail("While body executed") # This will not run
self.assertEqual(a, False)
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]