mirror of https://github.com/python/cpython
Add lineno, col_offset to excephandler to enable future fix for
tracing/line number table in except blocks. Reflow long lines introduced by col_offset changes. Update test_ast to handle new fields in excepthandler. As note in Python.asdl says, we might want to rethink how attributes are handled. Perhaps they should be the same as other fields, with the primary difference being how they are defined for all types within a sum. Also fix asdl_c so that constructors with int fields don't fail when passed a zero value.
This commit is contained in:
parent
cb30f97bd3
commit
2f327c14eb
|
@ -323,6 +323,8 @@ struct _excepthandler {
|
|||
expr_ty type;
|
||||
expr_ty name;
|
||||
asdl_seq *body;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
};
|
||||
|
||||
struct _arguments {
|
||||
|
@ -427,8 +429,8 @@ slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
|
|||
slice_ty Index(expr_ty value, PyArena *arena);
|
||||
comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
|
||||
PyArena *arena);
|
||||
excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body,
|
||||
PyArena *arena);
|
||||
excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int
|
||||
lineno, int col_offset, PyArena *arena);
|
||||
arguments_ty arguments(asdl_seq * args, identifier vararg, identifier kwarg,
|
||||
asdl_seq * defaults, PyArena *arena);
|
||||
keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena);
|
||||
|
|
|
@ -119,7 +119,8 @@ eval_tests = [
|
|||
# excepthandler, arguments, keywords, alias
|
||||
|
||||
if __name__=='__main__' and sys.argv[1:] == ['-g']:
|
||||
for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")):
|
||||
for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
|
||||
(eval_tests, "eval")):
|
||||
print kind+"_results = ["
|
||||
for s in statements:
|
||||
print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
|
||||
|
@ -131,7 +132,7 @@ def test_order(ast_node, parent_pos):
|
|||
|
||||
if not isinstance(ast_node, _ast.AST) or ast_node._fields == None:
|
||||
return
|
||||
if isinstance(ast_node, (_ast.expr, _ast.stmt)):
|
||||
if isinstance(ast_node, (_ast.expr, _ast.stmt, _ast.excepthandler)):
|
||||
node_pos = (ast_node.lineno, ast_node.col_offset)
|
||||
assert node_pos >= parent_pos, (node_pos, parent_pos)
|
||||
parent_pos = (ast_node.lineno, ast_node.col_offset)
|
||||
|
@ -145,10 +146,12 @@ def test_order(ast_node, parent_pos):
|
|||
|
||||
def run_tests():
|
||||
for input, output, kind in ((exec_tests, exec_results, "exec"),
|
||||
(single_tests, single_results, "single"),
|
||||
(eval_tests, eval_results, "eval")):
|
||||
(single_tests, single_results, "single"),
|
||||
(eval_tests, eval_results, "eval")):
|
||||
for i, o in itertools.izip(input, output):
|
||||
ast_tree = compile(i, "?", kind, 0x400)
|
||||
print repr(to_tuple(ast_tree))
|
||||
print repr(o)
|
||||
assert to_tuple(ast_tree) == o
|
||||
test_order(ast_tree, (0, 0))
|
||||
|
||||
|
@ -165,7 +168,7 @@ exec_results = [
|
|||
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
|
||||
('Module', [('Raise', (1, 0), ('Name', (1, 6), 'Exception', ('Load',)), ('Str', (1, 17), 'string'), None)]),
|
||||
('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('excepthandler', ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]),
|
||||
('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('excepthandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))], 3, 0)], [])]),
|
||||
('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
|
||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
|
||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
|
||||
|
|
|
@ -98,8 +98,11 @@ module Python version "$Revision$"
|
|||
comprehension = (expr target, expr iter, expr* ifs)
|
||||
|
||||
-- not sure what to call the first argument for raise and except
|
||||
|
||||
excepthandler = (expr? type, expr? name, stmt* body)
|
||||
-- TODO(jhylton): Figure out if there is a better way to handle
|
||||
-- lineno and col_offset fields, particularly when
|
||||
-- ast is exposed to Python.
|
||||
excepthandler = (expr? type, expr? name, stmt* body, int lineno,
|
||||
int col_offset)
|
||||
|
||||
arguments = (expr* args, identifier? vararg,
|
||||
identifier? kwarg, expr* defaults)
|
||||
|
|
|
@ -276,7 +276,7 @@ class FunctionVisitor(PrototypeVisitor):
|
|||
emit("%s p;" % ctype, 1)
|
||||
for argtype, argname, opt in args:
|
||||
# XXX hack alert: false is allowed for a bool
|
||||
if not opt and not argtype == "bool":
|
||||
if not opt and not (argtype == "bool" or argtype == "int"):
|
||||
emit("if (!%s) {" % argname, 1)
|
||||
emit("PyErr_SetString(PyExc_ValueError,", 2)
|
||||
msg = "field %s is required for %s" % (argname, name)
|
||||
|
|
|
@ -331,6 +331,8 @@ static char *excepthandler_fields[]={
|
|||
"type",
|
||||
"name",
|
||||
"body",
|
||||
"lineno",
|
||||
"col_offset",
|
||||
};
|
||||
static PyTypeObject *arguments_type;
|
||||
static PyObject* ast2obj_arguments(void*);
|
||||
|
@ -712,7 +714,7 @@ static int init_types(void)
|
|||
comprehension_fields, 3);
|
||||
if (!comprehension_type) return 0;
|
||||
excepthandler_type = make_type("excepthandler", AST_type,
|
||||
excepthandler_fields, 3);
|
||||
excepthandler_fields, 5);
|
||||
if (!excepthandler_type) return 0;
|
||||
arguments_type = make_type("arguments", AST_type, arguments_fields, 4);
|
||||
if (!arguments_type) return 0;
|
||||
|
@ -1843,7 +1845,8 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
|
|||
}
|
||||
|
||||
excepthandler_ty
|
||||
excepthandler(expr_ty type, expr_ty name, asdl_seq * body, PyArena *arena)
|
||||
excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
|
||||
col_offset, PyArena *arena)
|
||||
{
|
||||
excepthandler_ty p;
|
||||
p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
|
@ -1854,6 +1857,8 @@ excepthandler(expr_ty type, expr_ty name, asdl_seq * body, PyArena *arena)
|
|||
p->type = type;
|
||||
p->name = name;
|
||||
p->body = body;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -2917,6 +2922,16 @@ ast2obj_excepthandler(void* _o)
|
|||
if (PyObject_SetAttrString(result, "body", value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_int(o->lineno);
|
||||
if (!value) goto failed;
|
||||
if (PyObject_SetAttrString(result, "lineno", value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_int(o->col_offset);
|
||||
if (!value) goto failed;
|
||||
if (PyObject_SetAttrString(result, "col_offset", value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
return result;
|
||||
failed:
|
||||
Py_XDECREF(value);
|
||||
|
@ -3033,7 +3048,7 @@ init_ast(void)
|
|||
if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
|
||||
if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
|
||||
return;
|
||||
if (PyModule_AddStringConstant(m, "__version__", "42753") < 0)
|
||||
if (PyModule_AddStringConstant(m, "__version__", "") < 0)
|
||||
return;
|
||||
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
|
||||
if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
|
||||
|
|
76
Python/ast.c
76
Python/ast.c
|
@ -247,7 +247,8 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
|
|||
stmts = asdl_seq_new(1, arena);
|
||||
if (!stmts)
|
||||
goto error;
|
||||
asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset, arena));
|
||||
asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset,
|
||||
arena));
|
||||
return Interactive(stmts, arena);
|
||||
}
|
||||
else {
|
||||
|
@ -568,8 +569,8 @@ compiler_complex_args(struct compiling *c, const node *n)
|
|||
ast_error(child, "assignment to None");
|
||||
return NULL;
|
||||
}
|
||||
arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child), child->n_col_offset,
|
||||
c->c_arena);
|
||||
arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
|
||||
child->n_col_offset, c->c_arena);
|
||||
}
|
||||
else {
|
||||
arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1));
|
||||
|
@ -662,7 +663,8 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
goto error;
|
||||
}
|
||||
name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
|
||||
Param, LINENO(ch), ch->n_col_offset, c->c_arena);
|
||||
Param, LINENO(ch), ch->n_col_offset,
|
||||
c->c_arena);
|
||||
if (!name)
|
||||
goto error;
|
||||
asdl_seq_SET(args, k++, name);
|
||||
|
@ -754,7 +756,8 @@ ast_for_decorator(struct compiling *c, const node *n)
|
|||
name_expr = NULL;
|
||||
}
|
||||
else if (NCH(n) == 5) { /* Call with no arguments */
|
||||
d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
if (!d)
|
||||
return NULL;
|
||||
name_expr = NULL;
|
||||
|
@ -826,7 +829,8 @@ ast_for_funcdef(struct compiling *c, const node *n)
|
|||
if (!body)
|
||||
return NULL;
|
||||
|
||||
return FunctionDef(name, args, body, decorator_seq, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return FunctionDef(name, args, body, decorator_seq, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
|
@ -872,7 +876,8 @@ ast_for_ifexpr(struct compiling *c, const node *n)
|
|||
orelse = ast_for_expr(c, CHILD(n, 4));
|
||||
if (!orelse)
|
||||
return NULL;
|
||||
return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
}
|
||||
|
||||
/* Count the number of 'for' loop in a list comprehension.
|
||||
|
@ -983,7 +988,8 @@ ast_for_listcomp(struct compiling *c, const node *n)
|
|||
lc = comprehension(asdl_seq_GET(t, 0), expression, NULL,
|
||||
c->c_arena);
|
||||
else
|
||||
lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset, c->c_arena),
|
||||
lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
|
||||
c->c_arena),
|
||||
expression, NULL, c->c_arena);
|
||||
if (!lc)
|
||||
return NULL;
|
||||
|
@ -1128,7 +1134,8 @@ ast_for_genexp(struct compiling *c, const node *n)
|
|||
ge = comprehension(asdl_seq_GET(t, 0), expression,
|
||||
NULL, c->c_arena);
|
||||
else
|
||||
ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset, c->c_arena),
|
||||
ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
|
||||
c->c_arena),
|
||||
expression, NULL, c->c_arena);
|
||||
|
||||
if (!ge)
|
||||
|
@ -1372,7 +1379,8 @@ ast_for_binop(struct compiling *c, const node *n)
|
|||
if (!operator)
|
||||
return NULL;
|
||||
|
||||
result = BinOp(expr1, operator, expr2, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
result = BinOp(expr1, operator, expr2, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
|
@ -1390,7 +1398,8 @@ ast_for_binop(struct compiling *c, const node *n)
|
|||
return NULL;
|
||||
|
||||
tmp_result = BinOp(result, operator, tmp,
|
||||
LINENO(next_oper), next_oper->n_col_offset, c->c_arena);
|
||||
LINENO(next_oper), next_oper->n_col_offset,
|
||||
c->c_arena);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
result = tmp_result;
|
||||
|
@ -1408,7 +1417,8 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)
|
|||
REQ(n, trailer);
|
||||
if (TYPE(CHILD(n, 0)) == LPAR) {
|
||||
if (NCH(n) == 2)
|
||||
return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
else
|
||||
return ast_for_call(c, CHILD(n, 1), left_expr);
|
||||
}
|
||||
|
@ -1424,7 +1434,8 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)
|
|||
slice_ty slc = ast_for_slice(c, CHILD(n, 0));
|
||||
if (!slc)
|
||||
return NULL;
|
||||
return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
}
|
||||
else {
|
||||
/* The grammar is ambiguous here. The ambiguity is resolved
|
||||
|
@ -1565,7 +1576,8 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
asdl_seq_SET(seq, i / 2, e);
|
||||
}
|
||||
if (!strcmp(STR(CHILD(n, 1)), "and"))
|
||||
return BoolOp(And, seq, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return BoolOp(And, seq, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
assert(!strcmp(STR(CHILD(n, 1)), "or"));
|
||||
return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
case not_test:
|
||||
|
@ -1578,7 +1590,8 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
if (!expression)
|
||||
return NULL;
|
||||
|
||||
return UnaryOp(Not, expression, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return UnaryOp(Not, expression, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
}
|
||||
case comparison:
|
||||
if (NCH(n) == 1) {
|
||||
|
@ -1617,7 +1630,8 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return Compare(expression, ops, cmps, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2623,7 +2637,8 @@ ast_for_for_stmt(struct compiling *c, const node *n)
|
|||
if (!suite_seq)
|
||||
return NULL;
|
||||
|
||||
return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
}
|
||||
|
||||
static excepthandler_ty
|
||||
|
@ -2638,7 +2653,8 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
|
|||
if (!suite_seq)
|
||||
return NULL;
|
||||
|
||||
return excepthandler(NULL, NULL, suite_seq, c->c_arena);
|
||||
return excepthandler(NULL, NULL, suite_seq, LINENO(exc),
|
||||
exc->n_col_offset, c->c_arena);
|
||||
}
|
||||
else if (NCH(exc) == 2) {
|
||||
expr_ty expression;
|
||||
|
@ -2651,7 +2667,8 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
|
|||
if (!suite_seq)
|
||||
return NULL;
|
||||
|
||||
return excepthandler(expression, NULL, suite_seq, c->c_arena);
|
||||
return excepthandler(expression, NULL, suite_seq, LINENO(exc),
|
||||
exc->n_col_offset, c->c_arena);
|
||||
}
|
||||
else if (NCH(exc) == 4) {
|
||||
asdl_seq *suite_seq;
|
||||
|
@ -2668,7 +2685,8 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
|
|||
if (!suite_seq)
|
||||
return NULL;
|
||||
|
||||
return excepthandler(expression, e, suite_seq, c->c_arena);
|
||||
return excepthandler(expression, e, suite_seq, LINENO(exc),
|
||||
exc->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
|
@ -2737,7 +2755,8 @@ ast_for_try_stmt(struct compiling *c, const node *n)
|
|||
asdl_seq_SET(handlers, i, e);
|
||||
}
|
||||
|
||||
except_st = TryExcept(body, handlers, orelse, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
except_st = TryExcept(body, handlers, orelse, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
if (!finally)
|
||||
return except_st;
|
||||
|
||||
|
@ -2812,16 +2831,16 @@ ast_for_classdef(struct compiling *c, const node *n)
|
|||
s = ast_for_suite(c, CHILD(n, 3));
|
||||
if (!s)
|
||||
return NULL;
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
}
|
||||
/* check for empty base list */
|
||||
if (TYPE(CHILD(n,3)) == RPAR) {
|
||||
s = ast_for_suite(c, CHILD(n,5));
|
||||
if (!s)
|
||||
return NULL;
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
/* else handle the base class list */
|
||||
|
@ -2832,8 +2851,8 @@ ast_for_classdef(struct compiling *c, const node *n)
|
|||
s = ast_for_suite(c, CHILD(n, 6));
|
||||
if (!s)
|
||||
return NULL;
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n), n->n_col_offset,
|
||||
c->c_arena);
|
||||
return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
static stmt_ty
|
||||
|
@ -3105,7 +3124,8 @@ parsestr(const char *s, const char *encoding)
|
|||
#ifndef Py_USING_UNICODE
|
||||
/* This should not happen - we never see any other
|
||||
encoding. */
|
||||
Py_FatalError("cannot deal with encodings in this build.");
|
||||
Py_FatalError(
|
||||
"cannot deal with encodings in this build.");
|
||||
#else
|
||||
PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL);
|
||||
if (u == NULL)
|
||||
|
|
Loading…
Reference in New Issue