[Python-checkins] r67576 - in python/trunk: Lib/test/test_parser.py Misc/NEWS Modules/parsermodule.c

georg.brandl python-checkins at python.org
Fri Dec 5 13:09:42 CET 2008


Author: georg.brandl
Date: Fri Dec  5 13:09:41 2008
New Revision: 67576

Log:
#4529: fix parser's validation for try-except-finally statements.


Modified:
   python/trunk/Lib/test/test_parser.py
   python/trunk/Misc/NEWS
   python/trunk/Modules/parsermodule.c

Modified: python/trunk/Lib/test/test_parser.py
==============================================================================
--- python/trunk/Lib/test/test_parser.py	(original)
+++ python/trunk/Lib/test/test_parser.py	Fri Dec  5 13:09:41 2008
@@ -200,6 +200,16 @@
         self.check_suite("with open('x'): pass\n")
         self.check_suite("with open('x') as f: pass\n")
 
+    def test_try_stmt(self):
+        self.check_suite("try: pass\nexcept: pass\n")
+        self.check_suite("try: pass\nfinally: pass\n")
+        self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
+        self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
+                         "finally: pass\n")
+        self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
+        self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
+                         "finally: pass\n")
+
     def test_position(self):
         # An absolutely minimal test of position information.  Better
         # tests would be a big project.

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Fri Dec  5 13:09:41 2008
@@ -60,6 +60,9 @@
 Library
 -------
 
+- Issue #4529: fix the parser module's validation of try-except-finally
+  statements.
+
 - Issue #4458: getopt.gnu_getopt() now recognizes a single "-" as an argument,
   not a malformed option.
 

Modified: python/trunk/Modules/parsermodule.c
==============================================================================
--- python/trunk/Modules/parsermodule.c	(original)
+++ python/trunk/Modules/parsermodule.c	Fri Dec  5 13:09:41 2008
@@ -2057,6 +2057,7 @@
 
 /*  try_stmt:
  *      'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+                                                   ['finally' ':' suite]
  *    | 'try' ':' suite 'finally' ':' suite
  *
  */
@@ -2082,35 +2083,34 @@
         PyErr_Format(parser_error,
                      "Illegal number of children for try/%s node.", name);
     }
-    /*  Skip past except_clause sections:  */
+    /* Handle try/finally statement */
+    if (res && (TYPE(CHILD(tree, pos)) == NAME) &&
+        (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) {
+        res = (validate_numnodes(tree, 6, "try/finally")
+               && validate_colon(CHILD(tree, 4))
+               && validate_suite(CHILD(tree, 5)));
+        return (res);
+    }
+    /* try/except statement: skip past except_clause sections */
     while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
         res = (validate_except_clause(CHILD(tree, pos))
                && validate_colon(CHILD(tree, pos + 1))
                && validate_suite(CHILD(tree, pos + 2)));
         pos += 3;
     }
-    if (res && (pos < nch)) {
-        res = validate_ntype(CHILD(tree, pos), NAME);
-        if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
-            res = (validate_numnodes(tree, 6, "try/finally")
-                   && validate_colon(CHILD(tree, 4))
-                   && validate_suite(CHILD(tree, 5)));
-        else if (res) {
-            if (nch == (pos + 3)) {
-                res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
-                       || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
-                if (!res)
-                    err_string("illegal trailing triple in try statement");
-            }
-            else if (nch == (pos + 6)) {
-                res = (validate_name(CHILD(tree, pos), "except")
-                       && validate_colon(CHILD(tree, pos + 1))
-                       && validate_suite(CHILD(tree, pos + 2))
-                       && validate_name(CHILD(tree, pos + 3), "else"));
-            }
-            else
-                res = validate_numnodes(tree, pos + 3, "try/except");
-        }
+    /* skip else clause */
+    if (res && (TYPE(CHILD(tree, pos)) == NAME) &&
+        (strcmp(STR(CHILD(tree, pos)), "else") == 0)) {
+        res = (validate_colon(CHILD(tree, pos + 1))
+               && validate_suite(CHILD(tree, pos + 2)));
+        pos += 3;
+    }
+    if (res && pos < nch) {
+        /* last clause must be a finally */
+        res = (validate_name(CHILD(tree, pos), "finally")
+               && validate_numnodes(tree, pos + 3, "try/except/finally")
+               && validate_colon(CHILD(tree, pos + 1))
+               && validate_suite(CHILD(tree, pos + 2)));
     }
     return (res);
 }


More information about the Python-checkins mailing list