reject non-docs strings between future imports (closes #17434)
This commit is contained in:
parent
694bafa04e
commit
2d6acd2ac2
|
@ -0,0 +1,3 @@
|
|||
from __future__ import absolute_import
|
||||
"spam, bar, blah"
|
||||
from __future__ import print_function
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue