# HG changeset patch # User Bastien Orivel # Date 1465779793 -7200 # Node ID c59ad5ccd8a67bb743c75159fef5228c567ee053 # Parent 8ce78e2ba48cbffa911395fd55960321ea9f4ecd Add ast.Try diff --git a/src/ast_convert.rs b/src/ast_convert.rs --- a/src/ast_convert.rs +++ b/src/ast_convert.rs @@ -1,4 +1,4 @@ -use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem}; +use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler}; use cpython::{Python, PyObject}; use cpython::ObjectProtocol; //for call method @@ -255,6 +255,18 @@ fn parse_operator(py: Python, ast: PyObj } } +fn parse_excepthandler(py: Python, ast: PyObject) -> excepthandler { + let type_ = ast.getattr(py, "type").unwrap(); + let name = ast.getattr(py, "name").unwrap(); + let body = ast.getattr(py, "body").unwrap(); + + let type_ = parse_optional_expr(py, type_); + let name = if name == py.None() { None } else { Some(get_str(py, name)) }; + let body = parse_list(py, body, parse_statement); + + excepthandler{type_: type_, name: name, body: body} +} + fn parse_optional_expr(py: Python, ast: PyObject) -> Option { if ast == py.None() { None @@ -531,6 +543,7 @@ fn parse_statement(py: Python, ast: PyOb let assert_type = ast_module.get(py, "Assert").unwrap(); let with_type = ast_module.get(py, "With").unwrap(); let raise_type = ast_module.get(py, "Raise").unwrap(); + let try_type = ast_module.get(py, "Try").unwrap(); assert!(is_instance(&ast, &ast_type)); @@ -695,6 +708,18 @@ fn parse_statement(py: Python, ast: PyOb let cause = parse_optional_expr(py, cause); stmt::Raise(exc, cause) + } else if is_instance(&ast, &try_type) { + let body = ast.getattr(py, "body").unwrap(); + let excepthandlers = ast.getattr(py, "handlers").unwrap(); + let orelse = ast.getattr(py, "orelse").unwrap(); + let finalbody = ast.getattr(py, "finalbody").unwrap(); + + let body = parse_list(py, body, parse_statement); + let excepthandlers = parse_list(py, excepthandlers, parse_excepthandler); + let orelse = parse_list(py, orelse, parse_statement); + let finalbody = parse_list(py, finalbody, parse_statement); + + stmt::Try(body, excepthandlers, orelse, finalbody) } else { println!("stmt {}", ast); panic!() diff --git a/src/ast_dump.rs b/src/ast_dump.rs --- a/src/ast_dump.rs +++ b/src/ast_dump.rs @@ -1,4 +1,4 @@ -use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem}; +use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem, excepthandler}; use std::iter; @@ -117,6 +117,24 @@ impl to_string_able for comprehension { } } +impl excepthandler { + fn to_string(self, indent: usize) -> String { + let current_indent = make_indent(indent); + format!("{}except {}{}:\n{}", + current_indent, + match self.type_ { + None => String::new(), + Some(ref type_) => type_.to_string() + }, + match self.name { + None => String::new(), + Some(ref name) => format!(" as {}", name) + }, + statements_to_string(indent, self.body) + ) + } +} + impl to_string_able for expr { fn to_string(&self) -> String { match self.clone() { @@ -346,6 +364,30 @@ impl stmt { Some(ref cause) => format!(" from {}", cause.to_string()) } ) + }, + stmt::Try(body, excepthandlers, orelse, finalbody) => { + format!("{}try:\n{}\n{}{}\n{}", + current_indent, + statements_to_string(indent, body), + { + let mut excepthandlers_ = vec!(); + for excepthandler in excepthandlers { + let excepthandler = excepthandler.to_string(indent); + excepthandlers_.push(excepthandler); + } + excepthandlers_.join("\n") + }, + if !orelse.is_empty() { + format!("{}else:\n{}", current_indent, statements_to_string(indent, orelse)) + } else { + String::new() + }, + if !finalbody.is_empty() { + format!("{}finally:\n{}", current_indent, statements_to_string(indent, finalbody)) + } else { + String::new() + } + ) } } } diff --git a/src/python_ast.rs b/src/python_ast.rs --- a/src/python_ast.rs +++ b/src/python_ast.rs @@ -51,7 +51,7 @@ pub enum stmt { Raise(Option, Option), // Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) - //Try(Vec, Vec, Vec, Vec) + Try(Vec, Vec, Vec, Vec), // Assert(expr test, expr? msg) Assert(expr, Option), @@ -186,8 +186,10 @@ pub struct comprehension { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum excepthandler { - ExceptHandler(Option, Option, Vec) +pub struct excepthandler { + pub type_: Option, + pub name: Option, + pub body: Vec, } #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/tests/test_parse_files/test_try.py b/tests/test_parse_files/test_try.py new file mode 100644 --- /dev/null +++ b/tests/test_parse_files/test_try.py @@ -0,0 +1,9 @@ +def func(): + try: + pass + except (Exception1, Exception2): + pass + except Exception3 as e: + pass + finally: + pass