summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/reflection.rst7
-rw-r--r--Doc/whatsnew/3.9.rst3
-rw-r--r--Modules/_lsprof.c7
-rw-r--r--Modules/_tracemalloc.c19
-rw-r--r--Objects/frameobject.c1
-rw-r--r--Objects/typeobject.c4
-rw-r--r--Python/_warnings.c6
-rw-r--r--Python/import.c1
-rw-r--r--Python/traceback.c13
9 files changed, 35 insertions, 26 deletions
diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst
index 594c1ec..21d9878 100644
--- a/Doc/c-api/reflection.rst
+++ b/Doc/c-api/reflection.rst
@@ -33,10 +33,11 @@ Reflection
.. c:function:: int PyFrame_GetCode(PyFrameObject *frame)
- Return a borrowed reference to the *frame* code.
- The frame code cannot be ``NULL``.
+ Get the *frame* code.
- *frame* must not be ``NULL``.
+ Return a strong reference.
+
+ *frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``.
.. versionadded:: 3.9
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index e3751fa..cb3afd5 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -537,8 +537,7 @@ Optimizations
Build and C API Changes
=======================
-* New :c:func:`PyFrame_GetCode` function: return a borrowed reference to the
- frame code.
+* New :c:func:`PyFrame_GetCode` function: get a frame code.
(Contributed by Victor Stinner in :issue:`40421`.)
* Add :c:func:`PyFrame_GetLineNumber` to the limited C API.
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index 39cf6e1..5e53d83 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -390,14 +390,19 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what,
{
PyCodeObject *code = PyFrame_GetCode(frame);
ptrace_enter_call(self, (void *)code, (PyObject *)code);
+ Py_DECREF(code);
break;
}
/* the 'frame' of a called function is about to finish
(either normally or with an exception) */
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;
+ }
/* case PyTrace_EXCEPTION:
If the exception results in the function exiting, a
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index b2a0003..24628a9 100644
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -335,26 +335,24 @@ hashtable_compare_traceback(_Py_hashtable_t *ht, const void *pkey,
static void
tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
{
- PyCodeObject *code;
- PyObject *filename;
- _Py_hashtable_entry_t *entry;
- int lineno;
-
frame->filename = unknown_filename;
- lineno = PyFrame_GetLineNumber(pyframe);
- if (lineno < 0)
+ int lineno = PyFrame_GetLineNumber(pyframe);
+ if (lineno < 0) {
lineno = 0;
+ }
frame->lineno = (unsigned int)lineno;
- code = PyFrame_GetCode(pyframe);
- if (code->co_filename == NULL) {
+ PyCodeObject *code = PyFrame_GetCode(pyframe);
+ PyObject *filename = code->co_filename;
+ Py_DECREF(code);
+
+ if (filename == NULL) {
#ifdef TRACE_DEBUG
tracemalloc_error("failed to get the filename of the code object");
#endif
return;
}
- filename = code->co_filename;
assert(filename != NULL);
if (filename == NULL)
return;
@@ -375,6 +373,7 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
}
/* intern the filename */
+ _Py_hashtable_entry_t *entry;
entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename);
if (entry != NULL) {
_Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename);
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 6b3559e..533186b 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -1237,5 +1237,6 @@ PyFrame_GetCode(PyFrameObject *frame)
assert(frame != NULL);
PyCodeObject *code = frame->f_code;
assert(code != NULL);
+ Py_INCREF(code);
return code;
}
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index f65f053..8f9ab5c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -8031,7 +8031,6 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
/* Call super(), without args -- fill in from __class__
and first local variable on the stack. */
PyFrameObject *f;
- PyCodeObject *co;
Py_ssize_t i, n;
f = PyThreadState_GetFrame(_PyThreadState_GET());
if (f == NULL) {
@@ -8039,7 +8038,8 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
"super(): no current frame");
return -1;
}
- co = PyFrame_GetCode(f);
+ PyCodeObject *co = PyFrame_GetCode(f);
+ Py_DECREF(co); // use a borrowed reference
if (co->co_argcount == 0) {
PyErr_SetString(PyExc_RuntimeError,
"super(): no arguments");
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 7a620dc..7c15ce0 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -785,6 +785,8 @@ is_internal_frame(PyFrameObject *frame)
PyCodeObject *code = PyFrame_GetCode(frame);
PyObject *filename = code->co_filename;
+ Py_DECREF(code);
+
if (filename == NULL) {
return 0;
}
@@ -850,7 +852,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
}
else {
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);
*lineno = PyFrame_GetLineNumber(f);
}
diff --git a/Python/import.c b/Python/import.c
index 9142ebb..8c94e0e 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1557,6 +1557,7 @@ remove_importlib_frames(PyThreadState *tstate)
else {
prev_link = (PyObject **) &traceback->tb_next;
}
+ Py_DECREF(code);
tb = next;
}
done:
diff --git a/Python/traceback.c b/Python/traceback.c
index 1ea6cba..438a2c4 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -581,6 +581,7 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
err = PyErr_CheckSignals();
}
}
+ Py_DECREF(code);
tb = tb->tb_next;
}
if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) {
@@ -752,12 +753,9 @@ _Py_DumpASCII(int fd, PyObject *text)
static void
dump_frame(int fd, PyFrameObject *frame)
{
- PyCodeObject *code;
- int lineno;
-
- code = PyFrame_GetCode(frame);
+ PyCodeObject *code = PyFrame_GetCode(frame);
PUTS(fd, " File ");
- if (code != NULL && code->co_filename != NULL
+ if (code->co_filename != NULL
&& PyUnicode_Check(code->co_filename))
{
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 */
- lineno = PyCode_Addr2Line(code, frame->f_lasti);
+ int lineno = PyCode_Addr2Line(code, frame->f_lasti);
PUTS(fd, ", line ");
if (lineno >= 0) {
_Py_DumpDecimal(fd, (unsigned long)lineno);
@@ -778,7 +776,7 @@ dump_frame(int fd, PyFrameObject *frame)
}
PUTS(fd, " in ");
- if (code != NULL && code->co_name != NULL
+ if (code->co_name != NULL
&& PyUnicode_Check(code->co_name)) {
_Py_DumpASCII(fd, code->co_name);
}
@@ -787,6 +785,7 @@ dump_frame(int fd, PyFrameObject *frame)
}
PUTS(fd, "\n");
+ Py_DECREF(code);
}
static void