mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
reject non-docs strings between future imports (closes #17434)
This commit is contained in:
parent
694bafa04e
commit
2d6acd2ac2
4 changed files with 28 additions and 11 deletions
3
Lib/test/badsyntax_future10.py
Normal file
3
Lib/test/badsyntax_future10.py
Normal file
|
@ -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:
|
else:
|
||||||
self.fail("expected exception didn't occur")
|
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):
|
def test_parserhack(self):
|
||||||
# test that the parser.c::future_hack function works as expected
|
# test that the parser.c::future_hack function works as expected
|
||||||
# Note: although this test must pass, it's not testing the original
|
# 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
|
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
|
- Issue #17117: Import and @importlib.util.set_loader now set __loader__ when
|
||||||
it has a value of None or the attribute doesn't exist.
|
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
|
static int
|
||||||
future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
|
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))
|
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (asdl_seq_LEN(mod->v.Module.body) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* A subsequent pass will detect future imports that don't
|
/* A subsequent pass will detect future imports that don't
|
||||||
appear at the beginning of the file. There's one case,
|
appear at the beginning of the file. There's one case,
|
||||||
however, that is easier to handle here: A series of imports
|
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.
|
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);
|
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||||
|
|
||||||
if (done && s->lineno > prev_line)
|
if (done && s->lineno > prev_line)
|
||||||
|
@ -99,18 +107,13 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
|
||||||
return 0;
|
return 0;
|
||||||
ff->ff_lineno = s->lineno;
|
ff->ff_lineno = s->lineno;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
done = 1;
|
done = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (s->kind == Expr_kind && !found_docstring) {
|
else {
|
||||||
expr_ty e = s->v.Expr.value;
|
|
||||||
if (e->kind != Str_kind)
|
|
||||||
done = 1;
|
|
||||||
else
|
|
||||||
found_docstring = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
done = 1;
|
done = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue