Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f599f42

Browse files
committed
SF patch #1355913, PEP 341 - Unification of try/except and try/finally
Modified since ast-arenas was implemented.
1 parent adb69fc commit f599f42

5 files changed

Lines changed: 263 additions & 57 deletions

File tree

Grammar/Grammar

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
6767
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
6868
while_stmt: 'while' test ':' suite ['else' ':' suite]
6969
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
70-
try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
71-
['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
70+
try_stmt: 'try' ':' suite ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite)
7271
# NB compile.c makes sure that the default except clause is last
7372
except_clause: 'except' [test [',' test]]
7473
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
2+
from test.test_support import run_unittest
3+
import unittest
4+
5+
class ExceptionTestCase(unittest.TestCase):
6+
def test_try_except_else_finally(self):
7+
hit_except = False
8+
hit_else = False
9+
hit_finally = False
10+
11+
try:
12+
raise Exception, 'nyaa!'
13+
except:
14+
hit_except = True
15+
else:
16+
hit_else = True
17+
finally:
18+
hit_finally = True
19+
20+
self.assertTrue(hit_except)
21+
self.assertTrue(hit_finally)
22+
self.assertFalse(hit_else)
23+
24+
def test_try_except_else_finally_no_exception(self):
25+
hit_except = False
26+
hit_else = False
27+
hit_finally = False
28+
29+
try:
30+
pass
31+
except:
32+
hit_except = True
33+
else:
34+
hit_else = True
35+
finally:
36+
hit_finally = True
37+
38+
self.assertFalse(hit_except)
39+
self.assertTrue(hit_finally)
40+
self.assertTrue(hit_else)
41+
42+
def test_try_except_finally(self):
43+
hit_except = False
44+
hit_finally = False
45+
46+
try:
47+
raise Exception, 'yarr!'
48+
except:
49+
hit_except = True
50+
finally:
51+
hit_finally = True
52+
53+
self.assertTrue(hit_except)
54+
self.assertTrue(hit_finally)
55+
56+
def test_try_except_finally_no_exception(self):
57+
hit_except = False
58+
hit_finally = False
59+
60+
try:
61+
pass
62+
except:
63+
hit_except = True
64+
finally:
65+
hit_finally = True
66+
67+
self.assertFalse(hit_except)
68+
self.assertTrue(hit_finally)
69+
70+
def test_try_except(self):
71+
hit_except = False
72+
73+
try:
74+
raise Exception, 'ahoy!'
75+
except:
76+
hit_except = True
77+
78+
self.assertTrue(hit_except)
79+
80+
def test_try_except_no_exception(self):
81+
hit_except = False
82+
83+
try:
84+
pass
85+
except:
86+
hit_except = True
87+
88+
self.assertFalse(hit_except)
89+
90+
def test_try_except_else(self):
91+
hit_except = False
92+
hit_else = False
93+
94+
try:
95+
raise Exception, 'foo!'
96+
except:
97+
hit_except = True
98+
else:
99+
hit_else = True
100+
101+
self.assertFalse(hit_else)
102+
self.assertTrue(hit_except)
103+
104+
def test_try_except_else_no_exception(self):
105+
hit_except = False
106+
hit_else = False
107+
108+
try:
109+
pass
110+
except:
111+
hit_except = True
112+
else:
113+
hit_else = True
114+
115+
self.assertFalse(hit_except)
116+
self.assertTrue(hit_else)
117+
118+
def test_try_finally_no_exception(self):
119+
hit_finally = False
120+
121+
try:
122+
pass
123+
finally:
124+
hit_finally = True
125+
126+
self.assertTrue(hit_finally)
127+
128+
def test_nested(self):
129+
hit_finally = False
130+
hit_inner_except = False
131+
hit_inner_finally = False
132+
133+
try:
134+
try:
135+
raise Exception, 'inner exception'
136+
except:
137+
hit_inner_except = True
138+
finally:
139+
hit_inner_finally = True
140+
finally:
141+
hit_finally = True
142+
143+
self.assertTrue(hit_inner_except)
144+
self.assertTrue(hit_inner_finally)
145+
self.assertTrue(hit_finally)
146+
147+
def test_nested_else(self):
148+
hit_else = False
149+
hit_finally = False
150+
hit_except = False
151+
hit_inner_except = False
152+
hit_inner_else = False
153+
154+
try:
155+
try:
156+
pass
157+
except:
158+
hit_inner_except = True
159+
else:
160+
hit_inner_else = True
161+
162+
raise Exception, 'outer exception'
163+
except:
164+
hit_except = True
165+
else:
166+
hit_else = True
167+
finally:
168+
hit_finally = True
169+
170+
self.assertFalse(hit_inner_except)
171+
self.assertTrue(hit_inner_else)
172+
self.assertFalse(hit_else)
173+
self.assertTrue(hit_finally)
174+
self.assertTrue(hit_except)
175+
176+
def test_main():
177+
run_unittest(ExceptionTestCase)
178+
179+
if __name__ == '__main__':
180+
test_main()

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ Chris Lawrence
357357
Christopher Lee
358358
Inyeol Lee
359359
John J. Lee
360+
Thomas Lee
360361
Luc Lefebvre
361362
Kip Lehman
362363
Joerg Lehmann

