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:
Jeremy Hylton 2006-04-04 04:00:23 +00:00
parent cb30f97bd3
commit 2f327c14eb
6 changed files with 84 additions and 41 deletions

View File

@ -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);

View File

@ -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)])]),

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)