Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f153140

Browse filesBrowse files
Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)
- Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages
1 parent d7e57a4 commit f153140
Copy full SHA for f153140

File tree

Expand file treeCollapse file tree

2 files changed

+58
-2
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+58
-2
lines changed

‎Lib/test/test_named_expressions.py

Copy file name to clipboardExpand all lines: Lib/test/test_named_expressions.py
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ def test_named_expression_invalid_01(self):
1010
with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
1111
exec(code, {}, {})
1212

13+
def test_named_expression_invalid_01(self):
14+
code = """((x) := 0)"""
15+
16+
with self.assertRaisesRegex(SyntaxError,
17+
"can't use named assignment with expression"):
18+
exec(code, {}, {})
19+
1320
def test_named_expression_invalid_02(self):
1421
code = """x = y := 0"""
1522

@@ -28,10 +35,16 @@ def test_named_expression_invalid_04(self):
2835
with self.assertRaisesRegex(SyntaxError, "invalid syntax"):
2936
exec(code, {}, {})
3037

38+
# XXX this error message now follows the error message you get with
39+
# keyword args:
40+
# >>> spam((1,2)=1)
41+
# File "<stdin>", line 1
42+
# SyntaxError: keyword can't be an expression
3143
def test_named_expression_invalid_06(self):
3244
code = """((a, b) := (1, 2))"""
3345

34-
with self.assertRaisesRegex(SyntaxError, "can't use named assignment with tuple"):
46+
with self.assertRaisesRegex(SyntaxError,
47+
"can't use named assignment with expression"):
3548
exec(code, {}, {})
3649

3750
def test_named_expression_invalid_07(self):

‎Python/ast.c

Copy file name to clipboardExpand all lines: Python/ast.c
+44-1Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1715,8 +1715,51 @@ ast_for_namedexpr(struct compiling *c, const node *n)
17151715
'*' test )
17161716
*/
17171717
expr_ty target, value;
1718+
node *ch = CHILD(n, 0);
1719+
1720+
// To remain LL(1), the grammar accepts any test (basically, any
1721+
// expression) in the keyword slot of a call site. So, we need
1722+
// to manually enforce that the keyword is a NAME here.
1723+
static const int name_tree[] = {
1724+
namedexpr_test,
1725+
test,
1726+
or_test,
1727+
and_test,
1728+
not_test,
1729+
comparison,
1730+
expr,
1731+
xor_expr,
1732+
and_expr,
1733+
shift_expr,
1734+
arith_expr,
1735+
term,
1736+
factor,
1737+
power,
1738+
atom_expr,
1739+
atom,
1740+
};
1741+
1742+
node *expr_node = ch;
1743+
for (int i = 1; name_tree[i]; i++) {
1744+
if (TYPE(expr_node) != name_tree[i])
1745+
break;
1746+
if (TYPE(expr_node) == atom && expr_node->n_nchildren == 3) {
1747+
node *expr_node_ch = CHILD(CHILD(expr_node, 1), 0);
1748+
for (int i = 0; name_tree[i]; i++) {
1749+
if (TYPE(expr_node_ch) != name_tree[i])
1750+
break;
1751+
expr_node_ch = CHILD(expr_node_ch, 0);
1752+
}
1753+
if (TYPE(expr_node_ch) == NAME) {
1754+
ast_error(c, ch,
1755+
"can't use named assignment with expression");
1756+
return NULL;
1757+
}
1758+
}
1759+
expr_node = CHILD(expr_node, 0);
1760+
}
17181761

1719-
target = ast_for_expr(c, CHILD(n, 0));
1762+
target = ast_for_expr(c, ch);
17201763
if (!target)
17211764
return NULL;
17221765

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.