Python/ast.c

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,66 +2597,78 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
25972597
static stmt_ty
25982598
ast_for_try_stmt(struct compiling *c, const node *n)
25992599
{
2600+
const int nch = NCH(n);
2601+
int n_except = (nch - 3)/3;
2602+
asdl_seq *body, *orelse = NULL, *finally = NULL;
2603+
26002604
REQ(n, try_stmt);
26012605

2602-
if (TYPE(CHILD(n, 3)) == NAME) {/* must be 'finally' */
2603-
/* try_stmt: 'try' ':' suite 'finally' ':' suite) */
2604-
asdl_seq *s1, *s2;
2605-
s1 = ast_for_suite(c, CHILD(n, 2));
2606-
if (!s1)
2607-
return NULL;
2608-
s2 = ast_for_suite(c, CHILD(n, 5));
2609-
if (!s2) {
2610-
return NULL;
2611-
}
2612-
2613-
return TryFinally(s1, s2, LINENO(n), c->c_arena);
2614-
}
2615-
else if (TYPE(CHILD(n, 3)) == except_clause) {
2616-
/* try_stmt: ('try' ':' suite (except_clause ':' suite)+
2617-
['else' ':' suite]
2618-
*/
2619-
asdl_seq *suite_seq1, *suite_seq2;
2620-
asdl_seq *handlers;
2621-
int i, has_else = 0, n_except = NCH(n) - 3;
2622-
if (TYPE(CHILD(n, NCH(n) - 3)) == NAME) {
2623-
has_else = 1;
2624-
n_except -= 3;
2625-
}
2626-
n_except /= 3;
2627-
handlers = asdl_seq_new(n_except, c->c_arena);
2628-
if (!handlers)
2629-
return NULL;
2630-
for (i = 0; i < n_except; i++) {
2631-
excepthandler_ty e = ast_for_except_clause(c,
2632-
CHILD(n, 3 + i * 3),
2633-
CHILD(n, 5 + i * 3));
2634-
if (!e) {
2606+
body = ast_for_suite(c, CHILD(n, 2));
2607+
if (body == NULL)
2608+
return NULL;
2609+
2610+
if (TYPE(CHILD(n, nch - 3)) == NAME) {
2611+
if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
2612+
if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
2613+
/* we can assume it's an "else",
2614+
because nch >= 9 for try-else-finally and
2615+
it would otherwise have a type of except_clause */
2616+
orelse = ast_for_suite(c, CHILD(n, nch - 4));
2617+
if (orelse == NULL)
2618+
return NULL;
2619+
n_except--;
2620+
}
2621+
2622+
finally = ast_for_suite(c, CHILD(n, nch - 1));
2623+
if (finally == NULL)
26352624
return NULL;
2636-
}
2637-
asdl_seq_SET(handlers, i, e);
2625+
n_except--;
26382626
}
2639-
2640-
suite_seq1 = ast_for_suite(c, CHILD(n, 2));
2641-
if (!suite_seq1) {
2642-
return NULL;
2643-
}
2644-
if (has_else) {
2645-
suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
2646-
if (!suite_seq2) {
2627+
else {
2628+
/* we can assume it's an "else",
2629+
otherwise it would have a type of except_clause */
2630+
orelse = ast_for_suite(c, CHILD(n, nch - 1));
2631+
if (orelse == NULL)
26472632
return NULL;
2648-
}
2633+
n_except--;
26492634
}
2650-
else
2651-
suite_seq2 = NULL;
2652-
2653-
return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n),
2654-
c->c_arena);
26552635
}
2656-
else {
2636+
else if (TYPE(CHILD(n, nch - 3)) != except_clause) {
26572637
ast_error(n, "malformed 'try' statement");
26582638
return NULL;
26592639
}
2640+
2641+
if (n_except > 0) {
2642+
int i;
2643+
stmt_ty except_st;
2644+
/* process except statements to create a try ... except */
2645+
asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
2646+
if (handlers == NULL)
2647+
return NULL;
2648+
2649+
for (i = 0; i < n_except; i++) {
2650+
excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),
2651+
CHILD(n, 5 + i * 3));
2652+
if (!e)
2653+
return NULL;
2654+
asdl_seq_SET(handlers, i, e);
2655+
}
2656+
2657+
except_st = TryExcept(body, handlers, orelse, LINENO(n), c->c_arena);
2658+
if (!finally)
2659+
return except_st;
2660+
2661+
/* if a 'finally' is present too, we nest the TryExcept within a
2662+
TryFinally to emulate try ... except ... finally */
2663+
body = asdl_seq_new(1, c->c_arena);
2664+
if (body == NULL)
2665+
return NULL;
2666+
asdl_seq_SET(body, 0, except_st);
2667+
}
2668+
2669+
/* must be a try ... finally (except clauses are in body, if any exist) */
2670+
assert(finally != NULL);
2671+
return TryFinally(body, finally, LINENO(n), c->c_arena);
26602672
}
26612673

