diff --git a/Python/compile.c b/Python/compile.c index 69de0ec2996e00..d33db69f425361 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -77,14 +77,6 @@ typedef struct _PyCfgBuilder cfg_builder; #define LOCATION(LNO, END_LNO, COL, END_COL) \ ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)}) -/* Return true if loc1 starts after loc2 ends. */ -static inline bool -location_is_after(location loc1, location loc2) { - return (loc1.lineno > loc2.end_lineno) || - ((loc1.lineno == loc2.end_lineno) && - (loc1.col_offset > loc2.end_col_offset)); -} - #define LOC(x) SRC_LOCATION_FROM_AST(x) typedef _PyJumpTargetLabel jump_target_label; @@ -3847,14 +3839,6 @@ compiler_from_import(struct compiler *c, stmt_ty s) PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name)); } - if (location_is_after(LOC(s), c->c_future.ff_location) && - s->v.ImportFrom.module && s->v.ImportFrom.level == 0 && - _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) - { - Py_DECREF(names); - return compiler_error(c, LOC(s), "from __future__ imports must occur " - "at the beginning of the file"); - } ADDOP_LOAD_CONST_NEW(c, LOC(s), names); if (s->v.ImportFrom.module) { diff --git a/Python/symtable.c b/Python/symtable.c index 2e56ea6e830846..61fa5c6fdf923c 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1660,6 +1660,27 @@ has_kwonlydefaults(asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults) return 0; } +static int +check_import_from(struct symtable *st, stmt_ty s) +{ + assert(s->kind == ImportFrom_kind); + _Py_SourceLocation fut = st->st_future->ff_location; + if (s->v.ImportFrom.module && s->v.ImportFrom.level == 0 && + _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__") && + ((s->lineno > fut.lineno) || + ((s->lineno == fut.end_lineno) && (s->col_offset > fut.end_col_offset)))) + { + PyErr_SetString(PyExc_SyntaxError, + "from __future__ imports must occur " + "at the beginning of the file"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + s->lineno, s->col_offset + 1, + s->end_lineno, s->end_col_offset + 1); + return 0; + } + return 1; +} + static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { @@ -1914,6 +1935,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case ImportFrom_kind: VISIT_SEQ(st, alias, s->v.ImportFrom.names); + if (!check_import_from(st, s)) { + VISIT_QUIT(st, 0); + } break; case Global_kind: { Py_ssize_t i;