Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Grammar/Grammar
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ try_stmt: ('try' ':' suite
['else' ':' suite]
['finally' ':' suite] |
'finally' ':' suite))
with_stmt: 'with' with_item (',' with_item)* ':' suite
with_stmt: 'with' ( with_item (',' with_item)* | '(' with_item (',' with_item)* [','] ')' ) ':' suite
with_item: test ['as' expr]
# NB compile.c makes sure that the default except clause is last
except_clause: 'except' [test ['as' NAME]]
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,18 @@ def __exit__(self, *args):
pass
with manager() as x, manager():
pass
with (manager() as x, manager() as y):
pass
with (manager() as x, manager() as y,):
pass
with (manager()):
pass
with (manager() as x):
pass
with (((manager()))):
pass
with ((((manager()))) as x):
pass

def test_if_else_expr(self):
# Test ifelse expressions in various cases
Expand Down
12 changes: 9 additions & 3 deletions Python/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -3901,16 +3901,22 @@ static stmt_ty
ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async)
{
const node * const n = is_async ? CHILD(n0, 1) : n0;
int i, n_items;
int i, n_items, paren_surrounded;
asdl_seq *items, *body;

REQ(n, with_stmt);

n_items = (NCH(n) - 2) / 2;
paren_surrounded = TYPE(CHILD(n, 1)) == LPAR ? 1 : 0;
n_items = (NCH(n) - 2 - 2 * paren_surrounded) / 2;
items = _Py_asdl_seq_new(n_items, c->c_arena);

if (!items)
return NULL;
for (i = 1; i < NCH(n) - 2; i += 2) {

/* We are jumping by two elements (the item and the comma) and therefore
* the limit of i < NCH(n) - 2 - paren_surrounded will handle also the case
* when there is a trailing comma (it will not iterate over the comma). */
for (i = 1 + paren_surrounded; i < NCH(n) - 2 - paren_surrounded; i += 2) {
withitem_ty item = ast_for_with_item(c, CHILD(n, i));
if (!item)
return NULL;
Expand Down
39 changes: 31 additions & 8 deletions Python/graminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,25 +1063,48 @@ static state states_44[13] = {
static arc arcs_45_0[1] = {
{106, 1},
};
static arc arcs_45_1[1] = {
static arc arcs_45_1[2] = {
{107, 2},
{13, 3},
};
static arc arcs_45_2[2] = {
{32, 1},
{27, 3},
{32, 4},
{27, 5},
};
static arc arcs_45_3[1] = {
{28, 4},
{107, 6},
};
static arc arcs_45_4[1] = {
{0, 4},
{107, 2},
};
static arc arcs_45_5[1] = {
{28, 7},
};
static arc arcs_45_6[2] = {
{32, 8},
{15, 9},
};
static arc arcs_45_7[1] = {
{0, 7},
};
static arc arcs_45_8[2] = {
{107, 6},
{15, 9},
};
static arc arcs_45_9[1] = {
{27, 5},
};
static state states_45[5] = {
static state states_45[10] = {
{1, arcs_45_0},
{1, arcs_45_1},
{2, arcs_45_1},
{2, arcs_45_2},
{1, arcs_45_3},
{1, arcs_45_4},
{1, arcs_45_5},
{2, arcs_45_6},
{1, arcs_45_7},
{2, arcs_45_8},
{1, arcs_45_9},
};
static arc arcs_46_0[1] = {
{26, 1},
Expand Down Expand Up @@ -2004,7 +2027,7 @@ static dfa dfas[87] = {
"\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
{300, "try_stmt", 0, 13, states_44,
"\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000"},
{301, "with_stmt", 0, 5, states_45,
{301, "with_stmt", 0, 10, states_45,
"\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"},
{302, "with_item", 0, 4, states_46,
"\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000\000"},
Expand Down