bpo-34854: Fix compiling string annotations containing lambdas. (GH-9645)

* 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.
This commit is contained in:
Serhiy Storchaka 2018-09-30 21:07:05 +03:00 committed by GitHub
parent d5bd036138
commit 2a2940e5c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 5 deletions

View file

@ -178,11 +178,12 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq('-1') eq('-1')
eq('~int and not v1 ^ 123 + v2 | True') eq('~int and not v1 ^ 123 + v2 | True')
eq('a + (not b)') eq('a + (not b)')
eq('lambda: None')
eq('lambda arg: None') eq('lambda arg: None')
eq('lambda a=True: a') eq('lambda a=True: a')
eq('lambda a, b, c=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, *, 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('lambda x: lambda y: x + y')
eq('1 if True else 2') eq('1 if True else 2')
eq('str or None if int or True else str or bytes or None') eq('str or None if int or True else str or bytes or None')

View file

@ -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.

View file

@ -212,7 +212,7 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
} }
/* vararg, or bare '*' if no varargs but keyword-only arguments present */ /* 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_NOT_FIRST(", ");
APPEND_STR("*"); APPEND_STR("*");
if (args->vararg) { if (args->vararg) {
@ -229,8 +229,11 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
di = i - arg_count + default_count; di = i - arg_count + default_count;
if (di >= 0) { if (di >= 0) {
APPEND_STR("="); expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di);
APPEND_EXPR((expr_ty)asdl_seq_GET(args->kw_defaults, di), PR_TEST); 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_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level)
{ {
APPEND_STR_IF(level > PR_TEST, "("); 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(args, e->v.Lambda.args);
APPEND_STR(": "); APPEND_STR(": ");
APPEND_EXPR(e->v.Lambda.body, PR_TEST); APPEND_EXPR(e->v.Lambda.body, PR_TEST);