Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-121404: compiler_annassign --> codegen_annassign #123245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 100 additions & 63 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static PySTEntryObject *compiler_symtable_entry(struct compiler *c);
#define OPTIMIZATION_LEVEL(C) compiler_optimization_level(C)
#define IS_INTERACTIVE(C) compiler_is_interactive(C)
#define IS_NESTED_SCOPE(C) compiler_is_nested_scope(C)
#define SCOPE_TYPE(C) compiler_scope_type(C)

typedef _Py_SourceLocation location;
typedef struct _PyCfgBuilder cfg_builder;
Expand All @@ -104,6 +105,7 @@ static PyObject *compiler_maybe_mangle(struct compiler *c, PyObject *name);
static int compiler_optimization_level(struct compiler *c);
static int compiler_is_interactive(struct compiler *c);
static int compiler_is_nested_scope(struct compiler *c);
static int compiler_scope_type(struct compiler *c);

#define LOCATION(LNO, END_LNO, COL, END_COL) \
((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
Expand Down Expand Up @@ -314,7 +316,7 @@ static int compiler_visit_stmt(struct compiler *, stmt_ty);
static int compiler_visit_keyword(struct compiler *, keyword_ty);
static int compiler_visit_expr(struct compiler *, expr_ty);
static int codegen_augassign(struct compiler *, stmt_ty);
static int compiler_annassign(struct compiler *, stmt_ty);
static int codegen_annassign(struct compiler *, stmt_ty);
static int codegen_subscript(struct compiler *, expr_ty);
static int codegen_slice(struct compiler *, expr_ty);

Expand Down Expand Up @@ -1481,7 +1483,7 @@ codegen_setup_annotations_scope(struct compiler *c, location loc,
ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
ADDOP_I(c, loc, RAISE_VARARGS, 1);
USE_LABEL(c, body);
return 0;
return SUCCESS;
}

static int
Expand All @@ -1501,11 +1503,69 @@ codegen_leave_annotations_scope(struct compiler *c, location loc,
return SUCCESS;
}

static PyObject *
compiler_deferred_annotations(struct compiler *c)
{
return c->u->u_deferred_annotations;
}

static int
codegen_process_deferred_annotations(struct compiler *c, location loc)
{
PyObject *deferred_anno = compiler_deferred_annotations(c);
if (deferred_anno == NULL) {
return SUCCESS;
}
Py_INCREF(deferred_anno);

// It's possible that ste_annotations_block is set but
// u_deferred_annotations is not, because the former is still
// set if there are only non-simple annotations (i.e., annotations
// for attributes, subscripts, or parenthesized names). However, the
// reverse should not be possible.
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
assert(ste->ste_annotation_block != NULL);
void *key = (void *)((uintptr_t)ste->ste_id + 1);
if (codegen_setup_annotations_scope(c, loc, key,
ste->ste_annotation_block->ste_name) < 0) {
Py_DECREF(deferred_anno);
return ERROR;
}
Py_ssize_t annotations_len = PyList_Size(deferred_anno);
for (Py_ssize_t i = 0; i < annotations_len; i++) {
PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
if (st == NULL) {
compiler_exit_scope(c);
Py_DECREF(deferred_anno);
return ERROR;
}
PyObject *mangled = compiler_mangle(c, st->v.AnnAssign.target->v.Name.id);
if (!mangled) {
compiler_exit_scope(c);
Py_DECREF(deferred_anno);
return ERROR;
}
ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
VISIT(c, expr, st->v.AnnAssign.annotation);
}
Py_DECREF(deferred_anno);

RETURN_IF_ERROR(
codegen_leave_annotations_scope(c, loc, annotations_len)
);
RETURN_IF_ERROR(
compiler_nameop(c, loc, &_Py_ID(__annotate__), Store)
);

return SUCCESS;
}

/* Compile a sequence of statements, checking for a docstring
and for annotations. */

static int
compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
codegen_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
{
/* If from __future__ import annotations is active,
* every annotated class and module should have __annotations__.
Expand Down Expand Up @@ -1542,44 +1602,8 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
// If there are annotations and the future import is not on, we
// collect the annotations in a separate pass and generate an
// __annotate__ function. See PEP 649.
if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) &&
c->u->u_deferred_annotations != NULL) {

// It's possible that ste_annotations_block is set but
// u_deferred_annotations is not, because the former is still
// set if there are only non-simple annotations (i.e., annotations
// for attributes, subscripts, or parenthesized names). However, the
// reverse should not be possible.
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
assert(ste->ste_annotation_block != NULL);
PyObject *deferred_anno = Py_NewRef(c->u->u_deferred_annotations);
void *key = (void *)((uintptr_t)ste->ste_id + 1);
if (codegen_setup_annotations_scope(c, loc, key,
ste->ste_annotation_block->ste_name) == -1) {
Py_DECREF(deferred_anno);
return ERROR;
}
Py_ssize_t annotations_len = PyList_Size(deferred_anno);
for (Py_ssize_t i = 0; i < annotations_len; i++) {
PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
if (st == NULL) {
compiler_exit_scope(c);
Py_DECREF(deferred_anno);
return ERROR;
}
PyObject *mangled = compiler_mangle(c, st->v.AnnAssign.target->v.Name.id);
ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
VISIT(c, expr, st->v.AnnAssign.annotation);
}
Py_DECREF(deferred_anno);

RETURN_IF_ERROR(
codegen_leave_annotations_scope(c, loc, annotations_len)
);
RETURN_IF_ERROR(
compiler_nameop(c, loc, &_Py_ID(__annotate__), Store)
);
if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
}
return SUCCESS;
}
Expand All @@ -1606,13 +1630,13 @@ compiler_codegen(struct compiler *c, mod_ty mod)
switch (mod->kind) {
case Module_kind: {
asdl_stmt_seq *stmts = mod->v.Module.body;
RETURN_IF_ERROR(compiler_body(c, start_location(stmts), stmts));
RETURN_IF_ERROR(codegen_body(c, start_location(stmts), stmts));
break;
}
case Interactive_kind: {
c->c_interactive = 1;
asdl_stmt_seq *stmts = mod->v.Interactive.body;
RETURN_IF_ERROR(compiler_body(c, start_location(stmts), stmts));
RETURN_IF_ERROR(codegen_body(c, start_location(stmts), stmts));
break;
}
case Expression_kind: {
Expand Down Expand Up @@ -2385,7 +2409,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
}
/* compile the body proper */
RETURN_IF_ERROR_IN_SCOPE(c, compiler_body(c, loc, s->v.ClassDef.body));
RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body));
assert(c->u->u_static_attributes);
PyObject *static_attributes = PySequence_Tuple(c->u->u_static_attributes);
if (static_attributes == NULL) {
Expand Down Expand Up @@ -3847,7 +3871,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
case AugAssign_kind:
return codegen_augassign(c, s);
case AnnAssign_kind:
return compiler_annassign(c, s);
return codegen_annassign(c, s);
case For_kind:
return codegen_for(c, s);
case While_kind:
Expand Down Expand Up @@ -6287,7 +6311,28 @@ codegen_check_ann_subscr(struct compiler *c, expr_ty e)
}

static int
compiler_annassign(struct compiler *c, stmt_ty s)
compiler_add_deferred_annotation(struct compiler *c, stmt_ty s)
{
if (c->u->u_deferred_annotations == NULL) {
c->u->u_deferred_annotations = PyList_New(0);
if (c->u->u_deferred_annotations == NULL) {
return ERROR;
}
}
PyObject *ptr = PyLong_FromVoidPtr((void *)s);
if (ptr == NULL) {
return ERROR;
}
if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
Py_DECREF(ptr);
return ERROR;
}
Py_DECREF(ptr);
return SUCCESS;
}

