Skip to content

Commit 1ac2732

Browse files
authored
gh-121272: move __future__ import validation from compiler to symtable (#121273)
1 parent 6343486 commit 1ac2732

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

Python/compile.c

-16
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,6 @@ typedef struct _PyCfgBuilder cfg_builder;
7777
#define LOCATION(LNO, END_LNO, COL, END_COL) \
7878
((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
7979

80-
/* Return true if loc1 starts after loc2 ends. */
81-
static inline bool
82-
location_is_after(location loc1, location loc2) {
83-
return (loc1.lineno > loc2.end_lineno) ||
84-
((loc1.lineno == loc2.end_lineno) &&
85-
(loc1.col_offset > loc2.end_col_offset));
86-
}
87-
8880
#define LOC(x) SRC_LOCATION_FROM_AST(x)
8981

9082
typedef _PyJumpTargetLabel jump_target_label;
@@ -3847,14 +3839,6 @@ compiler_from_import(struct compiler *c, stmt_ty s)
38473839
PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
38483840
}
38493841

3850-
if (location_is_after(LOC(s), c->c_future.ff_location) &&
3851-
s->v.ImportFrom.module && s->v.ImportFrom.level == 0 &&
3852-
_PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__"))
3853-
{
3854-
Py_DECREF(names);
3855-
return compiler_error(c, LOC(s), "from __future__ imports must occur "
3856-
"at the beginning of the file");
3857-
}
38583842
ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
38593843

38603844
if (s->v.ImportFrom.module) {

Python/symtable.c

+24
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,27 @@ has_kwonlydefaults(asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
16601660
return 0;
16611661
}
16621662

1663+
static int
1664+
check_import_from(struct symtable *st, stmt_ty s)
1665+
{
1666+
assert(s->kind == ImportFrom_kind);
1667+
_Py_SourceLocation fut = st->st_future->ff_location;
1668+
if (s->v.ImportFrom.module && s->v.ImportFrom.level == 0 &&
1669+
_PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__") &&
1670+
((s->lineno > fut.lineno) ||
1671+
((s->lineno == fut.end_lineno) && (s->col_offset > fut.end_col_offset))))
1672+
{
1673+
PyErr_SetString(PyExc_SyntaxError,
1674+
"from __future__ imports must occur "
1675+
"at the beginning of the file");
1676+
PyErr_RangedSyntaxLocationObject(st->st_filename,
1677+
s->lineno, s->col_offset + 1,
1678+
s->end_lineno, s->end_col_offset + 1);
1679+
return 0;
1680+
}
1681+
return 1;
1682+
}
1683+
16631684
static int
16641685
symtable_visit_stmt(struct symtable *st, stmt_ty s)
16651686
{
@@ -1914,6 +1935,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
19141935
break;
19151936
case ImportFrom_kind:
19161937
VISIT_SEQ(st, alias, s->v.ImportFrom.names);
1938+
if (!check_import_from(st, s)) {
1939+
VISIT_QUIT(st, 0);
1940+
}
19171941
break;
19181942
case Global_kind: {
19191943
Py_ssize_t i;

0 commit comments

Comments
 (0)