cpython: 4ef4578db38a (original) (raw)

Mercurial > cpython

changeset 86715:4ef4578db38a

Issue #18408: Add a new PyFrame_FastToLocalsWithError() function to handle exceptions when merging fast locals into f_locals of a frame. PyEval_GetLocals() now raises an exception and return NULL on failure. [#18408]

Victor Stinner victor.stinner@gmail.com
date Tue, 29 Oct 2013 01:19:37 +0100
parents 6b86eb127030
children e1d51c42e5a1
files Include/frameobject.h Misc/NEWS Objects/frameobject.c Objects/object.c Python/bltinmodule.c Python/ceval.c Python/sysmodule.c
diffstat 7 files changed, 87 insertions(+), 46 deletions(-)[+] [-] Include/frameobject.h 2 Misc/NEWS 4 Objects/frameobject.c 77 Objects/object.c 7 Python/bltinmodule.c 17 Python/ceval.c 19 Python/sysmodule.c 7

line wrap: on

line diff

--- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -78,6 +78,8 @@ PyAPI_FUNC(PyObject **) PyFrame_ExtendSt /* Conversions between "fast locals" and locals in dictionary */ PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); + +PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); PyAPI_FUNC(int) PyFrame_ClearFreeList(void);

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Projected release date: 2013-11-24 Core and Builtins ----------------- +- Issue #18408: Add a new PyFrame_FastToLocalsWithError() function to handle

--- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -21,7 +21,8 @@ static PyMemberDef frame_memberlist[] = static PyObject * frame_getlocals(PyFrameObject *f, void *closure) {

-static void +static int map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, int deref) { @@ -794,14 +792,19 @@ map_to_dict(PyObject *map, Py_ssize_t nm value = PyCell_GET(value); } if (value == NULL) {

} /* Copy values from the "locals" dict into the fast locals. @@ -858,42 +861,49 @@ dict_to_map(PyObject *map, Py_ssize_t nm } } -void -PyFrame_FastToLocals(PyFrameObject *f) +int +PyFrame_FastToLocalsWithError(PyFrameObject f) { / Merge fast locals into f->f_locals */ PyObject *locals, *map; PyObject **fast;

+

+ /* If the namespace is unoptimized, then one of the following cases applies: 1. It does not contain free variables, because it @@ -903,11 +913,24 @@ PyFrame_FastToLocals(PyFrameObject *f) into the locals dict used by the class. */ if (co->co_flags & CO_OPTIMIZED) {

+} + +void +PyFrame_FastToLocals(PyFrameObject *f) +{

+

+

} void

--- a/Objects/object.c +++ b/Objects/object.c @@ -1407,12 +1407,11 @@ static PyObject * _dir_locals(void) { PyObject *names;

names = PyMapping_Keys(locals); if (!names)

--- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -755,8 +755,11 @@ builtin_eval(PyObject *self, PyObject *a } if (globals == Py_None) { globals = PyEval_GetGlobals();

@@ -820,6 +823,8 @@ builtin_exec(PyObject *self, PyObject *a globals = PyEval_GetGlobals(); if (locals == Py_None) { locals = PyEval_GetLocals();

@@ -1926,13 +1931,9 @@ builtin_vars(PyObject *self, PyObject *a return NULL; if (v == NULL) { d = PyEval_GetLocals();

--- a/Python/ceval.c +++ b/Python/ceval.c @@ -2472,7 +2472,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int TARGET(IMPORT_STAR) { PyObject *from = POP(), *locals; int err;

+ locals = f->f_locals; if (locals == NULL) { PyErr_SetString(PyExc_SystemError, @@ -4005,9 +4007,15 @@ PyObject * PyEval_GetLocals(void) { PyFrameObject *current_frame = PyEval_GetFrame();

+

+

@@ -4017,8 +4025,9 @@ PyEval_GetGlobals(void) PyFrameObject *current_frame = PyEval_GetFrame(); if (current_frame == NULL) return NULL;

+

} PyFrameObject *

--- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -332,12 +332,16 @@ static PyObject * call_trampoline(PyThreadState tstate, PyObject callback, PyFrameObject *frame, int what, PyObject *arg) {

+ Py_INCREF(frame); whatstr = whatstrings[what]; Py_INCREF(whatstr); @@ -349,7 +353,6 @@ call_trampoline(PyThreadState tstate, P PyTuple_SET_ITEM(args, 2, arg); / call the Python-level function */