summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-05-25 21:10:36 (GMT)
committerGeorg Brandl <georg@python.org>2009-05-25 21:10:36 (GMT)
commit0c31562a913e9a49842bd73c04847861c23774f1 (patch)
treef5fb007402b1a1863c4d317b08be6de4f5547b66 /Python/ast.c
parent0c1829b919cce6f6823e843a16c52e104f28c7f9 (diff)
downloadcpython-0c31562a913e9a49842bd73c04847861c23774f1.zip
cpython-0c31562a913e9a49842bd73c04847861c23774f1.tar.gz
cpython-0c31562a913e9a49842bd73c04847861c23774f1.tar.bz2
Merged revisions 72924 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r72924 | georg.brandl | 2009-05-25 23:02:56 +0200 (Mo, 25 Mai 2009) | 6 lines Allow multiple context managers in one with statement, as proposed in http://codereview.appspot.com/53094 and accepted by Guido. The construct is transformed into multiple With AST nodes so that there should be no problems with the semantics. ........
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c61
1 files changed, 41 insertions, 20 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 1c79359..ff412b3 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2959,25 +2959,16 @@ ast_for_try_stmt(struct compiling *c, const node *n)
return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
}
-static expr_ty
-ast_for_with_var(struct compiling *c, const node *n)
-{
- REQ(n, with_var);
- return ast_for_expr(c, CHILD(n, 1));
-}
-
-/* with_stmt: 'with' test [ with_var ] ':' suite */
+/* with_item: test ['as' expr] */
static stmt_ty
-ast_for_with_stmt(struct compiling *c, const node *n)
+ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content)
{
expr_ty context_expr, optional_vars = NULL;
- int suite_index = 3; /* skip 'with', test, and ':' */
- asdl_seq *suite_seq;
- assert(TYPE(n) == with_stmt);
- context_expr = ast_for_expr(c, CHILD(n, 1));
- if (TYPE(CHILD(n, 2)) == with_var) {
- optional_vars = ast_for_with_var(c, CHILD(n, 2));
+ REQ(n, with_item);
+ context_expr = ast_for_expr(c, CHILD(n, 0));
+ if (NCH(n) == 3) {
+ optional_vars = ast_for_expr(c, CHILD(n, 2));
if (!optional_vars) {
return NULL;
@@ -2985,15 +2976,45 @@ ast_for_with_stmt(struct compiling *c, const node *n)
if (!set_context(c, optional_vars, Store, n)) {
return NULL;
}
- suite_index = 4;
}
- suite_seq = ast_for_suite(c, CHILD(n, suite_index));
- if (!suite_seq) {
+ return With(context_expr, optional_vars, content, LINENO(n),
+ n->n_col_offset, c->c_arena);
+}
+
+/* with_stmt: 'with' with_item (',' with_item)* ':' suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n)
+{
+ int i;
+ stmt_ty ret;
+ asdl_seq *inner;
+
+ REQ(n, with_stmt);
+
+ /* process the with items inside-out */
+ i = NCH(n) - 1;
+ /* the suite of the innermost with item is the suite of the with stmt */
+ inner = ast_for_suite(c, CHILD(n, i));
+ if (!inner)
return NULL;
+
+ for (;;) {
+ i -= 2;
+ ret = ast_for_with_item(c, CHILD(n, i), inner);
+ if (!ret)
+ return NULL;
+ /* was this the last item? */
+ if (i == 1)
+ break;
+ /* if not, wrap the result so far in a new sequence */
+ inner = asdl_seq_new(1, c->c_arena);
+ if (!inner)
+ return NULL;
+ asdl_seq_SET(inner, 0, ret);
}
- return With(context_expr, optional_vars, suite_seq, LINENO(n),
- n->n_col_offset, c->c_arena);
+
+ return ret;
}
static stmt_ty