diff options
Diffstat (limited to 'Python/ast.c')
-rw-r--r-- | Python/ast.c | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/Python/ast.c b/Python/ast.c index 855acca29e..6560026109 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -94,6 +94,8 @@ expr_context_name(expr_context_ty ctx) return "Load"; case Store: return "Store"; + case NamedStore: + return "NamedStore"; case Del: return "Del"; case AugLoad: @@ -975,14 +977,29 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) switch (e->kind) { case Attribute_kind: + if (ctx == NamedStore) { + expr_name = "attribute"; + break; + } + e->v.Attribute.ctx = ctx; if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1)) return 0; break; case Subscript_kind: + if (ctx == NamedStore) { + expr_name = "subscript"; + break; + } + e->v.Subscript.ctx = ctx; break; case Starred_kind: + if (ctx == NamedStore) { + expr_name = "starred"; + break; + } + e->v.Starred.ctx = ctx; if (!set_context(c, e->v.Starred.value, ctx, n)) return 0; @@ -995,10 +1012,20 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) e->v.Name.ctx = ctx; break; case List_kind: + if (ctx == NamedStore) { + expr_name = "list"; + break; + } + e->v.List.ctx = ctx; s = e->v.List.elts; break; case Tuple_kind: + if (ctx == NamedStore) { + expr_name = "tuple"; + break; + } + e->v.Tuple.ctx = ctx; s = e->v.Tuple.elts; break; @@ -1060,17 +1087,27 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) case IfExp_kind: expr_name = "conditional expression"; break; + case NamedExpr_kind: + expr_name = "named expression"; + break; default: PyErr_Format(PyExc_SystemError, - "unexpected expression in assignment %d (line %d)", + "unexpected expression in %sassignment %d (line %d)", + ctx == NamedStore ? "named ": "", e->kind, e->lineno); return 0; } /* Check for error string set by switch */ if (expr_name) { - return ast_error(c, n, "cannot %s %s", + if (ctx == NamedStore) { + return ast_error(c, n, "cannot use named assignment with %s", + expr_name); + } + else { + return ast_error(c, n, "cannot %s %s", ctx == Store ? "assign to" : "delete", expr_name); + } } /* If the LHS is a list or tuple, we need to set the assignment @@ -1198,7 +1235,7 @@ seq_for_testlist(struct compiling *c, const node *n) for (i = 0; i < NCH(n); i += 2) { const node *ch = CHILD(n, i); - assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr); + assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr || TYPE(ch) == namedexpr_test); expression = ast_for_expr(c, ch); if (!expression) @@ -1692,6 +1729,35 @@ ast_for_decorated(struct compiling *c, const node *n) } static expr_ty +ast_for_namedexpr(struct compiling *c, const node *n) +{ + /* if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* + ['else' ':' suite] + namedexpr_test: test [':=' test] + argument: ( test [comp_for] | + test ':=' test | + test '=' test | + '**' test | + '*' test ) + */ + expr_ty target, value; + + target = ast_for_expr(c, CHILD(n, 0)); + if (!target) + return NULL; + + value = ast_for_expr(c, CHILD(n, 2)); + if (!value) + return NULL; + + if (!set_context(c, target, NamedStore, n)) + return NULL; + + return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno, + n->n_end_col_offset, c->c_arena); +} + +static expr_ty ast_for_lambdef(struct compiling *c, const node *n) { /* lambdef: 'lambda' [varargslist] ':' test @@ -2568,6 +2634,7 @@ static expr_ty ast_for_expr(struct compiling *c, const node *n) { /* handle the full range of simple expressions + namedexpr_test: test [':=' test] test: or_test ['if' or_test 'else' test] | lambdef test_nocond: or_test | lambdef_nocond or_test: and_test ('or' and_test)* @@ -2591,6 +2658,10 @@ ast_for_expr(struct compiling *c, const node *n) loop: switch (TYPE(n)) { + case namedexpr_test: + if (NCH(n) == 3) + return ast_for_namedexpr(c, n); + /* Fallthrough */ case test: case test_nocond: if (TYPE(CHILD(n, 0)) == lambdef || @@ -2770,6 +2841,9 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, } else if (TYPE(CHILD(ch, 0)) == STAR) nargs++; + else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { + nargs++; + } else /* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */ nkeywords++; @@ -2850,6 +2924,26 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, return NULL; asdl_seq_SET(args, nargs++, e); } + else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { + /* treat colon equal as positional argument */ + if (nkeywords) { + if (ndoublestars) { + ast_error(c, chch, + "positional argument follows " + "keyword argument unpacking"); + } + else { + ast_error(c, chch, + "positional argument follows " + "keyword argument"); + } + return NULL; + } + e = ast_for_namedexpr(c, ch); + if (!e) + return NULL; + asdl_seq_SET(args, nargs++, e); + } else { /* a keyword argument */ keyword_ty kw; |