[3.13] gh-118934: Make PyEval_GetLocals return borrowed reference (GH-119769) (#121869)

gh-118934: Make PyEval_GetLocals return borrowed reference (GH-119769)
(cherry picked from commit e65cb4c6f0)

Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-07-18 17:38:28 +02:00 committed by GitHub
parent 98e7d44712
commit 233ed46e6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 42 additions and 2 deletions

View file

@ -2466,6 +2466,7 @@ _PyEval_GetBuiltinId(_Py_Identifier *name)
PyObject *
PyEval_GetLocals(void)
{
// We need to return a borrowed reference here, so some tricks are needed
PyThreadState *tstate = _PyThreadState_GET();
_PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate);
if (current_frame == NULL) {
@ -2473,7 +2474,37 @@ PyEval_GetLocals(void)
return NULL;
}
PyObject *locals = _PyEval_GetFrameLocals();
// Be aware that this returns a new reference
PyObject *locals = _PyFrame_GetLocals(current_frame);
if (locals == NULL) {
return NULL;
}
if (PyFrameLocalsProxy_Check(locals)) {
PyFrameObject *f = _PyFrame_GetFrameObject(current_frame);
PyObject *ret = f->f_locals_cache;
if (ret == NULL) {
PyObject *ret = PyDict_New();
if (ret == NULL) {
Py_DECREF(locals);
return NULL;
}
f->f_locals_cache = ret;
}
if (PyDict_Update(ret, locals) < 0) {
// At this point, if the cache dict is broken, it will stay broken, as
// trying to clean it up or replace it will just cause other problems
ret = NULL;
}
Py_DECREF(locals);
return ret;
}
assert(PyMapping_Check(locals));
assert(Py_REFCNT(locals) > 1);
Py_DECREF(locals);
return locals;
}