diff options
Diffstat (limited to 'Python/future.c')
-rw-r--r-- | Python/future.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/Python/future.c b/Python/future.c index d465608..2a45d2e 100644 --- a/Python/future.c +++ b/Python/future.c @@ -2,8 +2,6 @@ #include "pycore_ast.h" // _PyAST_GetDocString() #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" -#define ERR_LATE_FUTURE \ -"from __future__ imports must occur at the beginning of the file" static int future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) @@ -56,59 +54,42 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) static int future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) { - 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; + } - if (asdl_seq_LEN(mod->v.Module.body) == 0) + Py_ssize_t n = asdl_seq_LEN(mod->v.Module.body); + if (n == 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 - joined by semi-colons, where the first import is a future - statement but some subsequent import has the future form - but is preceded by a regular import. - */ - - i = 0; - if (_PyAST_GetDocString(mod->v.Module.body) != NULL) + Py_ssize_t i = 0; + if (_PyAST_GetDocString(mod->v.Module.body) != NULL) { i++; + } - for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { + for (; i < n; i++) { stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); - if (done && s->lineno > prev_line) - return 1; - prev_line = s->lineno; - - /* The tests below will return from this function unless it is - still possible to find a future statement. The only things - that can precede a future statement are another future - statement and a doc string. - */ + /* The only things that can precede a future statement + * are another future statement and a doc string. + */ if (s->kind == ImportFrom_kind) { identifier modname = s->v.ImportFrom.module; if (modname && _PyUnicode_EqualToASCIIString(modname, "__future__")) { - if (done) { - PyErr_SetString(PyExc_SyntaxError, - ERR_LATE_FUTURE); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); + if (!future_check_features(ff, s, filename)) { return 0; } - if (!future_check_features(ff, s, filename)) - return 0; - ff->ff_lineno = s->lineno; + ff->ff_location = SRC_LOCATION_FROM_AST(s); } else { - done = 1; + return 1; } } else { - done = 1; + return 1; } } return 1; @@ -126,7 +107,7 @@ _PyFuture_FromAST(mod_ty mod, PyObject *filename) return NULL; } ff->ff_features = 0; - ff->ff_lineno = -1; + ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1}; if (!future_parse(ff, mod, filename)) { PyObject_Free(ff); |