-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Curiosity: f((a)=1) is not a syntax error -- why? #78822
Comments
Emily and I just discovered that f((a)=1) is accepted and compiled the same as f(a=1). This goes against the intention that keyword arguments have the syntax f(NAME=expr). I suspect that this behavior was introduced at the time we switched from generating from the (concrete) parse tree to first converting to an ast and then generating code from there. I.e. in the distant past (long before 2.7 even). But I still think it ought to be fixed. Thoughts? Anyone have an idea *where* to fix it? |
I expect you'd have to make the check of test nodes in ast.c stricter. Here's a slightly gross implementation of that: diff --git a/Python/ast.c b/Python/ast.c
index 94962e00c7..b7cebf4777 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2815,15 +2815,22 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, bool allowgen)
identifier key, tmp;
int k;
- /* chch is test, but must be an identifier? */
- e = ast_for_expr(c, chch);
- if (!e)
+ static const int chain[] = {test, or_test, and_test, not_test, comparison, expr, xor_expr, and_expr, shift_expr, arith_expr, term, factor, power, atom_expr, atom, 0};
+
+ node *expr_node = chch;
+ for (int i = 0; chain[i]; i++) {
+ if (TYPE(expr_node) != chain[i])
+ break;
+ if (NCH(expr_node) != 1)
+ break;
+ expr_node = CHILD(expr_node, 0);
+ }
+ if (TYPE(expr_node) != NAME) {
+ ast_error(c, chch,
+ "keyword can't be an expression");
return NULL;
- /* f(lambda x: x[0] = 3) ends up getting parsed with
- * LHS test = lambda x: x[0], and RHS test = 3.
- * SF bug 132313 points out that complaining about a keyword
- * then is very confusing.
- */
+ }
+ e = ast_for_expr(c, chch);
if (e->kind == Lambda_kind) {
ast_error(c, chch,
"lambda cannot contain assignment"); |
There seems to be some of the similar cases that have tests added as part of c960f26 and the original error message added at 3e0055f. Existing tests : >>> f(x()=2)
Traceback (most recent call last):
SyntaxError: keyword can't be an expression
>>> f(a or b=1)
Traceback (most recent call last):
SyntaxError: keyword can't be an expression
>>> f(x.y=1)
Traceback (most recent call last):
SyntaxError: keyword can't be an expression Thanks |
Could you please create a PR Benjamin? And please keep the comment about special casing lambda. See also bpo-30858 about the wording of the error message. |
Tested the patch. ➜ cpython git:(master) ✗ ./python.exe
Python 3.8.0a0 (heads/master-dirty:731ff68eee, Sep 12 2018, 11:40:16)
[Clang 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(a): pass
...
>>> foo((a)=1)
File "<stdin>", line 1
SyntaxError: keyword can't be an expression ➜ cpython git:(master) ✗ ./python.exe -m unittest -v test.test_syntax ---------------------------------------------------------------------- OK Thanks |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: