From fdeceae09c9611b47d4b7b031b6b602c38913e88 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 28 Jun 2009 19:19:51 +0000 Subject: Merged revisions 73376,73393,73398,73400,73404-73405,73409,73419-73421,73432,73457,73460,73485-73486,73488-73489,73501-73502,73513-73514 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73376 | benjamin.peterson | 2009-06-11 17:29:23 -0500 (Thu, 11 Jun 2009) | 1 line remove check for case handled in sub-function ........ r73393 | alexandre.vassalotti | 2009-06-12 13:56:57 -0500 (Fri, 12 Jun 2009) | 2 lines Clear reference to the static PyExc_RecursionErrorInst in _PyExc_Fini. ........ r73398 | alexandre.vassalotti | 2009-06-12 15:57:12 -0500 (Fri, 12 Jun 2009) | 3 lines Add const qualifier to PyErr_SetFromErrnoWithFilename and to PyErr_SetFromErrnoWithUnicodeFilename. ........ r73400 | alexandre.vassalotti | 2009-06-12 16:43:47 -0500 (Fri, 12 Jun 2009) | 2 lines Delete outdated make file for building the parser with MSVC 6. ........ r73404 | benjamin.peterson | 2009-06-12 20:40:00 -0500 (Fri, 12 Jun 2009) | 1 line keep the slice.step field as NULL if no step expression is given ........ r73405 | benjamin.peterson | 2009-06-12 22:46:30 -0500 (Fri, 12 Jun 2009) | 1 line prevent import statements from assigning to None ........ r73409 | benjamin.peterson | 2009-06-13 08:06:21 -0500 (Sat, 13 Jun 2009) | 1 line allow importing from a module named None if it has an 'as' clause ........ r73419 | benjamin.peterson | 2009-06-13 11:19:19 -0500 (Sat, 13 Jun 2009) | 1 line set Print.values to NULL if there are no values ........ r73420 | benjamin.peterson | 2009-06-13 12:08:53 -0500 (Sat, 13 Jun 2009) | 1 line give a better error message when deleting () ........ r73421 | benjamin.peterson | 2009-06-13 15:23:33 -0500 (Sat, 13 Jun 2009) | 1 line when no module is given in a 'from' relative import, make ImportFrom.module NULL ........ r73432 | amaury.forgeotdarc | 2009-06-14 16:20:40 -0500 (Sun, 14 Jun 2009) | 3 lines #6227: Because of a wrong indentation, the test was not testing what it should. Ensure that the snippet in doctest_aliases actually contains aliases. ........ r73457 | benjamin.peterson | 2009-06-16 18:13:09 -0500 (Tue, 16 Jun 2009) | 1 line add underscores ........ r73460 | benjamin.peterson | 2009-06-16 22:23:04 -0500 (Tue, 16 Jun 2009) | 1 line remove unused 'encoding' member from the compiler struct ........ r73485 | benjamin.peterson | 2009-06-19 17:07:47 -0500 (Fri, 19 Jun 2009) | 1 line remove duplicate test ........ r73486 | benjamin.peterson | 2009-06-19 17:09:17 -0500 (Fri, 19 Jun 2009) | 1 line add missing assertion #6313 ........ r73488 | benjamin.peterson | 2009-06-19 17:16:28 -0500 (Fri, 19 Jun 2009) | 1 line show that this one isn't used ........ r73489 | benjamin.peterson | 2009-06-19 17:21:12 -0500 (Fri, 19 Jun 2009) | 1 line use closures ........ r73501 | benjamin.peterson | 2009-06-21 18:01:07 -0500 (Sun, 21 Jun 2009) | 1 line don't need to add the name 'lambda' as assigned ........ r73502 | benjamin.peterson | 2009-06-21 18:03:36 -0500 (Sun, 21 Jun 2009) | 1 line remove tmpname support since it's no longer used ........ r73513 | benjamin.peterson | 2009-06-22 20:18:57 -0500 (Mon, 22 Jun 2009) | 1 line fix grammar ........ r73514 | benjamin.peterson | 2009-06-22 22:01:56 -0500 (Mon, 22 Jun 2009) | 1 line remove some unused symtable constants ........ --- Python/ast.c | 82 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 83572ee882..d81f001646 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -362,12 +362,12 @@ static const char* FORBIDDEN[] = { }; static int -forbidden_name(expr_ty e, const node *n) +forbidden_name(identifier name, const node *n) { const char **p; - assert(PyUnicode_Check(e->v.Name.id)); + assert(PyUnicode_Check(name)); for (p = FORBIDDEN; *p; p++) { - if (PyUnicode_CompareWithASCIIString(e->v.Name.id, *p) == 0) { + if (PyUnicode_CompareWithASCIIString(name, *p) == 0) { ast_error(n, "assignment to keyword"); return 1; } @@ -414,7 +414,7 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) break; case Name_kind: if (ctx == Store) { - if (forbidden_name(e, n)) + if (forbidden_name(e->v.Name.id, n)) return 0; /* forbidden_name() calls ast_error() */ } e->v.Name.ctx = ctx; @@ -424,10 +424,13 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) s = e->v.List.elts; break; case Tuple_kind: - if (asdl_seq_LEN(e->v.Tuple.elts) == 0) - return ast_error(n, "can't assign to ()"); - e->v.Tuple.ctx = ctx; - s = e->v.Tuple.elts; + if (asdl_seq_LEN(e->v.Tuple.elts)) { + e->v.Tuple.ctx = ctx; + s = e->v.Tuple.elts; + } + else { + expr_name = "()"; + } break; case Lambda_kind: expr_name = "lambda"; @@ -1378,7 +1381,7 @@ ast_for_atom(struct compiling *c, const node *n) /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == comp_for)) return ast_for_genexp(c, ch); - + return ast_for_testlist(c, ch); case LSQB: /* list (or list comprehension) */ ch = CHILD(n, 1); @@ -1513,14 +1516,7 @@ ast_for_slice(struct compiling *c, const node *n) ch = CHILD(n, NCH(n) - 1); if (TYPE(ch) == sliceop) { - if (NCH(ch) == 1) { - /* No expression, so step is None */ - ch = CHILD(ch, 0); - step = Name(new_identifier("None", c->c_arena), Load, - LINENO(ch), ch->n_col_offset, c->c_arena); - if (!step) - return NULL; - } else { + if (NCH(ch) != 1) { ch = CHILD(ch, 1); if (TYPE(ch) == test) { step = ast_for_expr(c, ch); @@ -2014,7 +2010,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) } else if (e->kind != Name_kind) { ast_error(CHILD(ch, 0), "keyword can't be an expression"); return NULL; - } else if (forbidden_name(e, ch)) { + } else if (forbidden_name(e->v.Name.id, ch)) { return NULL; } key = e->v.Name.id; @@ -2160,6 +2156,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) } } + static asdl_seq * ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context) { @@ -2260,49 +2257,64 @@ ast_for_flow_stmt(struct compiling *c, const node *n) } static alias_ty -alias_for_import_name(struct compiling *c, const node *n) +alias_for_import_name(struct compiling *c, const node *n, int store) { /* import_as_name: NAME ['as' NAME] dotted_as_name: dotted_name ['as' NAME] dotted_name: NAME ('.' NAME)* */ - PyObject *str, *name; + identifier str, name; loop: switch (TYPE(n)) { - case import_as_name: + case import_as_name: { + node *name_node = CHILD(n, 0); str = NULL; + name = NEW_IDENTIFIER(name_node); + if (!name) + return NULL; if (NCH(n) == 3) { - str = NEW_IDENTIFIER(CHILD(n, 2)); + node *str_node = CHILD(n, 2); + str = NEW_IDENTIFIER(str_node); if (!str) return NULL; + if (store && forbidden_name(str, str_node)) + return NULL; + } + else { + if (forbidden_name(name, name_node)) + return NULL; } - name = NEW_IDENTIFIER(CHILD(n, 0)); - if (!name) - return NULL; return alias(name, str, c->c_arena); + } case dotted_as_name: if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } else { - alias_ty a = alias_for_import_name(c, CHILD(n, 0)); + node *asname_node = CHILD(n, 2); + alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0); if (!a) return NULL; assert(!a->asname); - a->asname = NEW_IDENTIFIER(CHILD(n, 2)); + a->asname = NEW_IDENTIFIER(asname_node); if (!a->asname) return NULL; + if (forbidden_name(a->asname, asname_node)) + return NULL; return a; } break; case dotted_name: if (NCH(n) == 1) { - name = NEW_IDENTIFIER(CHILD(n, 0)); + node *name_node = CHILD(n, 0); + name = NEW_IDENTIFIER(name_node); if (!name) return NULL; + if (store && forbidden_name(name, name_node)) + return NULL; return alias(name, NULL, c->c_arena); } else { @@ -2382,7 +2394,7 @@ ast_for_import_stmt(struct compiling *c, const node *n) if (!aliases) return NULL; for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i)); + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, i / 2, import_alias); @@ -2393,13 +2405,15 @@ ast_for_import_stmt(struct compiling *c, const node *n) int n_children; int idx, ndots = 0; alias_ty mod = NULL; - identifier modname; + identifier modname = NULL; /* Count the number of dots (for relative imports) and check for the optional module name */ for (idx = 1; idx < NCH(n); idx++) { if (TYPE(CHILD(n, idx)) == dotted_name) { - mod = alias_for_import_name(c, CHILD(n, idx)); + mod = alias_for_import_name(c, CHILD(n, idx), 0); + if (!mod) + return NULL; idx++; break; } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { @@ -2444,14 +2458,14 @@ ast_for_import_stmt(struct compiling *c, const node *n) /* handle "from ... import *" special b/c there's no children */ if (TYPE(n) == STAR) { - alias_ty import_alias = alias_for_import_name(c, n); + alias_ty import_alias = alias_for_import_name(c, n, 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, 0, import_alias); } else { for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i)); + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, i / 2, import_alias); @@ -2459,8 +2473,6 @@ ast_for_import_stmt(struct compiling *c, const node *n) } if (mod != NULL) modname = mod->name; - else - modname = new_identifier("", c->c_arena); return ImportFrom(modname, aliases, ndots, lineno, col_offset, c->c_arena); } -- cgit v1.2.1 From 4982735db43513c8a18b7bfbbf936054ad32ccec Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 28 Jun 2009 23:32:44 +0000 Subject: In most cases, the parser will protect True, False, and None from being assign to. We must check for __debug__ in all cases. --- Python/ast.c | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index d81f001646..8a1edd2f10 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -357,19 +357,24 @@ static const char* FORBIDDEN[] = { "None", "True", "False", - "__debug__", NULL, }; static int -forbidden_name(identifier name, const node *n) +forbidden_name(identifier name, const node *n, int full_checks) { - const char **p; assert(PyUnicode_Check(name)); - for (p = FORBIDDEN; *p; p++) { - if (PyUnicode_CompareWithASCIIString(name, *p) == 0) { - ast_error(n, "assignment to keyword"); - return 1; + if (PyUnicode_CompareWithASCIIString(name, "__debug__") == 0) { + ast_error(n, "assignment to keyword"); + return 1; + } + if (full_checks) { + const char **p; + for (p = FORBIDDEN; *p; p++) { + if (PyUnicode_CompareWithASCIIString(name, *p) == 0) { + ast_error(n, "assignment to keyword"); + return 1; + } } } return 0; @@ -403,6 +408,8 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) switch (e->kind) { case Attribute_kind: e->v.Attribute.ctx = ctx; + if (ctx == Store && forbidden_name(e->v.Attribute.attr, n, 1)) + return 0; break; case Subscript_kind: e->v.Subscript.ctx = ctx; @@ -414,7 +421,7 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) break; case Name_kind: if (ctx == Store) { - if (forbidden_name(e->v.Name.id, n)) + if (forbidden_name(e->v.Name.id, n, 1)) return 0; /* forbidden_name() calls ast_error() */ } e->v.Name.ctx = ctx; @@ -631,6 +638,8 @@ compiler_arg(struct compiling *c, const node *n) name = NEW_IDENTIFIER(ch); if (!name) return NULL; + if (forbidden_name(name, ch, 0)) + return NULL; if (NCH(n) == 3 && TYPE(CHILD(n, 1)) == COLON) { annotation = ast_for_expr(c, CHILD(n, 2)); @@ -697,6 +706,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, argname = NEW_IDENTIFIER(ch); if (!argname) goto error; + if (forbidden_name(argname, ch, 0)) + goto error; arg = arg(argname, annotation, c->c_arena); if (!arg) goto error; @@ -855,6 +866,8 @@ ast_for_arguments(struct compiling *c, const node *n) vararg = NEW_IDENTIFIER(CHILD(ch, 0)); if (!vararg) return NULL; + if (forbidden_name(vararg, CHILD(ch, 0), 0)) + return NULL; if (NCH(ch) > 1) { /* there is an annotation on the vararg */ varargannotation = ast_for_expr(c, CHILD(ch, 2)); @@ -880,6 +893,8 @@ ast_for_arguments(struct compiling *c, const node *n) } if (!kwarg) goto error; + if (forbidden_name(kwarg, CHILD(ch, 0), 0)) + goto error; i += 3; break; default: @@ -1001,6 +1016,8 @@ ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) name = NEW_IDENTIFIER(CHILD(n, name_i)); if (!name) return NULL; + if (forbidden_name(name, CHILD(n, name_i), 0)) + return NULL; args = ast_for_arguments(c, CHILD(n, name_i + 1)); if (!args) return NULL; @@ -2010,7 +2027,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) } else if (e->kind != Name_kind) { ast_error(CHILD(ch, 0), "keyword can't be an expression"); return NULL; - } else if (forbidden_name(e->v.Name.id, ch)) { + } else if (forbidden_name(e->v.Name.id, ch, 1)) { return NULL; } key = e->v.Name.id; @@ -2279,11 +2296,11 @@ alias_for_import_name(struct compiling *c, const node *n, int store) str = NEW_IDENTIFIER(str_node); if (!str) return NULL; - if (store && forbidden_name(str, str_node)) + if (store && forbidden_name(str, str_node, 0)) return NULL; } else { - if (forbidden_name(name, name_node)) + if (forbidden_name(name, name_node, 0)) return NULL; } return alias(name, str, c->c_arena); @@ -2302,7 +2319,7 @@ alias_for_import_name(struct compiling *c, const node *n, int store) a->asname = NEW_IDENTIFIER(asname_node); if (!a->asname) return NULL; - if (forbidden_name(a->asname, asname_node)) + if (forbidden_name(a->asname, asname_node, 0)) return NULL; return a; } @@ -2313,7 +2330,7 @@ alias_for_import_name(struct compiling *c, const node *n, int store) name = NEW_IDENTIFIER(name_node); if (!name) return NULL; - if (store && forbidden_name(name, name_node)) + if (store && forbidden_name(name, name_node, 0)) return NULL; return alias(name, NULL, c->c_arena); } @@ -2853,6 +2870,8 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) identifier e = NEW_IDENTIFIER(CHILD(exc, 3)); if (!e) return NULL; + if (forbidden_name(e, CHILD(exc, 3), 0)) + return NULL; expression = ast_for_expr(c, CHILD(exc, 1)); if (!expression) return NULL; @@ -3023,6 +3042,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; + if (forbidden_name(classname, CHILD(n, 3), 0)) + return NULL; return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); } @@ -3034,6 +3055,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; + if (forbidden_name(classname, CHILD(n, 3), 0)) + return NULL; return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); } @@ -3057,6 +3080,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; + if (forbidden_name(classname, CHILD(n, 1), 0)) + return NULL; return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, call->v.Call.starargs, call->v.Call.kwargs, s, -- cgit v1.2.1 From b8417dd9d75e53fd65dcd3b63e913ccfbee59516 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 11 Sep 2009 22:36:20 +0000 Subject: Merged revisions 74464 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74464 | benjamin.peterson | 2009-08-15 17:59:21 -0500 (Sat, 15 Aug 2009) | 4 lines better col_offsets for "for" statements with tuple unpacking #6704 Patch from Frank Wierzbicki. ........ --- Python/ast.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 8a1edd2f10..fb3894449a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1192,7 +1192,7 @@ ast_for_comprehension(struct compiling *c, const node *n) for (i = 0; i < n_fors; i++) { comprehension_ty comp; asdl_seq *t; - expr_ty expression; + expr_ty expression, first; node *for_ch; REQ(n, comp_for); @@ -1207,14 +1207,13 @@ ast_for_comprehension(struct compiling *c, const node *n) /* Check the # of children rather than the length of t, since (x for x, in ...) has 1 element in t, but still requires a Tuple. */ + first = (expr_ty)asdl_seq_GET(t, 0); if (NCH(for_ch) == 1) - comp = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, - NULL, c->c_arena); + comp = comprehension(first, expression, NULL, c->c_arena); else - comp = comprehension(Tuple(t, Store, LINENO(n), n->n_col_offset, - c->c_arena), - expression, NULL, c->c_arena); - + comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset, + c->c_arena), + expression, NULL, c->c_arena); if (!comp) return NULL; @@ -1294,7 +1293,6 @@ ast_for_dictcomp(struct compiling *c, const node *n) key = ast_for_expr(c, CHILD(n, 0)); if (!key) return NULL; - value = ast_for_expr(c, CHILD(n, 2)); if (!value) return NULL; @@ -2802,7 +2800,7 @@ ast_for_for_stmt(struct compiling *c, const node *n) { asdl_seq *_target, *seq = NULL, *suite_seq; expr_ty expression; - expr_ty target; + expr_ty target, first; const node *node_target; /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */ REQ(n, for_stmt); @@ -2819,10 +2817,11 @@ ast_for_for_stmt(struct compiling *c, const node *n) return NULL; /* Check the # of children rather than the length of _target, since for x, in ... has 1 element in _target, but still requires a Tuple. */ + first = (expr_ty)asdl_seq_GET(_target, 0); if (NCH(node_target) == 1) - target = (expr_ty)asdl_seq_GET(_target, 0); + target = first; else - target = Tuple(_target, Store, LINENO(n), n->n_col_offset, c->c_arena); + target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena); expression = ast_for_testlist(c, CHILD(n, 3)); if (!expression) -- cgit v1.2.1 From 8ccabc0faaf6b0af4ba2483c6212f324815fbef1 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 27 Sep 2009 02:43:28 +0000 Subject: fix an ambiguity in the grammar from the implementation of extended unpacking (one which was strangely "resolved" by pgen) This also kills the unused testlist1 rule and fixes parse tree validation of extended unpacking. --- Python/ast.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index fb3894449a..97b57ec100 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -603,20 +603,23 @@ ast_for_comp_op(struct compiling *c, const node *n) static asdl_seq * seq_for_testlist(struct compiling *c, const node *n) { - /* testlist: test (',' test)* [','] */ + /* testlist: test (',' test)* [','] + testlist_star_expr: test|star_expr (',' test|star_expr)* [','] + */ asdl_seq *seq; expr_ty expression; int i; - assert(TYPE(n) == testlist || TYPE(n) == testlist_comp); + assert(TYPE(n) == testlist || TYPE(n) == testlist_star_expr || TYPE(n) == testlist_comp); seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); if (!seq) return NULL; for (i = 0; i < NCH(n); i += 2) { - assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == test_nocond); + const node *ch = CHILD(n, i); + assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr); - expression = ast_for_expr(c, CHILD(n, i)); + expression = ast_for_expr(c, ch); if (!expression) return NULL; @@ -1886,10 +1889,9 @@ ast_for_expr(struct compiling *c, const node *n) break; case star_expr: - if (TYPE(CHILD(n, 0)) == STAR) { - return ast_for_starred(c, n); - } - /* Fallthrough */ + if (TYPE(CHILD(n, 0)) == STAR) + return ast_for_starred(c, n); + /* Fall through to generic case. */ /* The next five cases all handle BinOps. The main body of code is the same in each case, but the switch turned inside out to reuse the code for each type of operator. @@ -2067,7 +2069,6 @@ ast_for_testlist(struct compiling *c, const node* n) { /* testlist_comp: test (comp_for | (',' test)* [',']) */ /* testlist: test (',' test)* [','] */ - /* testlist1: test (',' test)* */ assert(NCH(n) > 0); if (TYPE(n) == testlist_comp) { if (NCH(n) > 1) @@ -2075,7 +2076,7 @@ ast_for_testlist(struct compiling *c, const node* n) } else { assert(TYPE(n) == testlist || - TYPE(n) == testlist1); + TYPE(n) == testlist_star_expr); } if (NCH(n) == 1) return ast_for_expr(c, CHILD(n, 0)); @@ -2091,9 +2092,9 @@ static stmt_ty ast_for_expr_stmt(struct compiling *c, const node *n) { REQ(n, expr_stmt); - /* expr_stmt: testlist (augassign (yield_expr|testlist) + /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) - testlist: test (',' test)* [','] + testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' test: ... here starts the operator precendence dance @@ -2161,7 +2162,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) asdl_seq_SET(targets, i / 2, e); } value = CHILD(n, NCH(n) - 1); - if (TYPE(value) == testlist) + if (TYPE(value) == testlist_star_expr) expression = ast_for_testlist(c, value); else expression = ast_for_expr(c, value); -- cgit v1.2.1 From 07194b1ca66cd745689e24253b5f2a9288807e6e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 27 Sep 2009 14:08:59 +0000 Subject: star_expr now always has two nodes --- Python/ast.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 97b57ec100..dfcc8e32e1 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1889,9 +1889,7 @@ ast_for_expr(struct compiling *c, const node *n) break; case star_expr: - if (TYPE(CHILD(n, 0)) == STAR) - return ast_for_starred(c, n); - /* Fall through to generic case. */ + return ast_for_starred(c, n); /* The next five cases all handle BinOps. The main body of code is the same in each case, but the switch turned inside out to reuse the code for each type of operator. -- cgit v1.2.1 From c7963af8d161e72e93509de6445d06bad6967ecf Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 3 Oct 2009 20:27:13 +0000 Subject: Merged revisions 75223 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75223 | benjamin.peterson | 2009-10-03 15:23:24 -0500 (Sat, 03 Oct 2009) | 1 line #7050 fix a SystemError when using tuple unpacking and augmented assignment ........ --- Python/ast.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index dfcc8e32e1..8a35a1206f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2115,6 +2115,19 @@ ast_for_expr_stmt(struct compiling *c, const node *n) return NULL; if(!set_context(c, expr1, Store, ch)) return NULL; + /* set_context checks that most expressions are not the left side. + Augmented assignments can only have a name, a subscript, or an + attribute on the left, though, so we have to explicitly check for + those. */ + switch (expr1->kind) { + case Name_kind: + case Attribute_kind: + case Subscript_kind: + break; + default: + ast_error(ch, "illegal expression for augmented assignment"); + return NULL; + } ch = CHILD(n, 2); if (TYPE(ch) == testlist) -- cgit v1.2.1 From 94be56fe981742b8657e2f07ecb86b5aca70711c Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Sun, 18 Oct 2009 14:25:35 +0000 Subject: Issue 7147 - remove ability to attempt to build Python without complex number support (was broken anyway) --- Python/ast.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 8a35a1206f..c3edea3534 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3177,17 +3177,13 @@ parsenumber(struct compiling *c, const char *s) const char *end; long x; double dx; -#ifndef WITHOUT_COMPLEX Py_complex compl; int imflag; -#endif assert(s != NULL); errno = 0; end = s + strlen(s) - 1; -#ifndef WITHOUT_COMPLEX imflag = *end == 'j' || *end == 'J'; -#endif if (s[0] == '0') { x = (long) PyOS_strtoul((char *)s, (char **)&end, 0); if (x < 0 && errno == 0) { @@ -3204,7 +3200,6 @@ parsenumber(struct compiling *c, const char *s) return PyLong_FromLong(x); } /* XXX Huge floats may silently fail */ -#ifndef WITHOUT_COMPLEX if (imflag) { compl.real = 0.; compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); @@ -3213,7 +3208,6 @@ parsenumber(struct compiling *c, const char *s) return PyComplex_FromCComplex(compl); } else -#endif { dx = PyOS_string_to_double(s, NULL, NULL); if (dx == -1.0 && PyErr_Occurred()) -- cgit v1.2.1 From 26ad1df9768ed894740d1f88993e146ecd627ea6 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 28 Oct 2009 21:59:39 +0000 Subject: in wide builds, avoid storing high unicode characters from source code with surrogates This is accomplished by decoding with utf-32 instead of utf-16 on all builds. The patch is by Adam Olsen. --- Python/ast.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index c3edea3534..c6a6417efe 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3246,10 +3246,11 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons u = NULL; } else { /* check for integer overflow */ - if (len > PY_SIZE_MAX / 4) + if (len > PY_SIZE_MAX / 6) return NULL; - /* "\XX" may become "\u005c\uHHLL" (12 bytes) */ - u = PyBytes_FromStringAndSize((char *)NULL, len * 4); + /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 + "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ + u = PyBytes_FromStringAndSize((char *)NULL, len * 6); if (u == NULL) return NULL; p = buf = PyBytes_AsString(u); @@ -3266,20 +3267,24 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons PyObject *w; char *r; Py_ssize_t rn, i; - w = decode_utf8(c, &s, end, "utf-16-be"); + w = decode_utf8(c, &s, end, "utf-32-be"); if (w == NULL) { Py_DECREF(u); return NULL; } r = PyBytes_AS_STRING(w); rn = Py_SIZE(w); - assert(rn % 2 == 0); - for (i = 0; i < rn; i += 2) { - sprintf(p, "\\u%02x%02x", + assert(rn % 4 == 0); + for (i = 0; i < rn; i += 4) { + sprintf(p, "\\U%02x%02x%02x%02x", r[i + 0] & 0xFF, - r[i + 1] & 0xFF); - p += 6; + r[i + 1] & 0xFF, + r[i + 2] & 0xFF, + r[i + 3] & 0xFF); + p += 10; } + /* Should be impossible to overflow */ + assert(p - buf <= Py_SIZE(u)); Py_DECREF(w); } else { *p++ = *s++; -- cgit v1.2.1 From 567b94adaaceb622c33f9be1998735dfb95f1707 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 May 2010 15:52:27 +0000 Subject: Recorded merge of revisions 81029 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........ --- Python/ast.c | 190 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 95 insertions(+), 95 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index c6a6417efe..0703abc9a7 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -58,19 +58,19 @@ new_identifier(const char* n, PyArena *arena) /* Check whether there are non-ASCII characters in the identifier; if so, normalize to NFKC. */ for (; *u; u++) { - if (*u >= 128) { - PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); - PyObject *id2; - if (!m) - return NULL; - id2 = PyObject_CallMethod(m, "normalize", "sO", "NFKC", id); - Py_DECREF(m); - if (!id2) - return NULL; - Py_DECREF(id); - id = id2; - break; - } + if (*u >= 128) { + PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); + PyObject *id2; + if (!m) + return NULL; + id2 = PyObject_CallMethod(m, "normalize", "sO", "NFKC", id); + Py_DECREF(m); + if (!id2) + return NULL; + Py_DECREF(id); + id = id2; + break; + } } PyUnicode_InternInPlace(&id); PyArena_AddPyObject(arena, id); @@ -226,7 +226,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, c.c_encoding = STR(n); n = CHILD(n, 0); } else { - /* PEP 3120 */ + /* PEP 3120 */ c.c_encoding = "utf-8"; } c.c_arena = arena; @@ -481,8 +481,8 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) expr_name = "conditional expression"; break; default: - PyErr_Format(PyExc_SystemError, - "unexpected expression in assignment %d (line %d)", + PyErr_Format(PyExc_SystemError, + "unexpected expression in assignment %d (line %d)", e->kind, e->lineno); return 0; } @@ -497,7 +497,7 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) } /* If the LHS is a list or tuple, we need to set the assignment - context for all the contained elements. + context for all the contained elements. */ if (s) { int i; @@ -603,7 +603,7 @@ ast_for_comp_op(struct compiling *c, const node *n) static asdl_seq * seq_for_testlist(struct compiling *c, const node *n) { - /* testlist: test (',' test)* [','] + /* testlist: test (',' test)* [','] testlist_star_expr: test|star_expr (',' test|star_expr)* [','] */ asdl_seq *seq; @@ -616,7 +616,7 @@ seq_for_testlist(struct compiling *c, const node *n) return NULL; for (i = 0; i < NCH(n); i += 2) { - const node *ch = CHILD(n, i); + const node *ch = CHILD(n, i); assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr); expression = ast_for_expr(c, ch); @@ -726,7 +726,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, } return i; error: - return -1; + return -1; } /* Create AST for argument list. */ @@ -739,12 +739,12 @@ ast_for_arguments(struct compiling *c, const node *n) parameters: '(' [typedargslist] ')' typedargslist: ((tfpdef ['=' test] ',')* - ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] + ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) tfpdef: NAME [':' test] varargslist: ((vfpdef ['=' test] ',')* - ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] + ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) vfpdef: NAME @@ -785,7 +785,7 @@ ast_for_arguments(struct compiling *c, const node *n) if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; if (TYPE(ch) == EQUAL) nposdefaults++; } - /* count the number of keyword only args & + /* count the number of keyword only args & defaults for keyword only args */ for ( ; i < NCH(n); ++i) { ch = CHILD(n, i); @@ -799,11 +799,11 @@ ast_for_arguments(struct compiling *c, const node *n) asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); if (!kwonlyargs && nkwonlyargs) goto error; - posdefaults = (nposdefaults ? + posdefaults = (nposdefaults ? asdl_seq_new(nposdefaults, c->c_arena) : NULL); if (!posdefaults && nposdefaults) goto error; - /* The length of kwonlyargs and kwdefaults are same + /* The length of kwonlyargs and kwdefaults are same since we set NULL as default for keyword only argument w/o default - we have sequence data structure, but no dictionary */ kwdefaults = (nkwonlyargs ? @@ -840,7 +840,7 @@ ast_for_arguments(struct compiling *c, const node *n) found_default = 1; } else if (found_default) { - ast_error(n, + ast_error(n, "non-default argument follows default argument"); goto error; } @@ -852,7 +852,7 @@ ast_for_arguments(struct compiling *c, const node *n) break; case STAR: if (i+1 >= NCH(n)) { - ast_error(CHILD(n, i), + ast_error(CHILD(n, i), "named arguments must follow bare *"); goto error; } @@ -953,15 +953,15 @@ ast_for_decorator(struct compiling *c, const node *n) /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */ expr_ty d = NULL; expr_ty name_expr; - + REQ(n, decorator); REQ(CHILD(n, 0), AT); REQ(RCHILD(n, -1), NEWLINE); - + name_expr = ast_for_dotted_name(c, CHILD(n, 1)); if (!name_expr) return NULL; - + if (NCH(n) == 3) { /* No arguments */ d = name_expr; name_expr = NULL; @@ -989,12 +989,12 @@ ast_for_decorators(struct compiling *c, const node *n) asdl_seq* decorator_seq; expr_ty d; int i; - + REQ(n, decorators); decorator_seq = asdl_seq_new(NCH(n), c->c_arena); if (!decorator_seq) return NULL; - + for (i = 0; i < NCH(n); i++) { d = ast_for_decorator(c, CHILD(n, i)); if (!d) @@ -1052,7 +1052,7 @@ ast_for_decorated(struct compiling *c, const node *n) return NULL; assert(TYPE(CHILD(n, 1)) == funcdef || - TYPE(CHILD(n, 1)) == classdef); + TYPE(CHILD(n, 1)) == classdef); if (TYPE(CHILD(n, 1)) == funcdef) { thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq); @@ -1100,7 +1100,7 @@ ast_for_lambdef(struct compiling *c, const node *n) static expr_ty ast_for_ifexpr(struct compiling *c, const node *n) { - /* test: or_test 'if' or_test 'else' test */ + /* test: or_test 'if' or_test 'else' test */ expr_ty expression, body, orelse; assert(NCH(n) == 5); @@ -1197,9 +1197,9 @@ ast_for_comprehension(struct compiling *c, const node *n) asdl_seq *t; expr_ty expression, first; node *for_ch; - + REQ(n, comp_for); - + for_ch = CHILD(n, 1); t = ast_for_exprlist(c, for_ch, Store); if (!t) @@ -1223,7 +1223,7 @@ ast_for_comprehension(struct compiling *c, const node *n) if (NCH(n) == 5) { int j, n_ifs; asdl_seq *ifs; - + n = CHILD(n, 4); n_ifs = count_comp_ifs(c, n); if (n_ifs == -1) @@ -1237,7 +1237,7 @@ ast_for_comprehension(struct compiling *c, const node *n) REQ(n, comp_iter); n = CHILD(n, 0); REQ(n, comp_if); - + expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; @@ -1262,13 +1262,13 @@ ast_for_itercomp(struct compiling *c, const node *n, int type) argument: [test '='] test [comp_for] # Really [keyword '='] test */ expr_ty elt; asdl_seq *comps; - + assert(NCH(n) > 1); - + elt = ast_for_expr(c, CHILD(n, 0)); if (!elt) return NULL; - + comps = ast_for_comprehension(c, CHILD(n, 1)); if (!comps) return NULL; @@ -1289,21 +1289,21 @@ ast_for_dictcomp(struct compiling *c, const node *n) { expr_ty key, value; asdl_seq *comps; - + assert(NCH(n) > 3); REQ(CHILD(n, 1), COLON); - + key = ast_for_expr(c, CHILD(n, 0)); if (!key) return NULL; value = ast_for_expr(c, CHILD(n, 2)); if (!value) return NULL; - + comps = ast_for_comprehension(c, CHILD(n, 3)); if (!comps) return NULL; - + return DictComp(key, value, comps, LINENO(n), n->n_col_offset, c->c_arena); } @@ -1338,7 +1338,7 @@ ast_for_atom(struct compiling *c, const node *n) */ node *ch = CHILD(n, 0); int bytesmode = 0; - + switch (TYPE(ch)) { case NAME: { /* All names start in Load context, but may later be @@ -1389,24 +1389,24 @@ ast_for_atom(struct compiling *c, const node *n) return Ellipsis(LINENO(n), n->n_col_offset, c->c_arena); case LPAR: /* some parenthesized expressions */ ch = CHILD(n, 1); - + if (TYPE(ch) == RPAR) return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); - + if (TYPE(ch) == yield_expr) return ast_for_expr(c, ch); - /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ + /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == comp_for)) return ast_for_genexp(c, ch); return ast_for_testlist(c, ch); case LSQB: /* list (or list comprehension) */ ch = CHILD(n, 1); - + if (TYPE(ch) == RSQB) return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); - + REQ(ch, testlist_comp); if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { asdl_seq *elts = seq_for_testlist(c, ch); @@ -1453,14 +1453,14 @@ ast_for_atom(struct compiling *c, const node *n) keys = asdl_seq_new(size, c->c_arena); if (!keys) return NULL; - + values = asdl_seq_new(size, c->c_arena); if (!values) return NULL; - + for (i = 0; i < NCH(ch); i += 4) { expr_ty expression; - + expression = ast_for_expr(c, CHILD(ch, i)); if (!expression) return NULL; @@ -1498,10 +1498,10 @@ ast_for_slice(struct compiling *c, const node *n) if (NCH(n) == 1 && TYPE(ch) == test) { /* 'step' variable hold no significance in terms of being used over other vars */ - step = ast_for_expr(c, ch); + step = ast_for_expr(c, ch); if (!step) return NULL; - + return Index(step, c->c_arena); } @@ -1551,7 +1551,7 @@ static expr_ty ast_for_binop(struct compiling *c, const node *n) { /* Must account for a sequence of expressions. - How should A op B op C by represented? + How should A op B op C by represented? BinOp(BinOp(A, op, B), op, C). */ @@ -1589,10 +1589,10 @@ ast_for_binop(struct compiling *c, const node *n) if (!tmp) return NULL; - tmp_result = BinOp(result, newoperator, tmp, + tmp_result = BinOp(result, newoperator, tmp, LINENO(next_oper), next_oper->n_col_offset, c->c_arena); - if (!tmp_result) + if (!tmp_result) return NULL; result = tmp_result; } @@ -1602,7 +1602,7 @@ ast_for_binop(struct compiling *c, const node *n) static expr_ty ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) { - /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME + /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] */ @@ -1633,7 +1633,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) c->c_arena); } else { - /* The grammar is ambiguous here. The ambiguity is resolved + /* The grammar is ambiguous here. The ambiguity is resolved by treating the sequence as a tuple literal if there are no slice features. */ @@ -1786,7 +1786,7 @@ ast_for_expr(struct compiling *c, const node *n) /* handle the full range of simple expressions test: or_test ['if' or_test 'else' test] | lambdef test_nocond: or_test | lambdef_nocond - or_test: and_test ('or' and_test)* + or_test: and_test ('or' and_test)* and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* @@ -1874,7 +1874,7 @@ ast_for_expr(struct compiling *c, const node *n) if (!expression) { return NULL; } - + asdl_seq_SET(ops, i / 2, newoperator); asdl_seq_SET(cmps, i / 2, expression); } @@ -1882,14 +1882,14 @@ ast_for_expr(struct compiling *c, const node *n) if (!expression) { return NULL; } - + return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset, c->c_arena); } break; case star_expr: - return ast_for_starred(c, n); + return ast_for_starred(c, n); /* The next five cases all handle BinOps. The main body of code is the same in each case, but the switch turned inside out to reuse the code for each type of operator. @@ -1998,7 +1998,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) if (!e) return NULL; asdl_seq_SET(args, nargs++, e); - } + } else if (TYPE(CHILD(ch, 1)) == comp_for) { e = ast_for_genexp(c, ch); if (!e) @@ -2010,7 +2010,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) identifier key, tmp; int k; - /* CHILD(ch, 0) is test, but must be an identifier? */ + /* CHILD(ch, 0) is test, but must be an identifier? */ e = ast_for_expr(c, CHILD(ch, 0)); if (!e) return NULL; @@ -2026,8 +2026,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) ast_error(CHILD(ch, 0), "keyword can't be an expression"); return NULL; } else if (forbidden_name(e->v.Name.id, ch, 1)) { - return NULL; - } + return NULL; + } key = e->v.Name.id; for (k = 0; k < nkeywords; k++) { tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg; @@ -2090,7 +2090,7 @@ static stmt_ty ast_for_expr_stmt(struct compiling *c, const node *n) { REQ(n, expr_stmt); - /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) + /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' @@ -2164,7 +2164,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) e = ast_for_testlist(c, ch); /* set context to assign */ - if (!e) + if (!e) return NULL; if (!set_context(c, e, Store, CHILD(n, i))) @@ -2211,7 +2211,7 @@ static stmt_ty ast_for_del_stmt(struct compiling *c, const node *n) { asdl_seq *expr_list; - + /* del_stmt: 'del' exprlist */ REQ(n, del_stmt); @@ -2349,7 +2349,7 @@ alias_for_import_name(struct compiling *c, const node *n, int store) int i; size_t len; char *s; - PyObject *uni; + PyObject *uni; len = 0; for (i = 0; i < NCH(n); i += 2) @@ -2370,13 +2370,13 @@ alias_for_import_name(struct compiling *c, const node *n, int store) } --s; *s = '\0'; - uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), - PyBytes_GET_SIZE(str), - NULL); - Py_DECREF(str); - if (!uni) - return NULL; - str = uni; + uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), + PyBytes_GET_SIZE(str), + NULL); + Py_DECREF(str); + if (!uni) + return NULL; + str = uni; PyUnicode_InternInPlace(&str); PyArena_AddPyObject(c->c_arena, str); return alias(str, NULL, c->c_arena); @@ -2433,7 +2433,7 @@ ast_for_import_stmt(struct compiling *c, const node *n) int idx, ndots = 0; alias_ty mod = NULL; identifier modname = NULL; - + /* Count the number of dots (for relative imports) and check for the optional module name */ for (idx = 1; idx < NCH(n); idx++) { @@ -2444,7 +2444,7 @@ ast_for_import_stmt(struct compiling *c, const node *n) idx++; break; } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { - /* three consecutive dots are tokenized as one ELLIPSIS */ + /* three consecutive dots are tokenized as one ELLIPSIS */ ndots += 3; continue; } else if (TYPE(CHILD(n, idx)) != DOT) { @@ -2571,7 +2571,7 @@ ast_for_assert_stmt(struct compiling *c, const node *n) expr2 = ast_for_expr(c, CHILD(n, 3)); if (!expr2) return NULL; - + return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, @@ -2598,7 +2598,7 @@ ast_for_suite(struct compiling *c, const node *n) if (TYPE(CHILD(n, 0)) == simple_stmt) { n = CHILD(n, 0); /* simple_stmt always ends with a NEWLINE, - and may have a trailing SEMI + and may have a trailing SEMI */ end = NCH(n) - 1; if (TYPE(CHILD(n, end - 1)) == SEMI) @@ -2663,10 +2663,10 @@ ast_for_if_stmt(struct compiling *c, const node *n) expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; - suite_seq = ast_for_suite(c, CHILD(n, 3)); + suite_seq = ast_for_suite(c, CHILD(n, 3)); if (!suite_seq) return NULL; - + return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena); } @@ -2724,8 +2724,8 @@ ast_for_if_stmt(struct compiling *c, const node *n) if (!suite_seq2) return NULL; - asdl_seq_SET(orelse, 0, - If(expression, suite_seq, suite_seq2, + asdl_seq_SET(orelse, 0, + If(expression, suite_seq, suite_seq2, LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset, c->c_arena)); @@ -2746,7 +2746,7 @@ ast_for_if_stmt(struct compiling *c, const node *n) return NULL; asdl_seq_SET(newobj, 0, - If(expression, suite_seq, orelse, + If(expression, suite_seq, orelse, LINENO(CHILD(n, off)), CHILD(n, off)->n_col_offset, c->c_arena)); orelse = newobj; @@ -2943,7 +2943,7 @@ ast_for_try_stmt(struct compiling *c, const node *n) ast_error(n, "malformed 'try' statement"); return NULL; } - + if (n_except > 0) { int i; stmt_ty except_st; @@ -3160,8 +3160,8 @@ ast_for_stmt(struct compiling *c, const node *n) return ast_for_funcdef(c, ch, NULL); case classdef: return ast_for_classdef(c, ch, NULL); - case decorated: - return ast_for_decorated(c, ch); + case decorated: + return ast_for_decorated(c, ch); default: PyErr_Format(PyExc_SystemError, "unhandled small_stmt: TYPE=%d NCH=%d\n", @@ -3317,7 +3317,7 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) if (quote == 'b' || quote == 'B') { quote = *++s; *bytesmode = 1; - } + } if (quote == 'r' || quote == 'R') { quote = *++s; rawmode = 1; @@ -3330,7 +3330,7 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) s++; len = strlen(s); if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, + PyErr_SetString(PyExc_OverflowError, "string to parse is too long"); return NULL; } @@ -3374,7 +3374,7 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) return PyBytes_FromStringAndSize(s, len); } else if (strcmp(c->c_encoding, "utf-8") == 0) { return PyUnicode_FromStringAndSize(s, len); - } else { + } else { return PyUnicode_DecodeLatin1(s, len, NULL); } } -- cgit v1.2.1 From af43f50cd72640f3e72f68fa7c789c45cdaac839 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 17 Jun 2010 12:33:22 +0000 Subject: Issue #9011: Remove buggy and unnecessary ST->AST compilation code dealing with unary minus applied to a constant. The removed code was mutating the ST, causing a second compilation to fail. (The peephole optimizer already takes care of optimizing this case, so there's no lost optimization opportunity here.) --- Python/ast.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 0703abc9a7..34dc30f04d 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1678,34 +1678,8 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) static expr_ty ast_for_factor(struct compiling *c, const node *n) { - node *pfactor, *ppower, *patom, *pnum; expr_ty expression; - /* If the unary - operator is applied to a constant, don't generate - a UNARY_NEGATIVE opcode. Just store the approriate value as a - constant. The peephole optimizer already does something like - this but it doesn't handle the case where the constant is - (sys.maxint - 1). In that case, we want a PyIntObject, not a - PyLongObject. - */ - if (TYPE(CHILD(n, 0)) == MINUS - && NCH(n) == 2 - && TYPE((pfactor = CHILD(n, 1))) == factor - && NCH(pfactor) == 1 - && TYPE((ppower = CHILD(pfactor, 0))) == power - && NCH(ppower) == 1 - && TYPE((patom = CHILD(ppower, 0))) == atom - && TYPE((pnum = CHILD(patom, 0))) == NUMBER) { - char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2); - if (s == NULL) - return NULL; - s[0] = '-'; - strcpy(s + 1, STR(pnum)); - PyObject_FREE(STR(pnum)); - STR(pnum) = s; - return ast_for_atom(c, patom); - } - expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; -- cgit v1.2.1 From cca93ba2bbe772b1e6b6982b3933f0532edbe2d1 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Thu, 19 Aug 2010 17:43:15 +0000 Subject: Check the return values for all functions returning an ast node. Failure to do it may result in strange error messages or even crashes, in admittedly convoluted cases that are normally syntax errors, like: def f(*xx, __debug__): pass --- Python/ast.c | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 34dc30f04d..6ea830b8af 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -688,6 +688,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, case tfpdef: if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { expression = ast_for_expr(c, CHILD(n, i + 2)); + if (!expression) + goto error; asdl_seq_SET(kwdefaults, j, expression); i += 2; /* '=' and test */ } @@ -697,10 +699,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, if (NCH(ch) == 3) { /* ch is NAME ':' test */ annotation = ast_for_expr(c, CHILD(ch, 2)); - if (!annotation) { - ast_error(ch, "expected expression"); + if (!annotation) goto error; - } } else { annotation = NULL; @@ -794,22 +794,22 @@ ast_for_arguments(struct compiling *c, const node *n) } posargs = (nposargs ? asdl_seq_new(nposargs, c->c_arena) : NULL); if (!posargs && nposargs) - goto error; + return NULL; kwonlyargs = (nkwonlyargs ? asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); if (!kwonlyargs && nkwonlyargs) - goto error; + return NULL; posdefaults = (nposdefaults ? asdl_seq_new(nposdefaults, c->c_arena) : NULL); if (!posdefaults && nposdefaults) - goto error; + return NULL; /* The length of kwonlyargs and kwdefaults are same since we set NULL as default for keyword only argument w/o default - we have sequence data structure, but no dictionary */ kwdefaults = (nkwonlyargs ? asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); if (!kwdefaults && nkwonlyargs) - goto error; + return NULL; if (nposargs + nkwonlyargs > 255) { ast_error(n, "more than 255 arguments"); @@ -833,7 +833,7 @@ ast_for_arguments(struct compiling *c, const node *n) if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { expr_ty expression = ast_for_expr(c, CHILD(n, i + 2)); if (!expression) - goto error; + return NULL; assert(posdefaults != NULL); asdl_seq_SET(posdefaults, j++, expression); i += 2; @@ -842,11 +842,11 @@ ast_for_arguments(struct compiling *c, const node *n) else if (found_default) { ast_error(n, "non-default argument follows default argument"); - goto error; + return NULL; } arg = compiler_arg(c, ch); if (!arg) - goto error; + return NULL; asdl_seq_SET(posargs, k++, arg); i += 2; /* the name and the comma */ break; @@ -854,7 +854,7 @@ ast_for_arguments(struct compiling *c, const node *n) if (i+1 >= NCH(n)) { ast_error(CHILD(n, i), "named arguments must follow bare *"); - goto error; + return NULL; } ch = CHILD(n, i+1); /* tfpdef or COMMA */ if (TYPE(ch) == COMMA) { @@ -862,7 +862,7 @@ ast_for_arguments(struct compiling *c, const node *n) i += 2; /* now follows keyword only arguments */ res = handle_keywordonly_args(c, n, i, kwonlyargs, kwdefaults); - if (res == -1) goto error; + if (res == -1) return NULL; i = res; /* res has new position to process */ } else { @@ -874,6 +874,8 @@ ast_for_arguments(struct compiling *c, const node *n) if (NCH(ch) > 1) { /* there is an annotation on the vararg */ varargannotation = ast_for_expr(c, CHILD(ch, 2)); + if (!varargannotation) + return NULL; } i += 3; if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef @@ -881,7 +883,7 @@ ast_for_arguments(struct compiling *c, const node *n) int res = 0; res = handle_keywordonly_args(c, n, i, kwonlyargs, kwdefaults); - if (res == -1) goto error; + if (res == -1) return NULL; i = res; /* res has new position to process */ } } @@ -893,26 +895,24 @@ ast_for_arguments(struct compiling *c, const node *n) if (NCH(ch) > 1) { /* there is an annotation on the kwarg */ kwargannotation = ast_for_expr(c, CHILD(ch, 2)); + if (!kwargannotation) + return NULL; } if (!kwarg) - goto error; + return NULL; if (forbidden_name(kwarg, CHILD(ch, 0), 0)) - goto error; + return NULL; i += 3; break; default: PyErr_Format(PyExc_SystemError, "unexpected node in varargslist: %d @ %d", TYPE(ch), i); - goto error; + return NULL; } } return arguments(posargs, vararg, varargannotation, kwonlyargs, kwarg, kwargannotation, posdefaults, kwdefaults, c->c_arena); - error: - Py_XDECREF(vararg); - Py_XDECREF(kwarg); - return NULL; } static expr_ty @@ -997,9 +997,9 @@ ast_for_decorators(struct compiling *c, const node *n) for (i = 0; i < NCH(n); i++) { d = ast_for_decorator(c, CHILD(n, i)); - if (!d) - return NULL; - asdl_seq_SET(decorator_seq, i, d); + if (!d) + return NULL; + asdl_seq_SET(decorator_seq, i, d); } return decorator_seq; } @@ -1027,7 +1027,7 @@ ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) if (TYPE(CHILD(n, name_i+2)) == RARROW) { returns = ast_for_expr(c, CHILD(n, name_i + 3)); if (!returns) - return NULL; + return NULL; name_i += 2; } body = ast_for_suite(c, CHILD(n, name_i + 3)); @@ -2136,11 +2136,10 @@ ast_for_expr_stmt(struct compiling *c, const node *n) return NULL; } e = ast_for_testlist(c, ch); - - /* set context to assign */ if (!e) return NULL; + /* set context to assign */ if (!set_context(c, e, Store, CHILD(n, i))) return NULL; @@ -2960,6 +2959,8 @@ ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content) REQ(n, with_item); context_expr = ast_for_expr(c, CHILD(n, 0)); + if (!context_expr) + return NULL; if (NCH(n) == 3) { optional_vars = ast_for_expr(c, CHILD(n, 2)); -- cgit v1.2.1 From 79af57d60b94325a98a0b602e8cf06f5c9dafd6b Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Thu, 19 Aug 2010 21:32:38 +0000 Subject: Add tests for r84209 (crashes in the Ast builder) Also remove one tab, and move a check closer to the possible failure. --- Python/ast.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 6ea830b8af..9f6b7eaa8a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -689,7 +689,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { expression = ast_for_expr(c, CHILD(n, i + 2)); if (!expression) - goto error; + goto error; asdl_seq_SET(kwdefaults, j, expression); i += 2; /* '=' and test */ } @@ -892,14 +892,14 @@ ast_for_arguments(struct compiling *c, const node *n) ch = CHILD(n, i+1); /* tfpdef */ assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef); kwarg = NEW_IDENTIFIER(CHILD(ch, 0)); + if (!kwarg) + return NULL; if (NCH(ch) > 1) { /* there is an annotation on the kwarg */ kwargannotation = ast_for_expr(c, CHILD(ch, 2)); if (!kwargannotation) return NULL; } - if (!kwarg) - return NULL; if (forbidden_name(kwarg, CHILD(ch, 0), 0)) return NULL; i += 3; -- cgit v1.2.1 From c9651975ec1a9b373c4da03a83f5e5abe12b23b9 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 20 Sep 2010 23:02:10 +0000 Subject: add column offset to all syntax errors --- Python/ast.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 9f6b7eaa8a..38643f6a3b 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -90,7 +90,7 @@ new_identifier(const char* n, PyArena *arena) static int ast_error(const node *n, const char *errstr) { - PyObject *u = Py_BuildValue("zi", errstr, LINENO(n)); + PyObject *u = Py_BuildValue("zii", errstr, LINENO(n), n->n_col_offset); if (!u) return 0; PyErr_SetObject(PyExc_SyntaxError, u); @@ -101,7 +101,7 @@ ast_error(const node *n, const char *errstr) static void ast_error_finish(const char *filename) { - PyObject *type, *value, *tback, *errstr, *loc, *tmp; + PyObject *type, *value, *tback, *errstr, *offset, *loc, *tmp; long lineno; assert(PyErr_Occurred()); @@ -118,6 +118,11 @@ ast_error_finish(const char *filename) Py_DECREF(errstr); return; } + offset = PyTuple_GetItem(value, 2); + if (!offset) { + Py_DECREF(errstr); + return; + } Py_DECREF(value); loc = PyErr_ProgramText(filename, lineno); @@ -125,7 +130,7 @@ ast_error_finish(const char *filename) Py_INCREF(Py_None); loc = Py_None; } - tmp = Py_BuildValue("(zlOO)", filename, lineno, Py_None, loc); + tmp = Py_BuildValue("(zlOO)", filename, lineno, offset, loc); Py_DECREF(loc); if (!tmp) { Py_DECREF(errstr); -- cgit v1.2.1 From 24c7fa3b4d2daf8a3b9d1b3c143e6a55b5b2b4d5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Oct 2010 13:14:10 +0000 Subject: Issue #9713, #10114: Parser functions (eg. PyParser_ASTFromFile) expects filenames encoded to the filesystem encoding with surrogateescape error handler (to support undecodable bytes), instead of UTF-8 in strict mode. --- Python/ast.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index 38643f6a3b..b9beef88ef 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -102,6 +102,7 @@ static void ast_error_finish(const char *filename) { PyObject *type, *value, *tback, *errstr, *offset, *loc, *tmp; + PyObject *filename_obj; long lineno; assert(PyErr_Occurred()); @@ -130,7 +131,11 @@ ast_error_finish(const char *filename) Py_INCREF(Py_None); loc = Py_None; } - tmp = Py_BuildValue("(zlOO)", filename, lineno, offset, loc); + filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj != NULL) + tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, offset, loc); + else + tmp = NULL; Py_DECREF(loc); if (!tmp) { Py_DECREF(errstr); -- cgit v1.2.1 From a92ba0800250ece57c8b4cfa5f8d8fc1558fd024 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Oct 2010 13:42:53 +0000 Subject: Fix ast_error_finish() and err_input(): filename can be NULL Fix my previous commit (r85569). --- Python/ast.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index b9beef88ef..d1aa61640a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -131,7 +131,12 @@ ast_error_finish(const char *filename) Py_INCREF(Py_None); loc = Py_None; } - filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename != NULL) + filename_obj = PyUnicode_DecodeFSDefault(filename); + else { + Py_INCREF(Py_None); + filename_obj = Py_None; + } if (filename_obj != NULL) tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, offset, loc); else -- cgit v1.2.1 From c16ad2eeb23a20667e832e09ad88e012952d8988 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 30 Nov 2010 09:41:01 +0000 Subject: Remove redundant includes of headers that are already included by Python.h. --- Python/ast.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Python/ast.c') diff --git a/Python/ast.c b/Python/ast.c index d1aa61640a..4edf335c33 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -7,7 +7,6 @@ #include "Python-ast.h" #include "grammar.h" #include "node.h" -#include "pyarena.h" #include "ast.h" #include "token.h" #include "parsetok.h" -- cgit v1.2.1