mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Syntax restrictions for lazy imports
This commit is contained in:
parent
07a633f1f4
commit
20b14d9ca4
3 changed files with 175 additions and 0 deletions
|
|
@ -1747,6 +1747,13 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
|
|||
#define LEAVE_CONDITIONAL_BLOCK(ST) \
|
||||
(ST)->st_cur->ste_in_conditional_block = in_conditional_block;
|
||||
|
||||
#define ENTER_TRY_BLOCK(ST) \
|
||||
int in_try_block = (ST)->st_cur->ste_in_try_block; \
|
||||
(ST)->st_cur->ste_in_try_block = 1;
|
||||
|
||||
#define LEAVE_TRY_BLOCK(ST) \
|
||||
(ST)->st_cur->ste_in_try_block = in_try_block;
|
||||
|
||||
#define ENTER_RECURSIVE() \
|
||||
if (Py_EnterRecursiveCall(" during compilation")) { \
|
||||
return 0; \
|
||||
|
|
@ -1808,6 +1815,36 @@ check_import_from(struct symtable *st, stmt_ty s)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
check_lazy_import_context(struct symtable *st, stmt_ty s, const char* import_type)
|
||||
{
|
||||
/* Check if inside try/except block */
|
||||
if (st->st_cur->ste_in_try_block) {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
"lazy %s not allowed inside try/except blocks", import_type);
|
||||
SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if inside function scope */
|
||||
if (st->st_cur->ste_type == FunctionBlock) {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
"lazy %s not allowed inside functions", import_type);
|
||||
SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if inside class scope */
|
||||
if (st->st_cur->ste_type == ClassBlock) {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
"lazy %s not allowed inside classes", import_type);
|
||||
SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
allows_top_level_await(struct symtable *st)
|
||||
{
|
||||
|
|
@ -2076,19 +2113,23 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
|||
break;
|
||||
case Try_kind: {
|
||||
ENTER_CONDITIONAL_BLOCK(st);
|
||||
ENTER_TRY_BLOCK(st);
|
||||
VISIT_SEQ(st, stmt, s->v.Try.body);
|
||||
VISIT_SEQ(st, excepthandler, s->v.Try.handlers);
|
||||
VISIT_SEQ(st, stmt, s->v.Try.orelse);
|
||||
VISIT_SEQ(st, stmt, s->v.Try.finalbody);
|
||||
LEAVE_TRY_BLOCK(st);
|
||||
LEAVE_CONDITIONAL_BLOCK(st);
|
||||
break;
|
||||
}
|
||||
case TryStar_kind: {
|
||||
ENTER_CONDITIONAL_BLOCK(st);
|
||||
ENTER_TRY_BLOCK(st);
|
||||
VISIT_SEQ(st, stmt, s->v.TryStar.body);
|
||||
VISIT_SEQ(st, excepthandler, s->v.TryStar.handlers);
|
||||
VISIT_SEQ(st, stmt, s->v.TryStar.orelse);
|
||||
VISIT_SEQ(st, stmt, s->v.TryStar.finalbody);
|
||||
LEAVE_TRY_BLOCK(st);
|
||||
LEAVE_CONDITIONAL_BLOCK(st);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2098,9 +2139,29 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
|||
VISIT(st, expr, s->v.Assert.msg);
|
||||
break;
|
||||
case Import_kind:
|
||||
if (s->v.Import.is_lazy) {
|
||||
if (!check_lazy_import_context(st, s, "import")) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
VISIT_SEQ(st, alias, s->v.Import.names);
|
||||
break;
|
||||
case ImportFrom_kind:
|
||||
if (s->v.ImportFrom.is_lazy) {
|
||||
if (!check_lazy_import_context(st, s, "from ... import")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for import * */
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(s->v.ImportFrom.names); i++) {
|
||||
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
|
||||
if (alias->name && _PyUnicode_EqualToASCIIString(alias->name, "*")) {
|
||||
PyErr_SetString(PyExc_SyntaxError, "lazy from ... import * is not allowed");
|
||||
SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
VISIT_SEQ(st, alias, s->v.ImportFrom.names);
|
||||
if (!check_import_from(st, s)) {
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue