classification
Title: Curiosity: f((a)=1) is not a syntax error -- why?
Type: Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, emilyemorehouse, gvanrossum, serhiy.storchaka, xtreak
Priority: normal Keywords: patch

Created on 2018-09-12 00:31 by gvanrossum, last changed 2018-09-13 00:14 by benjamin.peterson. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 9212 merged benjamin.peterson, 2018-09-12 06:13
Messages (6)
msg325107 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2018-09-12 00:31
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?
msg325111 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2018-09-12 01:21
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");
msg325123 - (view) Author: Karthikeyan Singaravelan (xtreak) * Date: 2018-09-12 05:37
There seems to be some of the similar cases that have tests added as part of c960f26044edaea6669e60859ecf590c63c65e62 and the original error message added at 3e0055f8c65c407e74ce476b8e2b1fb889723514.

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
msg325125 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-09-12 06:04
Could you please create a PR Benjamin? And please keep the comment about special casing lambda.

See also issue30858 about the wording of the error message.
msg325126 - (view) Author: Karthikeyan Singaravelan (xtreak) * Date: 2018-09-12 06:13
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
test_assign_call (test.test_syntax.SyntaxTestCase) ... ok
test_assign_del (test.test_syntax.SyntaxTestCase) ... ok
test_bad_outdent (test.test_syntax.SyntaxTestCase) ... ok
test_break_outside_loop (test.test_syntax.SyntaxTestCase) ... ok
test_global_param_err_first (test.test_syntax.SyntaxTestCase) ... ok
test_kwargs_last (test.test_syntax.SyntaxTestCase) ... ok
test_kwargs_last2 (test.test_syntax.SyntaxTestCase) ... ok
test_kwargs_last3 (test.test_syntax.SyntaxTestCase) ... ok
test_no_indent (test.test_syntax.SyntaxTestCase) ... ok
test_nonlocal_param_err_first (test.test_syntax.SyntaxTestCase) ... ok
test_unexpected_indent (test.test_syntax.SyntaxTestCase) ... ok

----------------------------------------------------------------------
Ran 11 tests in 0.006s

OK



Thanks
msg325219 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2018-09-13 00:14
New changeset c9a71dd223c4ad200a97aa320aef6bd3d45f8897 by Benjamin Peterson in branch 'master':
closes bpo-34641: Further restrict the LHS of keyword argument function call syntax. (GH-9212)
https://github.com/python/cpython/commit/c9a71dd223c4ad200a97aa320aef6bd3d45f8897
History
Date User Action Args
2018-09-13 00:14:42benjamin.petersonsetstatus: open -> closed
resolution: fixed
messages: + msg325219

stage: patch review -> resolved
2018-09-12 06:13:48benjamin.petersonsetkeywords: + patch
stage: patch review
pull_requests: + pull_request8644
2018-09-12 06:13:32xtreaksetmessages: + msg325126
2018-09-12 06:04:00serhiy.storchakasetmessages: + msg325125
2018-09-12 05:37:31xtreaksetmessages: + msg325123
2018-09-12 04:50:22serhiy.storchakasetnosy: + serhiy.storchaka
2018-09-12 03:50:15xtreaksetnosy: + xtreak
2018-09-12 01:21:33benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg325111
2018-09-12 00:31:54gvanrossumcreate