SF patch #1355913, PEP 341 - Unification of try/except and try/finally
Modified since ast-arenas was implemented.
This commit is contained in:
parent
adb69fcdff
commit
f599f424a2
|
@ -67,8 +67,7 @@ compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
|
||||||
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
|
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
|
||||||
while_stmt: 'while' test ':' suite ['else' ':' suite]
|
while_stmt: 'while' test ':' suite ['else' ':' suite]
|
||||||
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
|
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
|
||||||
try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
|
try_stmt: 'try' ':' suite ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite)
|
||||||
['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
|
|
||||||
# NB compile.c makes sure that the default except clause is last
|
# NB compile.c makes sure that the default except clause is last
|
||||||
except_clause: 'except' [test [',' test]]
|
except_clause: 'except' [test [',' test]]
|
||||||
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
|
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
|
||||||
|
from test.test_support import run_unittest
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class ExceptionTestCase(unittest.TestCase):
|
||||||
|
def test_try_except_else_finally(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_else = False
|
||||||
|
hit_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise Exception, 'nyaa!'
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
else:
|
||||||
|
hit_else = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertTrue(hit_except)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
self.assertFalse(hit_else)
|
||||||
|
|
||||||
|
def test_try_except_else_finally_no_exception(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_else = False
|
||||||
|
hit_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
else:
|
||||||
|
hit_else = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_except)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
self.assertTrue(hit_else)
|
||||||
|
|
||||||
|
def test_try_except_finally(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise Exception, 'yarr!'
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertTrue(hit_except)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
|
||||||
|
def test_try_except_finally_no_exception(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_except)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
|
||||||
|
def test_try_except(self):
|
||||||
|
hit_except = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise Exception, 'ahoy!'
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
|
||||||
|
self.assertTrue(hit_except)
|
||||||
|
|
||||||
|
def test_try_except_no_exception(self):
|
||||||
|
hit_except = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_except)
|
||||||
|
|
||||||
|
def test_try_except_else(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_else = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise Exception, 'foo!'
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
else:
|
||||||
|
hit_else = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_else)
|
||||||
|
self.assertTrue(hit_except)
|
||||||
|
|
||||||
|
def test_try_except_else_no_exception(self):
|
||||||
|
hit_except = False
|
||||||
|
hit_else = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
else:
|
||||||
|
hit_else = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_except)
|
||||||
|
self.assertTrue(hit_else)
|
||||||
|
|
||||||
|
def test_try_finally_no_exception(self):
|
||||||
|
hit_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
|
||||||
|
def test_nested(self):
|
||||||
|
hit_finally = False
|
||||||
|
hit_inner_except = False
|
||||||
|
hit_inner_finally = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
raise Exception, 'inner exception'
|
||||||
|
except:
|
||||||
|
hit_inner_except = True
|
||||||
|
finally:
|
||||||
|
hit_inner_finally = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertTrue(hit_inner_except)
|
||||||
|
self.assertTrue(hit_inner_finally)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
|
||||||
|
def test_nested_else(self):
|
||||||
|
hit_else = False
|
||||||
|
hit_finally = False
|
||||||
|
hit_except = False
|
||||||
|
hit_inner_except = False
|
||||||
|
hit_inner_else = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
hit_inner_except = True
|
||||||
|
else:
|
||||||
|
hit_inner_else = True
|
||||||
|
|
||||||
|
raise Exception, 'outer exception'
|
||||||
|
except:
|
||||||
|
hit_except = True
|
||||||
|
else:
|
||||||
|
hit_else = True
|
||||||
|
finally:
|
||||||
|
hit_finally = True
|
||||||
|
|
||||||
|
self.assertFalse(hit_inner_except)
|
||||||
|
self.assertTrue(hit_inner_else)
|
||||||
|
self.assertFalse(hit_else)
|
||||||
|
self.assertTrue(hit_finally)
|
||||||
|
self.assertTrue(hit_except)
|
||||||
|
|
||||||
|
def test_main():
|
||||||
|
run_unittest(ExceptionTestCase)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_main()
|
|
@ -357,6 +357,7 @@ Chris Lawrence
|
||||||
Christopher Lee
|
Christopher Lee
|
||||||
Inyeol Lee
|
Inyeol Lee
|
||||||
John J. Lee
|
John J. Lee
|
||||||
|
Thomas Lee
|
||||||
Luc Lefebvre
|
Luc Lefebvre
|
||||||
Kip Lehman
|
Kip Lehman
|
||||||
Joerg Lehmann
|
Joerg Lehmann
|
||||||
|
|
116
Python/ast.c
116
Python/ast.c
|
@ -2597,66 +2597,78 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
|
||||||
static stmt_ty
|
static stmt_ty
|
||||||
ast_for_try_stmt(struct compiling *c, const node *n)
|
ast_for_try_stmt(struct compiling *c, const node *n)
|
||||||
{
|
{
|
||||||
|
const int nch = NCH(n);
|
||||||
|
int n_except = (nch - 3)/3;
|
||||||
|
asdl_seq *body, *orelse = NULL, *finally = NULL;
|
||||||
|
|
||||||
REQ(n, try_stmt);
|
REQ(n, try_stmt);
|
||||||
|
|
||||||
if (TYPE(CHILD(n, 3)) == NAME) {/* must be 'finally' */
|
body = ast_for_suite(c, CHILD(n, 2));
|
||||||
/* try_stmt: 'try' ':' suite 'finally' ':' suite) */
|
if (body == NULL)
|
||||||
asdl_seq *s1, *s2;
|
return NULL;
|
||||||
s1 = ast_for_suite(c, CHILD(n, 2));
|
|
||||||
if (!s1)
|
|
||||||
return NULL;
|
|
||||||
s2 = ast_for_suite(c, CHILD(n, 5));
|
|
||||||
if (!s2) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TryFinally(s1, s2, LINENO(n), c->c_arena);
|
|
||||||
}
|
|
||||||
else if (TYPE(CHILD(n, 3)) == except_clause) {
|
|
||||||
/* try_stmt: ('try' ':' suite (except_clause ':' suite)+
|
|
||||||
['else' ':' suite]
|
|
||||||
*/
|
|
||||||
asdl_seq *suite_seq1, *suite_seq2;
|
|
||||||
asdl_seq *handlers;
|
|
||||||
int i, has_else = 0, n_except = NCH(n) - 3;
|
|
||||||
if (TYPE(CHILD(n, NCH(n) - 3)) == NAME) {
|
|
||||||
has_else = 1;
|
|
||||||
n_except -= 3;
|
|
||||||
}
|
|
||||||
n_except /= 3;
|
|
||||||
handlers = asdl_seq_new(n_except, c->c_arena);
|
|
||||||
if (!handlers)
|
|
||||||
return NULL;
|
|
||||||
for (i = 0; i < n_except; i++) {
|
|
||||||
excepthandler_ty e = ast_for_except_clause(c,
|
|
||||||
CHILD(n, 3 + i * 3),
|
|
||||||
CHILD(n, 5 + i * 3));
|
|
||||||
if (!e) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
asdl_seq_SET(handlers, i, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
suite_seq1 = ast_for_suite(c, CHILD(n, 2));
|
if (TYPE(CHILD(n, nch - 3)) == NAME) {
|
||||||
if (!suite_seq1) {
|
if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
|
||||||
return NULL;
|
if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
|
||||||
}
|
/* we can assume it's an "else",
|
||||||
if (has_else) {
|
because nch >= 9 for try-else-finally and
|
||||||
suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
|
it would otherwise have a type of except_clause */
|
||||||
if (!suite_seq2) {
|
orelse = ast_for_suite(c, CHILD(n, nch - 4));
|
||||||
return NULL;
|
if (orelse == NULL)
|
||||||
}
|
return NULL;
|
||||||
}
|
n_except--;
|
||||||
else
|
}
|
||||||
suite_seq2 = NULL;
|
|
||||||
|
|
||||||
return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n),
|
finally = ast_for_suite(c, CHILD(n, nch - 1));
|
||||||
c->c_arena);
|
if (finally == NULL)
|
||||||
|
return NULL;
|
||||||
|
n_except--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we can assume it's an "else",
|
||||||
|
otherwise it would have a type of except_clause */
|
||||||
|
orelse = ast_for_suite(c, CHILD(n, nch - 1));
|
||||||
|
if (orelse == NULL)
|
||||||
|
return NULL;
|
||||||
|
n_except--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (TYPE(CHILD(n, nch - 3)) != except_clause) {
|
||||||
ast_error(n, "malformed 'try' statement");
|
ast_error(n, "malformed 'try' statement");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n_except > 0) {
|
||||||
|
int i;
|
||||||
|
stmt_ty except_st;
|
||||||
|
/* process except statements to create a try ... except */
|
||||||
|
asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
|
||||||
|
if (handlers == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < n_except; i++) {
|
||||||
|
excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),
|
||||||
|
CHILD(n, 5 + i * 3));
|
||||||
|
if (!e)
|
||||||
|
return NULL;
|
||||||
|
asdl_seq_SET(handlers, i, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
except_st = TryExcept(body, handlers, orelse, LINENO(n), c->c_arena);
|
||||||
|
if (!finally)
|
||||||
|
return except_st;
|
||||||
|
|
||||||
|
/* if a 'finally' is present too, we nest the TryExcept within a
|
||||||
|
TryFinally to emulate try ... except ... finally */
|
||||||
|
body = asdl_seq_new(1, c->c_arena);
|
||||||
|
if (body == NULL)
|
||||||
|
return NULL;
|
||||||
|
asdl_seq_SET(body, 0, except_st);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be a try ... finally (except clauses are in body, if any exist) */
|
||||||
|
assert(finally != NULL);
|
||||||
|
return TryFinally(body, finally, LINENO(n), c->c_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stmt_ty
|
static stmt_ty
|
||||||
|
|
|
@ -841,15 +841,26 @@ static arc arcs_39_6[1] = {
|
||||||
static arc arcs_39_7[1] = {
|
static arc arcs_39_7[1] = {
|
||||||
{22, 9},
|
{22, 9},
|
||||||
};
|
};
|
||||||
static arc arcs_39_8[3] = {
|
static arc arcs_39_8[4] = {
|
||||||
{95, 4},
|
{95, 4},
|
||||||
{91, 5},
|
{91, 10},
|
||||||
|
{96, 5},
|
||||||
{0, 8},
|
{0, 8},
|
||||||
};
|
};
|
||||||
static arc arcs_39_9[1] = {
|
static arc arcs_39_9[1] = {
|
||||||
{0, 9},
|
{0, 9},
|
||||||
};
|
};
|
||||||
static state states_39[10] = {
|
static arc arcs_39_10[1] = {
|
||||||
|
{21, 11},
|
||||||
|
};
|
||||||
|
static arc arcs_39_11[1] = {
|
||||||
|
{22, 12},
|
||||||
|
};
|
||||||
|
static arc arcs_39_12[2] = {
|
||||||
|
{96, 5},
|
||||||
|
{0, 12},
|
||||||
|
};
|
||||||
|
static state states_39[13] = {
|
||||||
{1, arcs_39_0},
|
{1, arcs_39_0},
|
||||||
{1, arcs_39_1},
|
{1, arcs_39_1},
|
||||||
{1, arcs_39_2},
|
{1, arcs_39_2},
|
||||||
|
@ -858,8 +869,11 @@ static state states_39[10] = {
|
||||||
{1, arcs_39_5},
|
{1, arcs_39_5},
|
||||||
{1, arcs_39_6},
|
{1, arcs_39_6},
|
||||||
{1, arcs_39_7},
|
{1, arcs_39_7},
|
||||||
{3, arcs_39_8},
|
{4, arcs_39_8},
|
||||||
{1, arcs_39_9},
|
{1, arcs_39_9},
|
||||||
|
{1, arcs_39_10},
|
||||||
|
{1, arcs_39_11},
|
||||||
|
{2, arcs_39_12},
|
||||||
};
|
};
|
||||||
static arc arcs_40_0[1] = {
|
static arc arcs_40_0[1] = {
|
||||||
{97, 1},
|
{97, 1},
|
||||||
|
@ -1754,7 +1768,7 @@ static dfa dfas[79] = {
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
|
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
|
||||||
{294, "for_stmt", 0, 10, states_38,
|
{294, "for_stmt", 0, 10, states_38,
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
|
"\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
|
||||||
{295, "try_stmt", 0, 10, states_39,
|
{295, "try_stmt", 0, 13, states_39,
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
|
"\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
|
||||||
{296, "except_clause", 0, 5, states_40,
|
{296, "except_clause", 0, 5, states_40,
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
|
"\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
|
||||||
|
|
Loading…
Reference in New Issue