Skip to content

Commit 16be03e

Browse files
committed
Some more changes related to the new except syntax and semantics,
by Collin Winter.
1 parent b940e11 commit 16be03e

File tree

10 files changed

+47
-33
lines changed

10 files changed

+47
-33
lines changed

Grammar/Grammar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ try_stmt: ('try' ':' suite
7979
with_stmt: 'with' test [ with_var ] ':' suite
8080
with_var: 'as' expr
8181
# NB compile.c makes sure that the default except clause is last
82-
except_clause: 'except' [test ['as' test]]
82+
except_clause: 'except' [test ['as' NAME]]
8383
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
8484

8585
# Backward compatibility cruft to support:

Include/Python-ast.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ struct _comprehension {
322322

323323
struct _excepthandler {
324324
expr_ty type;
325-
expr_ty name;
325+
identifier name;
326326
asdl_seq *body;
327327
int lineno;
328328
int col_offset;
@@ -448,8 +448,8 @@ slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
448448
slice_ty Index(expr_ty value, PyArena *arena);
449449
comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
450450
PyArena *arena);
451-
excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int
452-
lineno, int col_offset, PyArena *arena);
451+
excepthandler_ty excepthandler(expr_ty type, identifier name, asdl_seq * body,
452+
int lineno, int col_offset, PyArena *arena);
453453
arguments_ty arguments(asdl_seq * args, identifier vararg, expr_ty
454454
varargannotation, asdl_seq * kwonlyargs, identifier
455455
kwarg, expr_ty kwargannotation, asdl_seq * defaults,

Lib/compiler/pycodegen.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -825,11 +825,33 @@ def visitTryExcept(self, node):
825825
self.emit('POP_TOP')
826826
self.emit('POP_TOP')
827827
if target:
828-
self.visit(target)
828+
cleanup_body = self.newBlock()
829+
cleanup_final = self.newBlock()
830+
target_name = target[1]
831+
832+
self.storeName(target_name)
833+
self.emit('POP_TOP')
834+
self.emit('SETUP_FINALLY', cleanup_final)
835+
self.nextBlock(cleanup_body)
836+
self.setups.push((TRY_FINALLY, cleanup_body))
837+
self.visit(body)
838+
self.emit('POP_BLOCK')
839+
self.setups.pop()
840+
self.emit('LOAD_CONST', None)
841+
self.nextBlock(cleanup_final)
842+
self.setups.push((END_FINALLY, cleanup_final))
843+
844+
845+
self.emit('LOAD_CONST', None)
846+
self.storeName(target_name)
847+
self._implicitNameOp('DELETE', target_name)
848+
849+
self.emit('END_FINALLY')
850+
self.setups.pop()
829851
else:
830852
self.emit('POP_TOP')
831-
self.emit('POP_TOP')
832-
self.visit(body)
853+
self.emit('POP_TOP')
854+
self.visit(body)
833855
self.emit('JUMP_FORWARD', end)
834856
if expr:
835857
self.nextBlock(next)

Lib/compiler/transformer.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -988,16 +988,16 @@ def com_try_except_finally(self, nodelist):
988988
for i in range(3, len(nodelist), 3):
989989
node = nodelist[i]
990990
if node[0] == symbol.except_clause:
991-
# except_clause: 'except' [expr [',' expr]] */
991+
# except_clause: 'except' [expr ['as' NAME]] */
992992
if len(node) > 2:
993-
expr1 = self.com_node(node[2])
993+
expr = self.com_node(node[2])
994994
if len(node) > 4:
995-
expr2 = self.com_assign(node[4], OP_ASSIGN)
995+
expr_name = node[4]
996996
else:
997-
expr2 = None
997+
expr_name = None
998998
else:
999-
expr1 = expr2 = None
1000-
clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
999+
expr = expr_name = None
1000+
clauses.append((expr, expr_name, self.com_node(nodelist[i+2])))
10011001

10021002
if node[0] == token.NAME:
10031003
if node[1] == 'else':

Parser/Python.asdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ module Python version "$Revision$"
9797
-- TODO(jhylton): Figure out if there is a better way to handle
9898
-- lineno and col_offset fields, particularly when
9999
-- ast is exposed to Python.
100-
excepthandler = (expr? type, expr? name, stmt* body, int lineno,
100+
excepthandler = (expr? type, identifier? name, stmt* body, int lineno,
101101
int col_offset)
102102

103103
arguments = (arg* args, identifier? vararg, expr? varargannotation,

Python/Python-ast.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
18361836
}
18371837

18381838
excepthandler_ty
1839-
excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
1839+
excepthandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
18401840
col_offset, PyArena *arena)
18411841
{
18421842
excepthandler_ty p;
@@ -2928,7 +2928,7 @@ ast2obj_excepthandler(void* _o)
29282928
if (PyObject_SetAttrString(result, "type", value) == -1)
29292929
goto failed;
29302930
Py_DECREF(value);
2931-
value = ast2obj_expr(o->name);
2931+
value = ast2obj_identifier(o->name);
29322932
if (!value) goto failed;
29332933
if (PyObject_SetAttrString(result, "name", value) == -1)
29342934
goto failed;

Python/ast.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,11 +2899,9 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
28992899
else if (NCH(exc) == 4) {
29002900
asdl_seq *suite_seq;
29012901
expr_ty expression;
2902-
expr_ty e = ast_for_expr(c, CHILD(exc, 3));
2902+
identifier e = NEW_IDENTIFIER(CHILD(exc, 3));
29032903
if (!e)
29042904
return NULL;
2905-
if (!set_context(e, Store, CHILD(exc, 3)))
2906-
return NULL;
29072905
expression = ast_for_expr(c, CHILD(exc, 1));
29082906
if (!expression)
29092907
return NULL;

Python/compile.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,16 +1956,13 @@ compiler_try_except(struct compiler *c, stmt_ty s)
19561956
ADDOP(c, POP_TOP);
19571957
if (handler->name) {
19581958
basicblock *cleanup_end, *cleanup_body;
1959-
expr_context_ty orig_ctx;
1960-
1961-
assert(handler->name->kind == Name_kind);
19621959

19631960
cleanup_end = compiler_new_block(c);
19641961
cleanup_body = compiler_new_block(c);
19651962
if(!(cleanup_end || cleanup_body))
19661963
return 0;
19671964

1968-
VISIT(c, expr, handler->name);
1965+
compiler_nameop(c, handler->name, Store);
19691966
ADDOP(c, POP_TOP);
19701967

19711968
/*
@@ -1998,14 +1995,10 @@ compiler_try_except(struct compiler *c, stmt_ty s)
19981995

19991996
/* name = None */
20001997
ADDOP_O(c, LOAD_CONST, Py_None, consts);
2001-
orig_ctx = handler->name->v.Name.ctx;
2002-
handler->name->v.Name.ctx = Store;
2003-
VISIT(c, expr, handler->name);
2004-
2005-
/* del name */
2006-
handler->name->v.Name.ctx = Del;
2007-
VISIT(c, expr, handler->name);
2008-
handler->name->v.Name.ctx = orig_ctx;
1998+
compiler_nameop(c, handler->name, Store);
1999+
2000+
/* del name */
2001+
compiler_nameop(c, handler->name, Del);
20092002

20102003
ADDOP(c, END_FINALLY);
20112004
compiler_pop_fblock(c, FINALLY_END, cleanup_end);

Python/graminit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ static arc arcs_46_2[2] = {
10531053
{0, 2},
10541054
};
10551055
static arc arcs_46_3[1] = {
1056-
{22, 4},
1056+
{19, 4},
10571057
};
10581058
static arc arcs_46_4[1] = {
10591059
{0, 4},

Python/symtable.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,8 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
13351335
if (eh->type)
13361336
VISIT(st, expr, eh->type);
13371337
if (eh->name)
1338-
VISIT(st, expr, eh->name);
1338+
if (!symtable_add_def(st, eh->name, DEF_LOCAL))
1339+
return 0;
13391340
VISIT_SEQ(st, stmt, eh->body);
13401341
return 1;
13411342
}

0 commit comments

Comments
 (0)