]> granicus.if.org Git - python/commitdiff
bpo-34854: Fix compiling string annotations containing lambdas. (GH-9645)
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 30 Sep 2018 18:07:05 +0000 (21:07 +0300)
committerGitHub <noreply@github.com>
Sun, 30 Sep 2018 18:07:05 +0000 (21:07 +0300)
* Compiling a string annotation containing a lambda with keyword-only
argument without default value caused a crash.

* Remove the final "*" (it is incorrect syntax) in the representation of
lambda without *args and keyword-only arguments when compile from AST.

* Improve the representation of lambda without arguments.

Lib/test/test_future.py
Misc/NEWS.d/next/Core and Builtins/2018-09-30-19-27-13.bpo-34854.6TKTcB.rst [new file with mode: 0644]
Python/ast_unparse.c

index 904e8a9d5dfc4d8d6f80823ecfc213cbb79af6a4..4f2f9d272e7f96bf3c6edd5d4980ce75c743beaa 100644 (file)
@@ -178,11 +178,12 @@ class AnnotationsFutureTestCase(unittest.TestCase):
         eq('-1')
         eq('~int and not v1 ^ 123 + v2 | True')
         eq('a + (not b)')
+        eq('lambda: None')
         eq('lambda arg: None')
         eq('lambda a=True: a')
         eq('lambda a, b, c=True: a')
         eq("lambda a, b, c=True, *, d=1 << v2, e='str': a")
-        eq("lambda a, b, c=True, *vararg, d=v1 << 2, e='str', **kwargs: a + b")
+        eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b")
         eq('lambda x: lambda y: x + y')
         eq('1 if True else 2')
         eq('str or None if int or True else str or bytes or None')
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-30-19-27-13.bpo-34854.6TKTcB.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-30-19-27-13.bpo-34854.6TKTcB.rst
new file mode 100644 (file)
index 0000000..4e04e1f
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed a crash in compiling string annotations containing a lambda with a
+keyword-only argument that doesn't have a default value.
index 56ea3c424c5bbe16ba0c6d3b78365c013d2ca981..916ad5f97f0ce1950a415689973e88f47bb8d55c 100644 (file)
@@ -212,7 +212,7 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
     }
 
     /* vararg, or bare '*' if no varargs but keyword-only arguments present */
-    if (args->vararg || args->kwonlyargs) {
+    if (args->vararg || asdl_seq_LEN(args->kwonlyargs)) {
         APPEND_STR_IF_NOT_FIRST(", ");
         APPEND_STR("*");
         if (args->vararg) {
@@ -229,8 +229,11 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
 
         di = i - arg_count + default_count;
         if (di >= 0) {
-            APPEND_STR("=");
-            APPEND_EXPR((expr_ty)asdl_seq_GET(args->kw_defaults, di), PR_TEST);
+            expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di);
+            if (default_) {
+                APPEND_STR("=");
+                APPEND_EXPR(default_, PR_TEST);
+            }
         }
     }
 
@@ -248,7 +251,7 @@ static int
 append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level)
 {
     APPEND_STR_IF(level > PR_TEST, "(");
-    APPEND_STR("lambda ");
+    APPEND_STR(asdl_seq_LEN(e->v.Lambda.args->args) ? "lambda " : "lambda");
     APPEND(args, e->v.Lambda.args);
     APPEND_STR(": ");
     APPEND_EXPR(e->v.Lambda.body, PR_TEST);