mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
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
5 changed files with 265 additions and 59 deletions
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
|
||||
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);
|
||||
|
||||
if (TYPE(CHILD(n, 3)) == NAME) {/* must be 'finally' */
|
||||
/* try_stmt: 'try' ':' suite 'finally' ':' suite) */
|
||||
asdl_seq *s1, *s2;
|
||||
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);
|
||||
}
|
||||
body = ast_for_suite(c, CHILD(n, 2));
|
||||
if (body == NULL)
|
||||
return NULL;
|
||||
|
||||
suite_seq1 = ast_for_suite(c, CHILD(n, 2));
|
||||
if (!suite_seq1) {
|
||||
return NULL;
|
||||
}
|
||||
if (has_else) {
|
||||
suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
|
||||
if (!suite_seq2) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
suite_seq2 = NULL;
|
||||
if (TYPE(CHILD(n, nch - 3)) == NAME) {
|
||||
if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
|
||||
if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
|
||||
/* we can assume it's an "else",
|
||||
because nch >= 9 for try-else-finally and
|
||||
it would otherwise have a type of except_clause */
|
||||
orelse = ast_for_suite(c, CHILD(n, nch - 4));
|
||||
if (orelse == NULL)
|
||||
return NULL;
|
||||
n_except--;
|
||||
}
|
||||
|
||||
return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n),
|
||||
c->c_arena);
|
||||
finally = ast_for_suite(c, CHILD(n, nch - 1));
|
||||
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");
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue