Skip to content

Commit 4a58e68

Browse files
committed
Make it explicit that shim frame is artificial and should not show up in tracebacks or sys._getframe()
1 parent 70e3e06 commit 4a58e68

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

Include/internal/pycore_frame.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct _PyInterpreterFrame {
6161
_Py_CODEUNIT *prev_instr;
6262
int stacktop; /* Offset of TOS from localsplus */
6363
bool is_entry; // Whether this is the "root" frame for the current _PyCFrame.
64+
bool is_artificial; // Hide this frame in backtraces.
6465
char owner;
6566
/* Locals and stack */
6667
PyObject *localsplus[1];
@@ -109,6 +110,7 @@ _PyFrame_InitializeSpecials(
109110
frame->frame_obj = NULL;
110111
frame->prev_instr = _PyCode_CODE(frame->f_code) - 1;
111112
frame->is_entry = false;
113+
frame->is_artificial = false;
112114
frame->owner = FRAME_OWNED_BY_THREAD;
113115
}
114116

Python/ceval.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
15741574
Py_INCREF(res);
15751575

15761576
#define TRACE_FUNCTION_EXIT() \
1577-
if (cframe.use_tracing) { \
1577+
if (cframe.use_tracing && !frame->is_artificial) { \
15781578
if (trace_function_exit(tstate, frame, retval)) { \
15791579
Py_DECREF(retval); \
15801580
goto exit_unwind; \
@@ -5010,6 +5010,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
50105010
if (shim == NULL) {
50115011
goto error;
50125012
}
5013+
shim->is_artificial = true;
50135014
CALL_STAT_INC(inlined_py_calls);
50145015
shim->previous = frame;
50155016
shim->prev_instr = _PyCode_CODE(shim->f_code) + 1;

Python/frame.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
7070
assert(f->f_back == NULL);
7171
if (frame->previous != NULL) {
7272
/* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */
73-
PyFrameObject *back = _PyFrame_GetFrameObject(frame->previous);
73+
_PyInterpreterFrame *prev = frame->previous;
74+
while (prev->is_artificial) {
75+
prev = prev->previous;
76+
}
77+
PyFrameObject *back = _PyFrame_GetFrameObject(prev);
7478
if (back == NULL) {
7579
/* Memory error here. */
7680
assert(PyErr_ExceptionMatches(PyExc_MemoryError));

Python/sysmodule.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,9 @@ sys__getframe_impl(PyObject *module, int depth)
17781778

17791779
while (depth > 0 && frame != NULL) {
17801780
frame = frame->previous;
1781-
--depth;
1781+
if (!frame->is_artificial) {
1782+
--depth;
1783+
}
17821784
}
17831785
if (frame == NULL) {
17841786
_PyErr_SetString(tstate, PyExc_ValueError,

0 commit comments

Comments
 (0)