Skip to content

Commit

Permalink
No deferred evaluation in interactive mode
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed May 24, 2024
1 parent 1c98fe5 commit 5f5cf11
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
1 change: 1 addition & 0 deletions Include/internal/pycore_symtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct symtable {
the symbol table */
int recursion_depth; /* current recursion depth */
int recursion_limit; /* recursion limit */
int st_kind; /* kind of module */
};

typedef struct _symtable_entry {
Expand Down
39 changes: 34 additions & 5 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1653,7 +1653,7 @@ compiler_setup_annotations_scope(struct compiler *c, location loc,

static int
compiler_leave_annotations_scope(struct compiler *c, location loc,
int annotations_len, jump_target_label label)
Py_ssize_t annotations_len, jump_target_label label)
{
ADDOP_I(c, loc, BUILD_MAP, annotations_len);
ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
Expand Down Expand Up @@ -6595,6 +6595,23 @@ check_ann_expr(struct compiler *c, expr_ty e)
return SUCCESS;
}

static int
check_annotation(struct compiler *c, stmt_ty s)
{
/* Annotations of complex targets does not produce anything
under annotations future */
if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
return SUCCESS;
}

/* Annotations are only evaluated in a module or class. */
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
return check_ann_expr(c, s->v.AnnAssign.annotation);
}
return SUCCESS;
}

static int
check_ann_subscr(struct compiler *c, expr_ty e)
{
Expand Down Expand Up @@ -6630,7 +6647,11 @@ compiler_annassign(struct compiler *c, stmt_ty s)
{
location loc = LOC(s);
expr_ty targ = s->v.AnnAssign.target;
PyObject* mangled;
bool is_interactive = (
c->c_st->st_kind == Interactive_kind && c->u->u_scope_type == COMPILER_SCOPE_MODULE
);
bool future_annotations = c->c_future.ff_features & CO_FUTURE_ANNOTATIONS;
PyObject *mangled;

assert(s->kind == AnnAssign_kind);

Expand All @@ -6645,11 +6666,16 @@ compiler_annassign(struct compiler *c, stmt_ty s)
return ERROR;
}
/* If we have a simple name in a module or class, store annotation. */
if ((c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) &&
if ((future_annotations || is_interactive) &&
s->v.AnnAssign.simple &&
(c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
VISIT(c, annexpr, s->v.AnnAssign.annotation);
if (future_annotations) {
VISIT(c, annexpr, s->v.AnnAssign.annotation);
}
else {
VISIT(c, expr, s->v.AnnAssign.annotation);
}
ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
ADDOP_LOAD_CONST_NEW(c, loc, mangled);
Expand Down Expand Up @@ -6678,7 +6704,10 @@ compiler_annassign(struct compiler *c, stmt_ty s)
targ->kind);
return ERROR;
}
/* For non-simple AnnAssign, the annotation is not evaluated. */
/* Annotation is evaluated last. */
if ((future_annotations || is_interactive) && !s->v.AnnAssign.simple && check_annotation(c, s) < 0) {
return ERROR;
}
return SUCCESS;
}

Expand Down
8 changes: 6 additions & 2 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future)
}

st->st_top = st->st_cur;
st->st_kind = mod->kind;
switch (mod->kind) {
case Module_kind:
seq = mod->v.Module.body;
Expand Down Expand Up @@ -2471,13 +2472,16 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation,
struct _symtable_entry *parent_ste, void *key)
{
int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS;
int is_top_level_interactive = (
st->st_kind == Interactive_kind && st->st_cur->ste_type == ModuleBlock
);
if (future_annotations) {
if(!symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock,
key, LOCATION(annotation))) {
VISIT_QUIT(st, 0);
}
}
else {
else if (!is_top_level_interactive) {
if (st->st_cur->ste_annotation_block == NULL) {
PyObject *annotations_name = PyUnicode_FromFormat(
"<annotations of %U>", parent_ste->ste_name);
Expand Down Expand Up @@ -2518,7 +2522,7 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation,
}
}
VISIT(st, expr, annotation);
if (!symtable_exit_block(st)) {
if ((future_annotations || !is_top_level_interactive) && !symtable_exit_block(st)) {
VISIT_QUIT(st, 0);
}
return 1;
Expand Down

0 comments on commit 5f5cf11

Please sign in to comment.