static int
codegen_annassign(struct compiler *c, stmt_ty s)
{
location loc = LOC(s);
expr_ty targ = s->v.AnnAssign.target;
Expand All @@ -6305,8 +6350,8 @@ compiler_annassign(struct compiler *c, stmt_ty s)
case Name_kind:
/* If we have a simple name in a module or class, store annotation. */
if (s->v.AnnAssign.simple &&
(c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
(SCOPE_TYPE(c) == COMPILER_SCOPE_MODULE ||
SCOPE_TYPE(c) == COMPILER_SCOPE_CLASS)) {
if (future_annotations) {
VISIT(c, annexpr, s->v.AnnAssign.annotation);
ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
Expand All @@ -6315,21 +6360,7 @@ compiler_annassign(struct compiler *c, stmt_ty s)
ADDOP(c, loc, STORE_SUBSCR);
}
else {
if (c->u->u_deferred_annotations == NULL) {
c->u->u_deferred_annotations = PyList_New(0);
if (c->u->u_deferred_annotations == NULL) {
return ERROR;
}
}
PyObject *ptr = PyLong_FromVoidPtr((void *)s);
if (ptr == NULL) {
return ERROR;
}
if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
Py_DECREF(ptr);
return ERROR;
}
Py_DECREF(ptr);
RETURN_IF_ERROR(compiler_add_deferred_annotation(c, s));
}
}
break;
Expand Down Expand Up @@ -7399,6 +7430,12 @@ compiler_is_nested_scope(struct compiler *c)
return PyList_GET_SIZE(c->c_stack) > 0;
}

static int
compiler_scope_type(struct compiler *c)
{
return c->u->u_scope_type;
}

static int
compute_code_flags(struct compiler *c)
{
Expand Down
Loading