summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c205
1 files changed, 106 insertions, 99 deletions
diff --git a/Python/ast.c b/Python/ast.c
index d97e951..2ee2186 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"
@@ -90,7 +89,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 +100,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;
PyObject *filename_obj;
long lineno;
@@ -119,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);
@@ -133,7 +137,7 @@ ast_error_finish(const char *filename)
filename_obj = Py_None;
}
if (filename_obj != NULL)
- tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, Py_None, loc);
+ tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, offset, loc);
else
tmp = NULL;
Py_DECREF(loc);
@@ -367,19 +371,24 @@ static const char* FORBIDDEN[] = {
"None",
"True",
"False",
- "__debug__",
NULL,
};
static int
-forbidden_name(expr_ty e, const node *n)
+forbidden_name(identifier name, const node *n, int full_checks)
{
- const char **p;
- assert(PyUnicode_Check(e->v.Name.id));
- for (p = FORBIDDEN; *p; p++) {
- if (PyUnicode_CompareWithASCIIString(e->v.Name.id, *p) == 0) {
- ast_error(n, "assignment to keyword");
- return 1;
+ assert(PyUnicode_Check(name));
+ 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;
@@ -413,6 +422,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;
@@ -424,7 +435,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, 1))
return 0; /* forbidden_name() calls ast_error() */
}
e->v.Name.ctx = ctx;
@@ -434,10 +445,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";
@@ -604,20 +618,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;
@@ -639,6 +656,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));
@@ -705,6 +724,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;
@@ -863,6 +884,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));
@@ -892,6 +915,8 @@ ast_for_arguments(struct compiling *c, const node *n)
if (!kwargannotation)
return NULL;
}
+ if (forbidden_name(kwarg, CHILD(ch, 0), 0))
+ return NULL;
i += 3;
break;
default:
@@ -1009,6 +1034,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;
@@ -1183,7 +1210,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);
@@ -1198,14 +1225,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;
@@ -1285,7 +1311,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;
@@ -1524,14 +1549,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);
@@ -1675,34 +1693,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;
@@ -1886,10 +1878,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);
- }
- /* Fallthrough */
+ 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.
@@ -2025,7 +2014,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, 1)) {
return NULL;
}
key = e->v.Name.id;
@@ -2067,7 +2056,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 +2063,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 +2079,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
@@ -2173,7 +2161,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);
@@ -2183,6 +2171,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)
{
@@ -2283,49 +2272,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, 0))
+ return NULL;
+ }
+ else {
+ if (forbidden_name(name, name_node, 0))
+ 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, 0))
+ 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, 0))
+ return NULL;
return alias(name, NULL, c->c_arena);
}
else {
@@ -2405,7 +2409,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);
@@ -2416,13 +2420,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) {
@@ -2467,14 +2473,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);
@@ -2482,8 +2488,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);
}
@@ -2796,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);
@@ -2813,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)
@@ -2864,6 +2869,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;
@@ -3036,6 +3043,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);
}
@@ -3047,6 +3056,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);
}
@@ -3070,6 +3081,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,
@@ -3154,17 +3167,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) {
@@ -3181,7 +3190,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);
@@ -3190,7 +3198,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())