26622674
static stmt_ty

Python/graminit.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -841,15 +841,26 @@ static arc arcs_39_6[1] = {
841841
static arc arcs_39_7[1] = {
842842
{22, 9},
843843
};
844-
static arc arcs_39_8[3] = {
844+
static arc arcs_39_8[4] = {
845845
{95, 4},
846-
{91, 5},
846+
{91, 10},
847+
{96, 5},
847848
{0, 8},
848849
};
849850
static arc arcs_39_9[1] = {
850851
{0, 9},
851852
};
852-
static state states_39[10] = {
853+
static arc arcs_39_10[1] = {
854+
{21, 11},
855+
};
856+
static arc arcs_39_11[1] = {
857+
{22, 12},
858+
};
859+
static arc arcs_39_12[2] = {
860+
{96, 5},
861+
{0, 12},
862+
};
863+
static state states_39[13] = {
853864
{1, arcs_39_0},
854865
{1, arcs_39_1},
855866
{1, arcs_39_2},
@@ -858,8 +869,11 @@ static state states_39[10] = {
858869
{1, arcs_39_5},
859870
{1, arcs_39_6},
860871
{1, arcs_39_7},
861-
{3, arcs_39_8},
872+
{4, arcs_39_8},
862873
{1, arcs_39_9},
874+
{1, arcs_39_10},
875+
{1, arcs_39_11},
876+
{2, arcs_39_12},
863877
};
864878
static arc arcs_40_0[1] = {
865879
{97, 1},
@@ -1754,7 +1768,7 @@ static dfa dfas[79] = {
17541768
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
17551769
{294, "for_stmt", 0, 10, states_38,
17561770
"\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
1757-
{295, "try_stmt", 0, 10, states_39,
1771+
{295, "try_stmt", 0, 13, states_39,
17581772
"\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
17591773
{296, "except_clause", 0, 5, states_40,
17601774
"\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},

0 commit comments

Comments
 (0)