Lazy imports grammar / AST changes

This commit is contained in:
Dino Viehland 2025-09-16 15:10:28 -07:00
parent fb114cf497
commit 1c691ea756
25 changed files with 1016 additions and 338 deletions

113
Python/Python-ast.c generated
View file

@ -222,6 +222,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
Py_CLEAR(state->id);
Py_CLEAR(state->ifs);
Py_CLEAR(state->is_async);
Py_CLEAR(state->is_lazy);
Py_CLEAR(state->items);
Py_CLEAR(state->iter);
Py_CLEAR(state->key);
@ -327,6 +328,7 @@ static int init_identifiers(struct ast_state *state)
if ((state->id = PyUnicode_InternFromString("id")) == NULL) return -1;
if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return -1;
if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return -1;
if ((state->is_lazy = PyUnicode_InternFromString("is_lazy")) == NULL) return -1;
if ((state->items = PyUnicode_InternFromString("items")) == NULL) return -1;
if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return -1;
if ((state->key = PyUnicode_InternFromString("key")) == NULL) return -1;
@ -527,11 +529,13 @@ static const char * const Assert_fields[]={
};
static const char * const Import_fields[]={
"names",
"is_lazy",
};
static const char * const ImportFrom_fields[]={
"module",
"names",
"level",
"is_lazy",
};
static const char * const Global_fields[]={
"names",
@ -2254,6 +2258,21 @@ add_ast_annotations(struct ast_state *state)
return 0;
}
}
{
PyObject *type = (PyObject *)&PyLong_Type;
type = _Py_union_type_or(type, Py_None);
cond = type != NULL;
if (!cond) {
Py_DECREF(Import_annotations);
return 0;
}
cond = PyDict_SetItemString(Import_annotations, "is_lazy", type) == 0;
Py_DECREF(type);
if (!cond) {
Py_DECREF(Import_annotations);
return 0;
}
}
cond = PyObject_SetAttrString(state->Import_type, "_field_types",
Import_annotations) == 0;
if (!cond) {
@ -2315,6 +2334,22 @@ add_ast_annotations(struct ast_state *state)
return 0;
}
}
{
PyObject *type = (PyObject *)&PyLong_Type;
type = _Py_union_type_or(type, Py_None);
cond = type != NULL;
if (!cond) {
Py_DECREF(ImportFrom_annotations);
return 0;
}
cond = PyDict_SetItemString(ImportFrom_annotations, "is_lazy", type) ==
0;
Py_DECREF(type);
if (!cond) {
Py_DECREF(ImportFrom_annotations);
return 0;
}
}
cond = PyObject_SetAttrString(state->ImportFrom_type, "_field_types",
ImportFrom_annotations) == 0;
if (!cond) {
@ -6218,8 +6253,8 @@ init_types(void *arg)
" | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n"
" | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n"
" | Assert(expr test, expr? msg)\n"
" | Import(alias* names)\n"
" | ImportFrom(identifier? module, alias* names, int? level)\n"
" | Import(alias* names, int? is_lazy)\n"
" | ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)\n"
" | Global(identifier* names)\n"
" | Nonlocal(identifier* names)\n"
" | Expr(expr value)\n"
@ -6348,17 +6383,21 @@ init_types(void *arg)
if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1)
return -1;
state->Import_type = make_type(state, "Import", state->stmt_type,
Import_fields, 1,
"Import(alias* names)");
Import_fields, 2,
"Import(alias* names, int? is_lazy)");
if (!state->Import_type) return -1;
if (PyObject_SetAttr(state->Import_type, state->is_lazy, Py_None) == -1)
return -1;
state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type,
ImportFrom_fields, 3,
"ImportFrom(identifier? module, alias* names, int? level)");
ImportFrom_fields, 4,
"ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)");
if (!state->ImportFrom_type) return -1;
if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1)
return -1;
if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1)
return -1;
if (PyObject_SetAttr(state->ImportFrom_type, state->is_lazy, Py_None) == -1)
return -1;
state->Global_type = make_type(state, "Global", state->stmt_type,
Global_fields, 1,
"Global(identifier* names)");
@ -7598,8 +7637,8 @@ _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int
}
stmt_ty
_PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
end_lineno, int end_col_offset, PyArena *arena)
_PyAST_Import(asdl_alias_seq * names, int is_lazy, int lineno, int col_offset,
int end_lineno, int end_col_offset, PyArena *arena)
{
stmt_ty p;
p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
@ -7607,6 +7646,7 @@ _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
return NULL;
p->kind = Import_kind;
p->v.Import.names = names;
p->v.Import.is_lazy = is_lazy;
p->lineno = lineno;
p->col_offset = col_offset;
p->end_lineno = end_lineno;
@ -7616,8 +7656,8 @@ _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
stmt_ty
_PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int
lineno, int col_offset, int end_lineno, int end_col_offset,
PyArena *arena)
is_lazy, int lineno, int col_offset, int end_lineno, int
end_col_offset, PyArena *arena)
{
stmt_ty p;
p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
@ -7627,6 +7667,7 @@ _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int
p->v.ImportFrom.module = module;
p->v.ImportFrom.names = names;
p->v.ImportFrom.level = level;
p->v.ImportFrom.is_lazy = is_lazy;
p->lineno = lineno;
p->col_offset = col_offset;
p->end_lineno = end_lineno;
@ -9465,6 +9506,11 @@ ast2obj_stmt(struct ast_state *state, void* _o)
if (PyObject_SetAttr(result, state->names, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_int(state, o->v.Import.is_lazy);
if (!value) goto failed;
if (PyObject_SetAttr(result, state->is_lazy, value) == -1)
goto failed;
Py_DECREF(value);
break;
case ImportFrom_kind:
tp = (PyTypeObject *)state->ImportFrom_type;
@ -9486,6 +9532,11 @@ ast2obj_stmt(struct ast_state *state, void* _o)
if (PyObject_SetAttr(result, state->level, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_int(state, o->v.ImportFrom.is_lazy);
if (!value) goto failed;
if (PyObject_SetAttr(result, state->is_lazy, value) == -1)
goto failed;
Py_DECREF(value);
break;
case Global_kind:
tp = (PyTypeObject *)state->Global_type;
@ -13481,6 +13532,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
}
if (isinstance) {
asdl_alias_seq* names;
int is_lazy;
if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) {
return -1;
@ -13520,7 +13572,24 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
}
Py_CLEAR(tmp);
}
*out = _PyAST_Import(names, lineno, col_offset, end_lineno,
if (PyObject_GetOptionalAttr(obj, state->is_lazy, &tmp) < 0) {
return -1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
is_lazy = 0;
}
else {
int res;
if (_Py_EnterRecursiveCall(" while traversing 'Import' node")) {
goto failed;
}
res = obj2ast_int(state, tmp, &is_lazy, arena);
_Py_LeaveRecursiveCall();
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = _PyAST_Import(names, is_lazy, lineno, col_offset, end_lineno,
end_col_offset, arena);
if (*out == NULL) goto failed;
return 0;
@ -13534,6 +13603,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
identifier module;
asdl_alias_seq* names;
int level;
int is_lazy;
if (PyObject_GetOptionalAttr(obj, state->module, &tmp) < 0) {
return -1;
@ -13607,8 +13677,25 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = _PyAST_ImportFrom(module, names, level, lineno, col_offset,
end_lineno, end_col_offset, arena);
if (PyObject_GetOptionalAttr(obj, state->is_lazy, &tmp) < 0) {
return -1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
is_lazy = 0;
}
else {
int res;
if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
goto failed;
}
res = obj2ast_int(state, tmp, &is_lazy, arena);
_Py_LeaveRecursiveCall();
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = _PyAST_ImportFrom(module, names, level, is_lazy, lineno,
col_offset, end_lineno, end_col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}