Commit 2f327c14 authored by Jeremy Hylton's avatar Jeremy Hylton

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.
parent cb30f97b
...@@ -323,6 +323,8 @@ struct _excepthandler { ...@@ -323,6 +323,8 @@ struct _excepthandler {
expr_ty type; expr_ty type;
expr_ty name; expr_ty name;
asdl_seq *body; asdl_seq *body;
int lineno;
int col_offset;
}; };
struct _arguments { struct _arguments {
...@@ -427,8 +429,8 @@ slice_ty ExtSlice(asdl_seq * dims, PyArena *arena); ...@@ -427,8 +429,8 @@ slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
slice_ty Index(expr_ty value, PyArena *arena); slice_ty Index(expr_ty value, PyArena *arena);
comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
PyArena *arena); PyArena *arena);
excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body, excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int
PyArena *arena); lineno, int col_offset, PyArena *arena);
arguments_ty arguments(asdl_seq * args, identifier vararg, identifier kwarg, arguments_ty arguments(asdl_seq * args, identifier vararg, identifier kwarg,
asdl_seq * defaults, PyArena *arena); asdl_seq * defaults, PyArena *arena);
keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena); keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena);
......
...@@ -119,7 +119,8 @@ eval_tests = [ ...@@ -119,7 +119,8 @@ eval_tests = [
# excepthandler, arguments, keywords, alias # excepthandler, arguments, keywords, alias
if __name__=='__main__' and sys.argv[1:] == ['-g']: 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 = [" print kind+"_results = ["
for s in statements: for s in statements:
print repr(to_tuple(compile(s, "?", kind, 0x400)))+"," print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
...@@ -131,7 +132,7 @@ def test_order(ast_node, parent_pos): ...@@ -131,7 +132,7 @@ def test_order(ast_node, parent_pos):
if not isinstance(ast_node, _ast.AST) or ast_node._fields == None: if not isinstance(ast_node, _ast.AST) or ast_node._fields == None:
return 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) node_pos = (ast_node.lineno, ast_node.col_offset)
assert node_pos >= parent_pos, (node_pos, parent_pos) assert node_pos >= parent_pos, (node_pos, parent_pos)
parent_pos = (ast_node.lineno, ast_node.col_offset) parent_pos = (ast_node.lineno, ast_node.col_offset)
...@@ -145,10 +146,12 @@ def test_order(ast_node, parent_pos): ...@@ -145,10 +146,12 @@ def test_order(ast_node, parent_pos):
def run_tests(): def run_tests():
for input, output, kind in ((exec_tests, exec_results, "exec"), for input, output, kind in ((exec_tests, exec_results, "exec"),
(single_tests, single_results, "single"), (single_tests, single_results, "single"),
(eval_tests, eval_results, "eval")): (eval_tests, eval_results, "eval")):
for i, o in itertools.izip(input, output): for i, o in itertools.izip(input, output):
ast_tree = compile(i, "?", kind, 0x400) ast_tree = compile(i, "?", kind, 0x400)
print repr(to_tuple(ast_tree))
print repr(o)
assert to_tuple(ast_tree) == o assert to_tuple(ast_tree) == o
test_order(ast_tree, (0, 0)) test_order(ast_tree, (0, 0))
...@@ -165,7 +168,7 @@ exec_results = [ ...@@ -165,7 +168,7 @@ exec_results = [
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]), ('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', [('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', [('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', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]), ('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
......
...@@ -98,8 +98,11 @@ module Python version "$Revision$" ...@@ -98,8 +98,11 @@ module Python version "$Revision$"
comprehension = (expr target, expr iter, expr* ifs) comprehension = (expr target, expr iter, expr* ifs)
-- not sure what to call the first argument for raise and except -- not sure what to call the first argument for raise and except
-- TODO(jhylton): Figure out if there is a better way to handle
excepthandler = (expr? type, expr? name, stmt* body) -- 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, arguments = (expr* args, identifier? vararg,
identifier? kwarg, expr* defaults) identifier? kwarg, expr* defaults)
......
...@@ -276,7 +276,7 @@ class FunctionVisitor(PrototypeVisitor): ...@@ -276,7 +276,7 @@ class FunctionVisitor(PrototypeVisitor):
emit("%s p;" % ctype, 1) emit("%s p;" % ctype, 1)
for argtype, argname, opt in args: for argtype, argname, opt in args:
# XXX hack alert: false is allowed for a bool # 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("if (!%s) {" % argname, 1)
emit("PyErr_SetString(PyExc_ValueError,", 2) emit("PyErr_SetString(PyExc_ValueError,", 2)
msg = "field %s is required for %s" % (argname, name) msg = "field %s is required for %s" % (argname, name)
......
...@@ -331,6 +331,8 @@ static char *excepthandler_fields[]={ ...@@ -331,6 +331,8 @@ static char *excepthandler_fields[]={
"type", "type",
"name", "name",
"body", "body",
"lineno",
"col_offset",
}; };
static PyTypeObject *arguments_type; static PyTypeObject *arguments_type;
static PyObject* ast2obj_arguments(void*); static PyObject* ast2obj_arguments(void*);
...@@ -712,7 +714,7 @@ static int init_types(void) ...@@ -712,7 +714,7 @@ static int init_types(void)
comprehension_fields, 3); comprehension_fields, 3);
if (!comprehension_type) return 0; if (!comprehension_type) return 0;
excepthandler_type = make_type("excepthandler", AST_type, excepthandler_type = make_type("excepthandler", AST_type,
excepthandler_fields, 3); excepthandler_fields, 5);
if (!excepthandler_type) return 0; if (!excepthandler_type) return 0;
arguments_type = make_type("arguments", AST_type, arguments_fields, 4); arguments_type = make_type("arguments", AST_type, arguments_fields, 4);
if (!arguments_type) return 0; if (!arguments_type) return 0;
...@@ -1843,7 +1845,8 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena) ...@@ -1843,7 +1845,8 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
} }
excepthandler_ty 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; excepthandler_ty p;
p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*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) ...@@ -1854,6 +1857,8 @@ excepthandler(expr_ty type, expr_ty name, asdl_seq * body, PyArena *arena)
p->type = type; p->type = type;
p->name = name; p->name = name;
p->body = body; p->body = body;
p->lineno = lineno;
p->col_offset = col_offset;
return p; return p;
} }
...@@ -2917,6 +2922,16 @@ ast2obj_excepthandler(void* _o) ...@@ -2917,6 +2922,16 @@ ast2obj_excepthandler(void* _o)
if (PyObject_SetAttrString(result, "body", value) == -1) if (PyObject_SetAttrString(result, "body", value) == -1)
goto failed; goto failed;
Py_DECREF(value); 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; return result;
failed: failed:
Py_XDECREF(value); Py_XDECREF(value);
...@@ -3033,7 +3048,7 @@ init_ast(void) ...@@ -3033,7 +3048,7 @@ init_ast(void)
if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return; if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
return; return;
if (PyModule_AddStringConstant(m, "__version__", "42753") < 0) if (PyModule_AddStringConstant(m, "__version__", "") < 0)
return; return;
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment