diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/compile.c | 163 |
1 files changed, 100 insertions, 63 deletions
diff --git a/Python/compile.c b/Python/compile.c index 2d69855..7cf33a9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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; @@ -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)}) @@ -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); @@ -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 @@ -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__. @@ -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; } @@ -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: { @@ -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) { @@ -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: @@ -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; @@ -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); @@ -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; @@ -7400,6 +7431,12 @@ compiler_is_nested_scope(struct compiler *c) } static int +compiler_scope_type(struct compiler *c) +{ + return c->u->u_scope_type; +} + +static int compute_code_flags(struct compiler *c) { PySTEntryObject *ste = SYMTABLE_ENTRY(c); |