bpo-40429: PyFrame_GetCode() now returns a strong reference (GH-19773)
This commit is contained in:
parent
5e8c691594
commit
8852ad4208
|
@ -33,10 +33,11 @@ Reflection
|
||||||
|
|
||||||
.. c:function:: int PyFrame_GetCode(PyFrameObject *frame)
|
.. c:function:: int PyFrame_GetCode(PyFrameObject *frame)
|
||||||
|
|
||||||
Return a borrowed reference to the *frame* code.
|
Get the *frame* code.
|
||||||
The frame code cannot be ``NULL``.
|
|
||||||
|
|
||||||
*frame* must not be ``NULL``.
|
Return a strong reference.
|
||||||
|
|
||||||
|
*frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``.
|
||||||
|
|
||||||
.. versionadded:: 3.9
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
|
@ -537,8 +537,7 @@ Optimizations
|
||||||
Build and C API Changes
|
Build and C API Changes
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
* New :c:func:`PyFrame_GetCode` function: return a borrowed reference to the
|
* New :c:func:`PyFrame_GetCode` function: get a frame code.
|
||||||
frame code.
|
|
||||||
(Contributed by Victor Stinner in :issue:`40421`.)
|
(Contributed by Victor Stinner in :issue:`40421`.)
|
||||||
|
|
||||||
* Add :c:func:`PyFrame_GetLineNumber` to the limited C API.
|
* Add :c:func:`PyFrame_GetLineNumber` to the limited C API.
|
||||||
|
|
|
@ -390,14 +390,19 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what,
|
||||||
{
|
{
|
||||||
PyCodeObject *code = PyFrame_GetCode(frame);
|
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||||
ptrace_enter_call(self, (void *)code, (PyObject *)code);
|
ptrace_enter_call(self, (void *)code, (PyObject *)code);
|
||||||
|
Py_DECREF(code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the 'frame' of a called function is about to finish
|
/* the 'frame' of a called function is about to finish
|
||||||
(either normally or with an exception) */
|
(either normally or with an exception) */
|
||||||
case PyTrace_RETURN:
|
case PyTrace_RETURN:
|
||||||
ptrace_leave_call(self, (void *)PyFrame_GetCode(frame));
|
{
|
||||||
|
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||||
|
ptrace_leave_call(self, (void *)code);
|
||||||
|
Py_DECREF(code);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* case PyTrace_EXCEPTION:
|
/* case PyTrace_EXCEPTION:
|
||||||
If the exception results in the function exiting, a
|
If the exception results in the function exiting, a
|
||||||
|
|
|
@ -335,26 +335,24 @@ hashtable_compare_traceback(_Py_hashtable_t *ht, const void *pkey,
|
||||||
static void
|
static void
|
||||||
tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
|
tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
|
||||||
{
|
{
|
||||||
PyCodeObject *code;
|
|
||||||
PyObject *filename;
|
|
||||||
_Py_hashtable_entry_t *entry;
|
|
||||||
int lineno;
|
|
||||||
|
|
||||||
frame->filename = unknown_filename;
|
frame->filename = unknown_filename;
|
||||||
lineno = PyFrame_GetLineNumber(pyframe);
|
int lineno = PyFrame_GetLineNumber(pyframe);
|
||||||
if (lineno < 0)
|
if (lineno < 0) {
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
|
}
|
||||||
frame->lineno = (unsigned int)lineno;
|
frame->lineno = (unsigned int)lineno;
|
||||||
|
|
||||||
code = PyFrame_GetCode(pyframe);
|
PyCodeObject *code = PyFrame_GetCode(pyframe);
|
||||||
if (code->co_filename == NULL) {
|
PyObject *filename = code->co_filename;
|
||||||
|
Py_DECREF(code);
|
||||||
|
|
||||||
|
if (filename == NULL) {
|
||||||
#ifdef TRACE_DEBUG
|
#ifdef TRACE_DEBUG
|
||||||
tracemalloc_error("failed to get the filename of the code object");
|
tracemalloc_error("failed to get the filename of the code object");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = code->co_filename;
|
|
||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -375,6 +373,7 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intern the filename */
|
/* intern the filename */
|
||||||
|
_Py_hashtable_entry_t *entry;
|
||||||
entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename);
|
entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename);
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
_Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename);
|
_Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename);
|
||||||
|
|
|
@ -1237,5 +1237,6 @@ PyFrame_GetCode(PyFrameObject *frame)
|
||||||
assert(frame != NULL);
|
assert(frame != NULL);
|
||||||
PyCodeObject *code = frame->f_code;
|
PyCodeObject *code = frame->f_code;
|
||||||
assert(code != NULL);
|
assert(code != NULL);
|
||||||
|
Py_INCREF(code);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8031,7 +8031,6 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
/* Call super(), without args -- fill in from __class__
|
/* Call super(), without args -- fill in from __class__
|
||||||
and first local variable on the stack. */
|
and first local variable on the stack. */
|
||||||
PyFrameObject *f;
|
PyFrameObject *f;
|
||||||
PyCodeObject *co;
|
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
f = PyThreadState_GetFrame(_PyThreadState_GET());
|
f = PyThreadState_GetFrame(_PyThreadState_GET());
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
|
@ -8039,7 +8038,8 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
"super(): no current frame");
|
"super(): no current frame");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
co = PyFrame_GetCode(f);
|
PyCodeObject *co = PyFrame_GetCode(f);
|
||||||
|
Py_DECREF(co); // use a borrowed reference
|
||||||
if (co->co_argcount == 0) {
|
if (co->co_argcount == 0) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"super(): no arguments");
|
"super(): no arguments");
|
||||||
|
|
|
@ -785,6 +785,8 @@ is_internal_frame(PyFrameObject *frame)
|
||||||
|
|
||||||
PyCodeObject *code = PyFrame_GetCode(frame);
|
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||||
PyObject *filename = code->co_filename;
|
PyObject *filename = code->co_filename;
|
||||||
|
Py_DECREF(code);
|
||||||
|
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -850,7 +852,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
globals = f->f_globals;
|
globals = f->f_globals;
|
||||||
*filename = PyFrame_GetCode(f)->co_filename;
|
PyCodeObject *code = PyFrame_GetCode(f);
|
||||||
|
*filename = code->co_filename;
|
||||||
|
Py_DECREF(code);
|
||||||
Py_INCREF(*filename);
|
Py_INCREF(*filename);
|
||||||
*lineno = PyFrame_GetLineNumber(f);
|
*lineno = PyFrame_GetLineNumber(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1557,6 +1557,7 @@ remove_importlib_frames(PyThreadState *tstate)
|
||||||
else {
|
else {
|
||||||
prev_link = (PyObject **) &traceback->tb_next;
|
prev_link = (PyObject **) &traceback->tb_next;
|
||||||
}
|
}
|
||||||
|
Py_DECREF(code);
|
||||||
tb = next;
|
tb = next;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
|
|
@ -581,6 +581,7 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
|
||||||
err = PyErr_CheckSignals();
|
err = PyErr_CheckSignals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Py_DECREF(code);
|
||||||
tb = tb->tb_next;
|
tb = tb->tb_next;
|
||||||
}
|
}
|
||||||
if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
|
if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
|
||||||
|
@ -752,12 +753,9 @@ _Py_DumpASCII(int fd, PyObject *text)
|
||||||
static void
|
static void
|
||||||
dump_frame(int fd, PyFrameObject *frame)
|
dump_frame(int fd, PyFrameObject *frame)
|
||||||
{
|
{
|
||||||
PyCodeObject *code;
|
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||||
int lineno;
|
|
||||||
|
|
||||||
code = PyFrame_GetCode(frame);
|
|
||||||
PUTS(fd, " File ");
|
PUTS(fd, " File ");
|
||||||
if (code != NULL && code->co_filename != NULL
|
if (code->co_filename != NULL
|
||||||
&& PyUnicode_Check(code->co_filename))
|
&& PyUnicode_Check(code->co_filename))
|
||||||
{
|
{
|
||||||
PUTS(fd, "\"");
|
PUTS(fd, "\"");
|
||||||
|
@ -768,7 +766,7 @@ dump_frame(int fd, PyFrameObject *frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
|
/* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */
|
||||||
lineno = PyCode_Addr2Line(code, frame->f_lasti);
|
int lineno = PyCode_Addr2Line(code, frame->f_lasti);
|
||||||
PUTS(fd, ", line ");
|
PUTS(fd, ", line ");
|
||||||
if (lineno >= 0) {
|
if (lineno >= 0) {
|
||||||
_Py_DumpDecimal(fd, (unsigned long)lineno);
|
_Py_DumpDecimal(fd, (unsigned long)lineno);
|
||||||
|
@ -778,7 +776,7 @@ dump_frame(int fd, PyFrameObject *frame)
|
||||||
}
|
}
|
||||||
PUTS(fd, " in ");
|
PUTS(fd, " in ");
|
||||||
|
|
||||||
if (code != NULL && code->co_name != NULL
|
if (code->co_name != NULL
|
||||||
&& PyUnicode_Check(code->co_name)) {
|
&& PyUnicode_Check(code->co_name)) {
|
||||||
_Py_DumpASCII(fd, code->co_name);
|
_Py_DumpASCII(fd, code->co_name);
|
||||||
}
|
}
|
||||||
|
@ -787,6 +785,7 @@ dump_frame(int fd, PyFrameObject *frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
PUTS(fd, "\n");
|
PUTS(fd, "\n");
|
||||||
|
Py_DECREF(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue