diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 16 | ||||
-rw-r--r-- | Python/compile.c | 4 | ||||
-rw-r--r-- | Python/symtable.c | 11 |
3 files changed, 20 insertions, 11 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 2d4b16a..368ad69 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2052,6 +2052,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) break; TARGET(LOAD_NAME) + TARGET(LOAD_NAME_LOCAL_ONLY) w = GETITEM(names, oparg); if ((v = f->f_locals) == NULL) { PyErr_Format(PyExc_SystemError, @@ -2073,15 +2074,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) } } if (x == NULL) { - x = PyDict_GetItem(f->f_globals, w); + if (opcode != LOAD_NAME_LOCAL_ONLY) { + x = PyDict_GetItem(f->f_globals, w); + if (x == NULL) + x = PyDict_GetItem(f->f_builtins, w); + } if (x == NULL) { - x = PyDict_GetItem(f->f_builtins, w); - if (x == NULL) { - format_exc_check_arg( - PyExc_NameError, - NAME_ERROR_MSG, w); - break; - } + format_exc_check_arg(PyExc_NameError, NAME_ERROR_MSG, w); + break; } Py_INCREF(x); } diff --git a/Python/compile.c b/Python/compile.c index aae0339..83c9e02 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -787,6 +787,7 @@ opcode_stack_effect(int opcode, int oparg) case LOAD_CONST: return 1; case LOAD_NAME: + case LOAD_NAME_LOCAL_ONLY: return 1; case BUILD_TUPLE: case BUILD_LIST: @@ -2481,6 +2482,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) optype = OP_DEREF; break; case LOCAL: + case LOCAL_ONLY: if (c->u->u_ste->ste_type == FunctionBlock) optype = OP_FAST; break; @@ -2556,7 +2558,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) break; case OP_NAME: switch (ctx) { - case Load: op = LOAD_NAME; break; + case Load: op = (scope == LOCAL_ONLY) ? LOAD_NAME_LOCAL_ONLY : LOAD_NAME; break; case Store: op = STORE_NAME; break; case Del: op = DELETE_NAME; break; case AugLoad: diff --git a/Python/symtable.c b/Python/symtable.c index 55c9f47..37bdf2a 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -432,7 +432,14 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, return PySet_Add(free, name) >= 0; } if (flags & DEF_BOUND) { - SET_SCOPE(scopes, name, LOCAL); + if (ste->ste_type == ClassBlock && + !(flags & DEF_PARAM) && + bound && PySet_Contains(bound, name)) { + SET_SCOPE(scopes, name, LOCAL_ONLY); + } + else { + SET_SCOPE(scopes, name, LOCAL); + } if (PySet_Add(local, name) < 0) return 0; if (PySet_Discard(global, name) < 0) @@ -489,7 +496,7 @@ analyze_cells(PyObject *scopes, PyObject *free, const char *restricted) long scope; assert(PyLong_Check(v)); scope = PyLong_AS_LONG(v); - if (scope != LOCAL) + if (scope != LOCAL && scope != LOCAL_ONLY) continue; if (!PySet_Contains(free, name)) continue; |