summaryrefslogtreecommitdiff
path: root/Python/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c695
1 files changed, 406 insertions, 289 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 574a3d817c..88e47450b6 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -31,7 +31,7 @@ static asdl_seq *ast_for_exprlist(struct compiling *, const node *,
expr_context_ty);
static expr_ty ast_for_testlist(struct compiling *, const node *);
static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *);
-static expr_ty ast_for_testlist_gexp(struct compiling *, const node *);
+static expr_ty ast_for_testlist_comp(struct compiling *, const node *);
/* Note different signature for ast_for_call */
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
@@ -44,6 +44,9 @@ static PyObject *parsestrplus(struct compiling *, const node *n);
#define LINENO(n) ((n)->n_lineno)
#endif
+#define COMP_GENEXP 0
+#define COMP_SETCOMP 1
+
static identifier
new_identifier(const char* n, PyArena *arena) {
PyObject* id = PyString_InternFromString(n);
@@ -131,10 +134,17 @@ static int
forbidden_check(struct compiling *c, const node *n, const char *x)
{
if (!strcmp(x, "None"))
- return ast_error(n, "assignment to None");
- if (Py_Py3kWarningFlag && !(strcmp(x, "True") && strcmp(x, "False")) &&
- !ast_warn(c, n, "assignment to True or False is forbidden in 3.x"))
- return 0;
+ return ast_error(n, "cannot assign to None");
+ if (!strcmp(x, "__debug__"))
+ return ast_error(n, "cannot assign to __debug__");
+ if (Py_Py3kWarningFlag) {
+ if (!(strcmp(x, "True") && strcmp(x, "False")) &&
+ !ast_warn(c, n, "assignment to True or False is forbidden in 3.x"))
+ return 0;
+ if (!strcmp(x, "nonlocal") &&
+ !ast_warn(c, n, "nonlocal is a keyword in 3.x"))
+ return 0;
+ }
return 1;
}
@@ -190,7 +200,7 @@ num_stmts(const node *n)
default: {
char buf[128];
- sprintf(buf, "Non-statement found: %d %d\n",
+ sprintf(buf, "Non-statement found: %d %d",
TYPE(n), NCH(n));
Py_FatalError(buf);
}
@@ -261,7 +271,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
case eval_input: {
expr_ty testlist_ast;
- /* XXX Why not gen_for here? */
+ /* XXX Why not comp_for here? */
testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
if (!testlist_ast)
goto error;
@@ -395,10 +405,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";
@@ -420,7 +433,14 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
case ListComp_kind:
expr_name = "list comprehension";
break;
+ case SetComp_kind:
+ expr_name = "set comprehension";
+ break;
+ case DictComp_kind:
+ expr_name = "dict comprehension";
+ break;
case Dict_kind:
+ case Set_kind:
case Num_kind:
case Str_kind:
expr_name = "literal";
@@ -435,8 +455,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;
}
@@ -451,7 +471,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;
@@ -563,7 +583,7 @@ seq_for_testlist(struct compiling *c, const node *n)
int i;
assert(TYPE(n) == testlist ||
TYPE(n) == listmaker ||
- TYPE(n) == testlist_gexp ||
+ TYPE(n) == testlist_comp ||
TYPE(n) == testlist_safe ||
TYPE(n) == testlist1);
@@ -668,10 +688,10 @@ ast_for_arguments(struct compiling *c, const node *n)
}
args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
if (!args && n_args)
- return NULL; /* Don't need to goto error; no objects allocated */
+ return NULL;
defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
if (!defaults && n_defaults)
- return NULL; /* Don't need to goto error; no objects allocated */
+ return NULL;
/* fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
@@ -691,7 +711,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(defaults != NULL);
asdl_seq_SET(defaults, j++, expression);
i += 2;
@@ -702,11 +722,11 @@ ast_for_arguments(struct compiling *c, const node *n)
def f((x, (y))): pass will just incur the tuple unpacking warning. */
if (parenthesized && !complex_args) {
ast_error(n, "parenthesized arg with default");
- goto error;
+ return NULL;
}
- ast_error(n,
+ ast_error(n,
"non-default argument follows default argument");
- goto error;
+ return NULL;
}
if (NCH(ch) == 3) {
ch = CHILD(ch, 1);
@@ -715,11 +735,11 @@ ast_for_arguments(struct compiling *c, const node *n)
/* We have complex arguments, setup for unpacking. */
if (Py_Py3kWarningFlag && !ast_warn(c, ch,
"tuple parameter unpacking has been removed in 3.x"))
- goto error;
+ return NULL;
complex_args = 1;
asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
if (!asdl_seq_GET(args, k-1))
- goto error;
+ return NULL;
} else {
/* def foo((x)): setup for checking NAME below. */
/* Loop because there can be many parens and tuple
@@ -734,55 +754,50 @@ ast_for_arguments(struct compiling *c, const node *n)
PyObject *id;
expr_ty name;
if (!forbidden_check(c, n, STR(CHILD(ch, 0))))
- goto error;
+ return NULL;
id = NEW_IDENTIFIER(CHILD(ch, 0));
if (!id)
- goto error;
+ return NULL;
name = Name(id, Param, LINENO(ch), ch->n_col_offset,
c->c_arena);
if (!name)
- goto error;
+ return NULL;
asdl_seq_SET(args, k++, name);
-
+
}
i += 2; /* the name and the comma */
if (parenthesized && Py_Py3kWarningFlag &&
!ast_warn(c, ch, "parenthesized argument names "
"are invalid in 3.x"))
- goto error;
+ return NULL;
break;
}
case STAR:
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
- goto error;
+ return NULL;
vararg = NEW_IDENTIFIER(CHILD(n, i+1));
if (!vararg)
- goto error;
+ return NULL;
i += 3;
break;
case DOUBLESTAR:
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
- goto error;
+ return NULL;
kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
if (!kwarg)
- 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(args, vararg, kwarg, defaults, c->c_arena);
-
- error:
- Py_XDECREF(vararg);
- Py_XDECREF(kwarg);
- return NULL;
}
static expr_ty
@@ -823,15 +838,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;
@@ -859,17 +874,17 @@ 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)
- return NULL;
- asdl_seq_SET(decorator_seq, i, d);
+ if (!d)
+ return NULL;
+ asdl_seq_SET(decorator_seq, i, d);
}
return decorator_seq;
}
@@ -961,7 +976,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);
@@ -1052,7 +1067,7 @@ ast_for_listcomp(struct compiling *c, const node *n)
list_if: 'if' test [list_iter]
testlist_safe: test [(',' test)+ [',']]
*/
- expr_ty elt;
+ expr_ty elt, first;
asdl_seq *listcomps;
int i, n_fors;
node *ch;
@@ -1078,9 +1093,9 @@ ast_for_listcomp(struct compiling *c, const node *n)
asdl_seq *t;
expr_ty expression;
node *for_ch;
-
+
REQ(ch, list_for);
-
+
for_ch = CHILD(ch, 1);
t = ast_for_exprlist(c, for_ch, Store);
if (!t)
@@ -1088,15 +1103,15 @@ ast_for_listcomp(struct compiling *c, const node *n)
expression = ast_for_testlist(c, CHILD(ch, 3));
if (!expression)
return NULL;
-
+
/* 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)
- lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
- c->c_arena);
+ lc = comprehension(first, expression, NULL, c->c_arena);
else
- lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+ lc = comprehension(Tuple(t, Store, first->lineno, first->col_offset,
c->c_arena),
expression, NULL, c->c_arena);
if (!lc)
@@ -1120,11 +1135,11 @@ ast_for_listcomp(struct compiling *c, const node *n)
REQ(ch, list_iter);
ch = CHILD(ch, 0);
REQ(ch, list_if);
-
+
list_for_expr = ast_for_expr(c, CHILD(ch, 1));
if (!list_for_expr)
return NULL;
-
+
asdl_seq_SET(ifs, j, list_for_expr);
if (NCH(ch) == 3)
ch = CHILD(ch, 2);
@@ -1140,60 +1155,60 @@ ast_for_listcomp(struct compiling *c, const node *n)
return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);
}
-/* Count the number of 'for' loops in a generator expression.
+/*
+ Count the number of 'for' loops in a comprehension.
- Helper for ast_for_genexp().
+ Helper for ast_for_comprehension().
*/
static int
-count_gen_fors(struct compiling *c, const node *n)
+count_comp_fors(struct compiling *c, const node *n)
{
int n_fors = 0;
- node *ch = CHILD(n, 1);
- count_gen_for:
+ count_comp_for:
n_fors++;
- REQ(ch, gen_for);
- if (NCH(ch) == 5)
- ch = CHILD(ch, 4);
+ REQ(n, comp_for);
+ if (NCH(n) == 5)
+ n = CHILD(n, 4);
else
return n_fors;
- count_gen_iter:
- REQ(ch, gen_iter);
- ch = CHILD(ch, 0);
- if (TYPE(ch) == gen_for)
- goto count_gen_for;
- else if (TYPE(ch) == gen_if) {
- if (NCH(ch) == 3) {
- ch = CHILD(ch, 2);
- goto count_gen_iter;
+ count_comp_iter:
+ REQ(n, comp_iter);
+ n = CHILD(n, 0);
+ if (TYPE(n) == comp_for)
+ goto count_comp_for;
+ else if (TYPE(n) == comp_if) {
+ if (NCH(n) == 3) {
+ n = CHILD(n, 2);
+ goto count_comp_iter;
}
else
return n_fors;
}
-
+
/* Should never be reached */
PyErr_SetString(PyExc_SystemError,
- "logic error in count_gen_fors");
+ "logic error in count_comp_fors");
return -1;
}
-/* Count the number of 'if' statements in a generator expression.
+/* Count the number of 'if' statements in a comprehension.
- Helper for ast_for_genexp().
+ Helper for ast_for_comprehension().
*/
static int
-count_gen_ifs(struct compiling *c, const node *n)
+count_comp_ifs(struct compiling *c, const node *n)
{
int n_ifs = 0;
while (1) {
- REQ(n, gen_iter);
- if (TYPE(CHILD(n, 0)) == gen_for)
+ REQ(n, comp_iter);
+ if (TYPE(CHILD(n, 0)) == comp_for)
return n_ifs;
n = CHILD(n, 0);
- REQ(n, gen_if);
+ REQ(n, comp_if);
n_ifs++;
if (NCH(n) == 2)
return n_ifs;
@@ -1201,68 +1216,54 @@ count_gen_ifs(struct compiling *c, const node *n)
}
}
-/* TODO(jhylton): Combine with list comprehension code? */
-static expr_ty
-ast_for_genexp(struct compiling *c, const node *n)
+static asdl_seq *
+ast_for_comprehension(struct compiling *c, const node *n)
{
- /* testlist_gexp: test ( gen_for | (',' test)* [','] )
- argument: [test '='] test [gen_for] # Really [keyword '='] test */
- expr_ty elt;
- asdl_seq *genexps;
int i, n_fors;
- node *ch;
-
- assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));
- assert(NCH(n) > 1);
-
- elt = ast_for_expr(c, CHILD(n, 0));
- if (!elt)
- return NULL;
-
- n_fors = count_gen_fors(c, n);
+ asdl_seq *comps;
+
+ n_fors = count_comp_fors(c, n);
if (n_fors == -1)
return NULL;
- genexps = asdl_seq_new(n_fors, c->c_arena);
- if (!genexps)
+ comps = asdl_seq_new(n_fors, c->c_arena);
+ if (!comps)
return NULL;
- ch = CHILD(n, 1);
for (i = 0; i < n_fors; i++) {
- comprehension_ty ge;
+ comprehension_ty comp;
asdl_seq *t;
- expr_ty expression;
+ expr_ty expression, first;
node *for_ch;
-
- REQ(ch, gen_for);
-
- for_ch = CHILD(ch, 1);
+
+ REQ(n, comp_for);
+
+ for_ch = CHILD(n, 1);
t = ast_for_exprlist(c, for_ch, Store);
if (!t)
return NULL;
- expression = ast_for_expr(c, CHILD(ch, 3));
+ expression = ast_for_expr(c, CHILD(n, 3));
if (!expression)
return NULL;
/* 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)
- ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
- NULL, c->c_arena);
+ comp = comprehension(first, expression, NULL, c->c_arena);
else
- ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+ comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset,
c->c_arena),
expression, NULL, c->c_arena);
-
- if (!ge)
+ if (!comp)
return NULL;
- if (NCH(ch) == 5) {
+ if (NCH(n) == 5) {
int j, n_ifs;
asdl_seq *ifs;
-
- ch = CHILD(ch, 4);
- n_ifs = count_gen_ifs(c, ch);
+
+ n = CHILD(n, 4);
+ n_ifs = count_comp_ifs(c, n);
if (n_ifs == -1)
return NULL;
@@ -1271,36 +1272,98 @@ ast_for_genexp(struct compiling *c, const node *n)
return NULL;
for (j = 0; j < n_ifs; j++) {
- REQ(ch, gen_iter);
- ch = CHILD(ch, 0);
- REQ(ch, gen_if);
-
- expression = ast_for_expr(c, CHILD(ch, 1));
+ REQ(n, comp_iter);
+ n = CHILD(n, 0);
+ REQ(n, comp_if);
+
+ expression = ast_for_expr(c, CHILD(n, 1));
if (!expression)
return NULL;
asdl_seq_SET(ifs, j, expression);
- if (NCH(ch) == 3)
- ch = CHILD(ch, 2);
+ if (NCH(n) == 3)
+ n = CHILD(n, 2);
}
- /* on exit, must guarantee that ch is a gen_for */
- if (TYPE(ch) == gen_iter)
- ch = CHILD(ch, 0);
- ge->ifs = ifs;
+ /* on exit, must guarantee that n is a comp_for */
+ if (TYPE(n) == comp_iter)
+ n = CHILD(n, 0);
+ comp->ifs = ifs;
}
- asdl_seq_SET(genexps, i, ge);
+ asdl_seq_SET(comps, i, comp);
}
-
- return GeneratorExp(elt, genexps, LINENO(n), n->n_col_offset, c->c_arena);
+ return comps;
+}
+
+static expr_ty
+ast_for_itercomp(struct compiling *c, const node *n, int type)
+{
+ 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;
+
+ if (type == COMP_GENEXP)
+ return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);
+ else if (type == COMP_SETCOMP)
+ return SetComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);
+ else
+ /* Should never happen */
+ return NULL;
+}
+
+static expr_ty
+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);
+}
+
+static expr_ty
+ast_for_genexp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument));
+ return ast_for_itercomp(c, n, COMP_GENEXP);
+}
+
+static expr_ty
+ast_for_setcomp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (dictorsetmaker));
+ return ast_for_itercomp(c, n, COMP_SETCOMP);
}
static expr_ty
ast_for_atom(struct compiling *c, const node *n)
{
- /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
+ /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']'
| '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
*/
node *ch = CHILD(n, 0);
-
+
switch (TYPE(ch)) {
case NAME: {
/* All names start in Load context, but may later be
@@ -1348,23 +1411,20 @@ ast_for_atom(struct compiling *c, const node *n)
}
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);
-
- if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
- return ast_for_genexp(c, ch);
-
- return ast_for_testlist_gexp(c, ch);
+
+ return ast_for_testlist_comp(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, listmaker);
if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
asdl_seq *elts = seq_for_testlist(c, ch);
@@ -1376,36 +1436,65 @@ ast_for_atom(struct compiling *c, const node *n)
else
return ast_for_listcomp(c, ch);
case LBRACE: {
- /* dictmaker: test ':' test (',' test ':' test)* [','] */
+ /* dictorsetmaker:
+ * (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ * (test (comp_for | (',' test)* [',']))
+ */
int i, size;
asdl_seq *keys, *values;
-
+
ch = CHILD(n, 1);
- size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
- 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)
+ if (TYPE(ch) == RBRACE) {
+ /* it's an empty dict */
+ return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+ } else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+ /* it's a simple set */
+ asdl_seq *elts;
+ size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
+ elts = asdl_seq_new(size, c->c_arena);
+ if (!elts)
+ return NULL;
+ for (i = 0; i < NCH(ch); i += 2) {
+ expr_ty expression;
+ expression = ast_for_expr(c, CHILD(ch, i));
+ if (!expression)
+ return NULL;
+ asdl_seq_SET(elts, i / 2, expression);
+ }
+ return Set(elts, LINENO(n), n->n_col_offset, c->c_arena);
+ } else if (TYPE(CHILD(ch, 1)) == comp_for) {
+ /* it's a set comprehension */
+ return ast_for_setcomp(c, ch);
+ } else if (NCH(ch) > 3 && TYPE(CHILD(ch, 3)) == comp_for) {
+ return ast_for_dictcomp(c, ch);
+ } else {
+ /* it's a dict */
+ size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
+ keys = asdl_seq_new(size, c->c_arena);
+ if (!keys)
return NULL;
- asdl_seq_SET(keys, i / 4, expression);
-
- expression = ast_for_expr(c, CHILD(ch, i + 2));
- if (!expression)
+ values = asdl_seq_new(size, c->c_arena);
+ if (!values)
return NULL;
- asdl_seq_SET(values, i / 4, expression);
+ for (i = 0; i < NCH(ch); i += 4) {
+ expr_ty expression;
+
+ expression = ast_for_expr(c, CHILD(ch, i));
+ if (!expression)
+ return NULL;
+
+ asdl_seq_SET(keys, i / 4, expression);
+
+ expression = ast_for_expr(c, CHILD(ch, i + 2));
+ if (!expression)
+ return NULL;
+
+ asdl_seq_SET(values, i / 4, expression);
+ }
+ return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
}
- return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
}
case BACKQUOTE: { /* repr */
expr_ty expression;
@@ -1443,10 +1532,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);
}
@@ -1480,10 +1569,17 @@ 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 */
+ /*
+ This is an extended slice (ie "x[::]") with no expression in the
+ step field. We set this literally to "None" in order to
+ disambiguate it from x[:]. (The interpreter might have to call
+ __getslice__ for x[:], but it must call __getitem__ for x[::].)
+ */
+ identifier none = new_identifier("None", c->c_arena);
+ if (!none)
+ return NULL;
ch = CHILD(ch, 0);
- step = Name(new_identifier("None", c->c_arena), Load,
- LINENO(ch), ch->n_col_offset, c->c_arena);
+ step = Name(none, Load, LINENO(ch), ch->n_col_offset, c->c_arena);
if (!step)
return NULL;
} else {
@@ -1503,7 +1599,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).
*/
@@ -1541,10 +1637,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;
}
@@ -1554,7 +1650,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]
*/
@@ -1585,7 +1681,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.
*/
@@ -1722,7 +1818,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
- 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)*
@@ -1739,7 +1835,7 @@ ast_for_expr(struct compiling *c, const node *n)
to explicitly allow:
[ x for x in lambda: 0, lambda: 1 ]
(which would be ambiguous without these extra rules)
-
+
old_test: or_test | old_lambdef
old_lambdef: 'lambda' [vararglist] ':' old_test
@@ -1819,7 +1915,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);
}
@@ -1827,7 +1923,7 @@ 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);
}
@@ -1879,7 +1975,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
/*
arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
| '**' test)
- argument: [test '='] test [gen_for] # Really [keyword '='] test
+ argument: [test '='] test [comp_for] # Really [keyword '='] test
*/
int i, nargs, nkeywords, ngens;
@@ -1897,7 +1993,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
if (TYPE(ch) == argument) {
if (NCH(ch) == 1)
nargs++;
- else if (TYPE(CHILD(ch, 1)) == gen_for)
+ else if (TYPE(CHILD(ch, 1)) == comp_for)
ngens++;
else
nkeywords++;
@@ -1941,8 +2037,8 @@ 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)) == gen_for) {
+ }
+ else if (TYPE(CHILD(ch, 1)) == comp_for) {
e = ast_for_genexp(c, ch);
if (!e)
return NULL;
@@ -1954,7 +2050,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
int k;
char *tmp;
- /* 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;
@@ -2012,14 +2108,14 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
static expr_ty
ast_for_testlist(struct compiling *c, const node* n)
{
- /* testlist_gexp: test (',' test)* [','] */
+ /* testlist_comp: test (',' test)* [','] */
/* testlist: test (',' test)* [','] */
/* testlist_safe: test (',' test)+ [','] */
/* testlist1: test (',' test)* */
assert(NCH(n) > 0);
- if (TYPE(n) == testlist_gexp) {
+ if (TYPE(n) == testlist_comp) {
if (NCH(n) > 1)
- assert(TYPE(CHILD(n, 1)) != gen_for);
+ assert(TYPE(CHILD(n, 1)) != comp_for);
}
else {
assert(TYPE(n) == testlist ||
@@ -2037,12 +2133,12 @@ ast_for_testlist(struct compiling *c, const node* n)
}
static expr_ty
-ast_for_testlist_gexp(struct compiling *c, const node* n)
+ast_for_testlist_comp(struct compiling *c, const node* n)
{
- /* testlist_gexp: test ( gen_for | (',' test)* [','] ) */
- /* argument: test [ gen_for ] */
- assert(TYPE(n) == testlist_gexp || TYPE(n) == argument);
- if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == gen_for)
+ /* testlist_comp: test ( comp_for | (',' test)* [','] ) */
+ /* argument: test [ comp_for ] */
+ assert(TYPE(n) == testlist_comp || TYPE(n) == argument);
+ if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == comp_for)
return ast_for_genexp(c, n);
return ast_for_testlist(c, n);
}
@@ -2073,7 +2169,7 @@ 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 (augassign (yield_expr|testlist)
| ('=' (yield_expr|testlist))*)
testlist: test (',' test)* [',']
augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
@@ -2096,33 +2192,21 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
expr1 = ast_for_testlist(c, ch);
if (!expr1)
return NULL;
- /* TODO(nas): Remove duplicated error checks (set_context does it) */
+ 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 GeneratorExp_kind:
- ast_error(ch, "augmented assignment to generator "
- "expression not possible");
- return NULL;
- case Yield_kind:
- ast_error(ch, "augmented assignment to yield "
- "expression not possible");
- return NULL;
- case Name_kind: {
- const char *var_name = PyBytes_AS_STRING(expr1->v.Name.id);
- if ((var_name[0] == 'N' || var_name[0] == 'T' || var_name[0] == 'F') &&
- !forbidden_check(c, ch, var_name))
- return NULL;
- break;
- }
+ case Name_kind:
case Attribute_kind:
case Subscript_kind:
break;
default:
- ast_error(ch, "illegal expression for augmented "
- "assignment");
+ ast_error(ch, "illegal expression for augmented assignment");
return NULL;
}
- if(!set_context(c, expr1, Store, ch))
- return NULL;
ch = CHILD(n, 2);
if (TYPE(ch) == testlist)
@@ -2158,11 +2242,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)
+ if (!e)
return NULL;
+ /* set context to assign */
if (!set_context(c, e, Store, CHILD(n, i)))
return NULL;
@@ -2187,9 +2270,9 @@ ast_for_print_stmt(struct compiling *c, const node *n)
| '>>' test [ (',' test)+ [','] ] )
*/
expr_ty dest = NULL, expression;
- asdl_seq *seq;
+ asdl_seq *seq = NULL;
bool nl;
- int i, j, start = 1;
+ int i, j, values_count, start = 1;
REQ(n, print_stmt);
if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {
@@ -2198,14 +2281,17 @@ ast_for_print_stmt(struct compiling *c, const node *n)
return NULL;
start = 4;
}
- seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
- if (!seq)
- return NULL;
- for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
- expression = ast_for_expr(c, CHILD(n, i));
- if (!expression)
+ values_count = (NCH(n) + 1 - start) / 2;
+ if (values_count) {
+ seq = asdl_seq_new(values_count, c->c_arena);
+ if (!seq)
return NULL;
- asdl_seq_SET(seq, j, expression);
+ for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
+ expression = ast_for_expr(c, CHILD(n, i));
+ if (!expression)
+ return NULL;
+ asdl_seq_SET(seq, j, expression);
+ }
}
nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
return Print(dest, seq, nl, LINENO(n), n->n_col_offset, c->c_arena);
@@ -2238,7 +2324,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);
@@ -2322,7 +2408,7 @@ ast_for_flow_stmt(struct compiling *c, const node *n)
expr3 = ast_for_expr(c, CHILD(ch, 5));
if (!expr3)
return NULL;
-
+
return Raise(expr1, expr2, expr3, LINENO(n), n->n_col_offset,
c->c_arena);
}
@@ -2337,7 +2423,7 @@ 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]
@@ -2348,28 +2434,40 @@ alias_for_import_name(struct compiling *c, const node *n)
loop:
switch (TYPE(n)) {
- case import_as_name:
+ case import_as_name: {
+ node *name_node = CHILD(n, 0);
str = NULL;
if (NCH(n) == 3) {
- str = NEW_IDENTIFIER(CHILD(n, 2));
+ node *str_node = CHILD(n, 2);
+ if (store && !forbidden_check(c, str_node, STR(str_node)))
+ return NULL;
+ str = NEW_IDENTIFIER(str_node);
if (!str)
return NULL;
}
- name = NEW_IDENTIFIER(CHILD(n, 0));
+ else {
+ if (!forbidden_check(c, name_node, STR(name_node)))
+ return NULL;
+ }
+ name = NEW_IDENTIFIER(name_node);
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));
+ if (!forbidden_check(c, asname_node, STR(asname_node)))
+ return NULL;
+ a->asname = NEW_IDENTIFIER(asname_node);
if (!a->asname)
return NULL;
return a;
@@ -2377,7 +2475,10 @@ alias_for_import_name(struct compiling *c, const node *n)
break;
case dotted_name:
if (NCH(n) == 1) {
- name = NEW_IDENTIFIER(CHILD(n, 0));
+ node *name_node = CHILD(n, 0);
+ if (store && !forbidden_check(c, name_node, STR(name_node)))
+ return NULL;
+ name = NEW_IDENTIFIER(name_node);
if (!name)
return NULL;
return alias(name, NULL, c->c_arena);
@@ -2451,7 +2552,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);
@@ -2462,13 +2563,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)) != DOT) {
@@ -2509,14 +2612,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);
@@ -2524,8 +2627,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);
}
@@ -2609,7 +2710,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,
@@ -2636,7 +2737,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)
@@ -2701,10 +2802,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);
}
@@ -2762,8 +2863,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));
@@ -2784,7 +2885,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;
@@ -2852,7 +2953,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);
@@ -2869,10 +2970,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)
@@ -2982,7 +3084,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;
@@ -3017,27 +3119,18 @@ ast_for_try_stmt(struct compiling *c, const node *n)
return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
}
-static expr_ty
-ast_for_with_var(struct compiling *c, const node *n)
-{
- REQ(n, with_var);
- return ast_for_expr(c, CHILD(n, 1));
-}
-
-/* with_stmt: 'with' test [ with_var ] ':' suite */
+/* with_item: test ['as' expr] */
static stmt_ty
-ast_for_with_stmt(struct compiling *c, const node *n)
+ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content)
{
expr_ty context_expr, optional_vars = NULL;
- int suite_index = 3; /* skip 'with', test, and ':' */
- asdl_seq *suite_seq;
- assert(TYPE(n) == with_stmt);
- context_expr = ast_for_expr(c, CHILD(n, 1));
+ REQ(n, with_item);
+ context_expr = ast_for_expr(c, CHILD(n, 0));
if (!context_expr)
return NULL;
- if (TYPE(CHILD(n, 2)) == with_var) {
- optional_vars = ast_for_with_var(c, CHILD(n, 2));
+ if (NCH(n) == 3) {
+ optional_vars = ast_for_expr(c, CHILD(n, 2));
if (!optional_vars) {
return NULL;
@@ -3045,15 +3138,45 @@ ast_for_with_stmt(struct compiling *c, const node *n)
if (!set_context(c, optional_vars, Store, n)) {
return NULL;
}
- suite_index = 4;
}
- suite_seq = ast_for_suite(c, CHILD(n, suite_index));
- if (!suite_seq) {
+ return With(context_expr, optional_vars, content, LINENO(n),
+ n->n_col_offset, c->c_arena);
+}
+
+/* with_stmt: 'with' with_item (',' with_item)* ':' suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n)
+{
+ int i;
+ stmt_ty ret;
+ asdl_seq *inner;
+
+ REQ(n, with_stmt);
+
+ /* process the with items inside-out */
+ i = NCH(n) - 1;
+ /* the suite of the innermost with item is the suite of the with stmt */
+ inner = ast_for_suite(c, CHILD(n, i));
+ if (!inner)
return NULL;
+
+ for (;;) {
+ i -= 2;
+ ret = ast_for_with_item(c, CHILD(n, i), inner);
+ if (!ret)
+ return NULL;
+ /* was this the last item? */
+ if (i == 1)
+ break;
+ /* if not, wrap the result so far in a new sequence */
+ inner = asdl_seq_new(1, c->c_arena);
+ if (!inner)
+ return NULL;
+ asdl_seq_SET(inner, 0, ret);
}
- return With(context_expr, optional_vars, suite_seq, LINENO(n),
- n->n_col_offset, c->c_arena);
+
+ return ret;
}
static stmt_ty
@@ -3062,7 +3185,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
/* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
PyObject *classname;
asdl_seq *bases, *s;
-
+
REQ(n, classdef);
if (!forbidden_check(c, n, STR(CHILD(n, 1))))
@@ -3117,7 +3240,6 @@ ast_for_stmt(struct compiling *c, const node *n)
n = CHILD(n, 0);
}
if (TYPE(n) == small_stmt) {
- REQ(n, small_stmt);
n = CHILD(n, 0);
/* small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt
| flow_stmt | import_stmt | global_stmt | exec_stmt
@@ -3210,17 +3332,17 @@ parsenumber(struct compiling *c, const char *s)
#ifndef WITHOUT_COMPLEX
if (imflag) {
complex.real = 0.;
- PyFPE_START_PROTECT("atof", return 0)
- complex.imag = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(complex)
+ complex.imag = PyOS_string_to_double(s, (char **)&end, NULL);
+ if (complex.imag == -1.0 && PyErr_Occurred())
+ return NULL;
return PyComplex_FromCComplex(complex);
}
else
#endif
{
- PyFPE_START_PROTECT("atof", return 0)
- dx = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(dx)
+ dx = PyOS_string_to_double(s, NULL, NULL);
+ if (dx == -1.0 && PyErr_Occurred())
+ return NULL;
return PyFloat_FromDouble(dx);
}
}
@@ -3251,17 +3373,12 @@ decode_utf8(struct compiling *c, const char **sPtr, const char *end, char* encod
static PyObject *
decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, const char *encoding)
{
- PyObject *v, *u;
+ PyObject *v;
+ PyObject *u = NULL;
char *buf;
char *p;
const char *end;
- if (encoding == NULL) {
- buf = (char *)s;
- u = NULL;
- } else if (strcmp(encoding, "iso-8859-1") == 0) {
- buf = (char *)s;
- u = NULL;
- } else {
+ if (encoding != NULL && strcmp(encoding, "iso-8859-1")) {
/* check for integer overflow */
if (len > PY_SIZE_MAX / 6)
return NULL;
@@ -3351,7 +3468,7 @@ parsestr(struct compiling *c, const char *s)
s++;
len = strlen(s);
if (len > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
+ PyErr_SetString(PyExc_OverflowError,
"string to parse is too long");
return NULL;
}