@@ -243,3 +243,62 @@ Unless using :pep:`523`, you will not need this.
243243 Return the currently executing line number, or -1 if there is no line number.
244244
245245 .. versionadded :: 3.12
246+
247+
248+ .. c :var :: const PyTypeObject *PyUnstable_ExecutableKinds
249+
250+ An array of executable kinds (executor types) for frames, used for internal
251+ debugging and tracing.
252+
253+ Tools like debuggers and profilers can use this to identify the type of execution
254+ context associated with a frame (such as to filter out internal frames).
255+ The entries are indexed by the following constants:
256+
257+ .. list-table::
258+ :header-rows: 1
259+ :widths: auto
260+
261+ * - Constant
262+ - Description
263+ * - .. c:macro:: PyUnstable_EXECUTABLE_KIND_SKIP
264+ - The frame is internal (For example: inlined) and should be skipped by tools.
265+ * - .. c:macro:: PyUnstable_EXECUTABLE_KIND_PY_FUNCTION
266+ - The frame corresponds to a standard Python function.
267+ * - .. c:macro:: PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION
268+ - The frame corresponds to a function defined in native code.
269+ * - .. c:macro:: PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR
270+ - The frame corresponds to a method on a class instance.
271+
272+ However, Python's C API lacks a function to read the executable kind from
273+ a frame. Instead, use this recipe:
274+
275+ .. code-block:: c
276+
277+ int
278+ get_executable_kind(PyFrameObject *frame)
279+ {
280+ _PyInterpreterFrame *f = frame->f_frame;
281+ PyObject *exec = PyStackRef_AsPyObjectBorrow(f->f_executable);
282+
283+ if (PyCode_Check(exec)) {
284+ return PyUnstable_EXECUTABLE_KIND_PY_FUNCTION;
285+ }
286+ if (PyMethod_Check(exec)) {
287+ return PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION;
288+ }
289+ if (Py_IS_TYPE(exec, &PyMethodDescr_Type)) {
290+ return PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR;
291+ }
292+
293+ return PyUnstable_EXECUTABLE_KIND_SKIP;
294+ }
295+
296+ .. versionadded :: 3.13
297+
298+
299+ .. c :macro :: PyUnstable_EXECUTABLE_KINDS
300+
301+ The number of entries in :c:data: `PyUnstable_ExecutableKinds `.
302+
303+ .. versionadded :: 3.13
304+
0 commit comments