]> granicus.if.org Git - python/commitdiff
reject non-docs strings between future imports (closes #17434)
authorBenjamin Peterson <benjamin@python.org>
Sat, 16 Mar 2013 16:15:47 +0000 (09:15 -0700)
committerBenjamin Peterson <benjamin@python.org>
Sat, 16 Mar 2013 16:15:47 +0000 (09:15 -0700)
Lib/test/badsyntax_future10.py [new file with mode: 0644]
Lib/test/test_future.py
Misc/NEWS
Python/future.c

diff --git a/Lib/test/badsyntax_future10.py b/Lib/test/badsyntax_future10.py
new file mode 100644 (file)
index 0000000..fa5ab67
--- /dev/null
@@ -0,0 +1,3 @@
+from __future__ import absolute_import
+"spam, bar, blah"
+from __future__ import print_function
index a0c156f5f7baa6d17b5337f78f5c24a8da3a9837..beac993e4d543f7a29ce2a2e826c2e6bfd02bec1 100644 (file)
@@ -82,6 +82,14 @@ class FutureTest(unittest.TestCase):
         else:
             self.fail("expected exception didn't occur")
 
+    def test_badfuture10(self):
+        try:
+            from test import badsyntax_future10
+        except SyntaxError as msg:
+            self.assertEqual(get_error_location(msg), ("badsyntax_future10", '3'))
+        else:
+            self.fail("expected exception didn't occur")
+
     def test_parserhack(self):
         # test that the parser.c::future_hack function works as expected
         # Note: although this test must pass, it's not testing the original
index 389be1c9b3a70f093f901897695948a1f50580ef..b79e295be38ba64569e2d87e78a7d0f43fb5924c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
 Core and Builtins
 -----------------
 
+- Issue #17434: Properly raise a SyntaxError when a string occurs between future
+  imports.
+
 - Issue #17117: Import and @importlib.util.set_loader now set __loader__ when
   it has a value of None or the attribute doesn't exist.
 
index d24ae416ff5d1ba03938bc39628925e2c276415e..345efb2167590fe91e66c3f531b6616c637476af 100644 (file)
@@ -58,11 +58,14 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
 static int
 future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
 {
-    int i, found_docstring = 0, done = 0, prev_line = 0;
+    int i, done = 0, prev_line = 0;
 
     if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
         return 1;
 
+    if (asdl_seq_LEN(mod->v.Module.body) == 0)
+        return 1;
+
     /* A subsequent pass will detect future imports that don't
        appear at the beginning of the file.  There's one case,
        however, that is easier to handle here: A series of imports
@@ -71,8 +74,13 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
        but is preceded by a regular import.
     */
 
+    i = 0;
+    stmt_ty first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
+    if (first->kind == Expr_kind && first->v.Expr.value->kind == Str_kind)
+        i++;
 
-    for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
+
+    for (; i < asdl_seq_LEN(mod->v.Module.body); i++) {
         stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
 
         if (done && s->lineno > prev_line)
@@ -99,18 +107,13 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
                     return 0;
                 ff->ff_lineno = s->lineno;
             }
-            else
+            else {
                 done = 1;
+            }
         }
-        else if (s->kind == Expr_kind && !found_docstring) {
-            expr_ty e = s->v.Expr.value;
-            if (e->kind != Str_kind)
-                done = 1;
-            else
-                found_docstring = 1;
-        }
-        else
+        else {
             done = 1;
+        }
     }
     return 1;
 }