diff options
author | Mark Dickinson <mdickinson@enthought.com> | 2012-04-29 21:18:31 (GMT) |
---|---|---|
committer | Mark Dickinson <mdickinson@enthought.com> | 2012-04-29 21:18:31 (GMT) |
commit | 407b3bd89b877c198bf9cdbf290ddb91b49910b5 (patch) | |
tree | 2e60f2c615ab3ce8176763ba281897035b4e865f | |
parent | 2420d831582a5403d679b6383933112948d476fe (diff) | |
download | cpython-407b3bd89b877c198bf9cdbf290ddb91b49910b5.zip cpython-407b3bd89b877c198bf9cdbf290ddb91b49910b5.tar.gz cpython-407b3bd89b877c198bf9cdbf290ddb91b49910b5.tar.bz2 |
Issue #14696: Fix parser module to understand 'nonlocal' declarations.
-rw-r--r-- | Lib/test/test_parser.py | 10 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/parsermodule.c | 41 |
3 files changed, 48 insertions, 5 deletions
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 833d317..f6105fc 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -57,6 +57,16 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): " if (yield):\n" " yield x\n") + def test_nonlocal_statement(self): + self.check_suite("def f():\n" + " x = 0\n" + " def g():\n" + " nonlocal x\n") + self.check_suite("def f():\n" + " x = y = 0\n" + " def g():\n" + " nonlocal x, y\n") + def test_expressions(self): self.check_expr("foo(1)") self.check_expr("[1, 2, 3]") @@ -56,6 +56,8 @@ Core and Builtins Library ------- +- Issue #14696: Fix parser module to understand 'nonlocal' declarations. + - Issue #10941: Fix imaplib.Internaldate2tuple to produce correct result near the DST transition. Patch by Joe Peterson. diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index bc4e74b..99e476d 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -954,7 +954,8 @@ VALIDATER(del_stmt); VALIDATER(return_stmt); VALIDATER(raise_stmt); VALIDATER(import_stmt); VALIDATER(import_stmt); VALIDATER(import_name); VALIDATER(yield_stmt); -VALIDATER(global_stmt); VALIDATER(assert_stmt); +VALIDATER(global_stmt); VALIDATER(nonlocal_stmt); +VALIDATER(assert_stmt); VALIDATER(compound_stmt); VALIDATER(test_or_star_expr); VALIDATER(while); VALIDATER(for); VALIDATER(try); VALIDATER(except_clause); @@ -1477,6 +1478,7 @@ validate_small_stmt(node *tree) || (ntype == flow_stmt) || (ntype == import_stmt) || (ntype == global_stmt) + || (ntype == nonlocal_stmt) || (ntype == assert_stmt)) res = validate_node(CHILD(tree, 0)); else { @@ -1834,8 +1836,10 @@ validate_import_stmt(node *tree) } - - +/* global_stmt: + * + * 'global' NAME (',' NAME)* + */ static int validate_global_stmt(node *tree) { @@ -1857,6 +1861,30 @@ validate_global_stmt(node *tree) return (res); } +/* nonlocal_stmt: + * + * 'nonlocal' NAME (',' NAME)* + */ +static int +validate_nonlocal_stmt(node *tree) +{ + int j; + int nch = NCH(tree); + int res = (validate_ntype(tree, nonlocal_stmt) + && is_even(nch) && (nch >= 2)); + + if (!res && !PyErr_Occurred()) + err_string("illegal nonlocal statement"); + + if (res) + res = (validate_name(CHILD(tree, 0), "nonlocal") + && validate_ntype(CHILD(tree, 1), NAME)); + for (j = 2; res && (j < nch); j += 2) + res = (validate_comma(CHILD(tree, j)) + && validate_ntype(CHILD(tree, j + 1), NAME)); + + return res; +} /* assert_stmt: * @@ -2921,8 +2949,8 @@ validate_node(node *tree) break; case small_stmt: /* - * expr_stmt | del_stmt | pass_stmt | flow_stmt - * | import_stmt | global_stmt | assert_stmt + * expr_stmt | del_stmt | pass_stmt | flow_stmt | + * import_stmt | global_stmt | nonlocal_stmt | assert_stmt */ res = validate_small_stmt(tree); break; @@ -2989,6 +3017,9 @@ validate_node(node *tree) case global_stmt: res = validate_global_stmt(tree); break; + case nonlocal_stmt: + res = validate_nonlocal_stmt(tree); + break; case assert_stmt: res = validate_assert_stmt(tree); break; |