gh-141004: Document unstable executable kind macros in `pyframe.h` by Yashp002 · Pull Request #143490 · python/cpython
gh-141004: Document unstable executable kind macros in pyframe.h
This PR documents the PyUnstable_EXECUTABLE_KIND_* macros and the PyUnstable_ExecutableKinds array in Doc/c-api/frame.rst. These were listed as undocumented in the parent issue.
📚 Documentation preview 📚: https://cpython-previews--143490.org.readthedocs.build/
| Index for the "skip" kind in ``PyUnstable_ExecutableKinds``. | ||
| Indicates that the frame's code object should be skipped. | ||
|
|
||
| .. versionadded:: 3.12 |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9c03215 was not backported to 3.12?
These are rather useless without docs for PyUnstable_ExecutableKinds.
Once you document that, you can associate the macros with it, like for example Py_MOD_GIL_USED with Py_mod_gil.
@encukou ok, makes sense. I'll add the documentation for PyUnstable_ExecutableKinds and link these macros to it. Thanks :)
Comment on lines +255 to +257
| An enumeration of the different kinds of executables (code objects) in a frame. | ||
| This can be one of the constants :c:macro:`PyUnstable_EXECUTABLE_KIND_SKIP` | ||
| or :c:macro:`PyUnstable_EXECUTABLE_KIND_PY_FUNCTION`. |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an array, not an enum.
Could you document what it's useful for or how to use it? That part isn't very clear to me.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please go through what i've mentioned below and let me know if its perfectly appropriate, and as soon I recieve the heads up i'll update and commit:
.. c:var:: PyUnstable_ExecutableKinds
An array of executable kinds (executor types) for frames, used for internal
debugging and tracing. The entries are indexed by the constants
:c:macro:PyUnstable_EXECUTABLE_KIND_SKIP or
:c:macro:PyUnstable_EXECUTABLE_KIND_PY_FUNCTION.
This can be used to identify the type of the code object associated with a frame.
.. versionadded:: 3.13
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could @encukou or @StanFromIreland please review my suggestion above and correct it if its wrong or gimme the green light to commit this ⬆️
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer some words on why/how you'd use this.
You can say “The entries are indexed by the following constants:”, and indent the docs for the constants. Since the entries are all similar, you could even use a compact table, like in code object flags.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to update ignored_c_api.txt here too.
Comment on lines +296 to +298
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too many blank lines.
|
|
||
| .. c:macro:: PyUnstable_EXECUTABLE_KIND_PY_FUNCTION | ||
|
|
||
| Index for the "Python function" kind in ``PyUnstable_ExecutableKinds``. |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be links via :c:data:`PyUnstable_ExecutableKinds`
We don't need those tests to run at all really, we can (I think) exclude the ignore file from triggering the run-tests condition.
Edit: See #143583.
We don't need those tests to run at all really, we can (I think) exclude the ignore file from triggering the
run-testscondition.Edit: See #143583.
Can the same be said for #143492
and #143494 then? @StanFromIreland
This part is not clear to me:
Tools like debuggers and profilers can use this to identify the type of execution
context associated with a frame (e.g. to filter out internal frames).
I assume “frame” refers to PyFrameObject?
How do you use this array to filter out internal frames?
Once the docs say what the function is for and how to use it, there are some presentation issues to fix up:
There are now two descriptions for PyUnstable_EXECUTABLE_KIND_SKIP: on in list-table and one below. Choose one. If you need a full/sentence, use individual entries; if you only need a few words then the table makes sense.
Either way, indent the macro docs so they're under PyUnstable_ExecutableKinds, and use .. c:namespace:: NULL (see elsewhere in the docs for examples).
@encukou Since PyUnstable_EXECUTABLE_KIND_SKIP has only a couple words, should I just keep the list-table description and remove the one below completely?

as in the description of it below.
Also, Yes the frame refers to PyFrameObject and I'll be adding a sentence below saying "The frame should be skipped by tools.
- The frame corresponds to a standard Py function"
Also, to check for internal frames:
perf_map = PyUnstable_GetPerfMapFile()
for i, kind in enumerate(perf_map):
if kind == PyUnstable_EXECUTABLE_KIND_SKIP:
skip_frame(i)
It's from the Cpython source code
Should i go ahead with above mentioned changes?
Also, my indents with c:macro: are fine right? or have i missed something
Since PyUnstable_EXECUTABLE_KIND_SKIP has only a couple words, should I just keep the list-table description and remove the one below completely?
Yes. But switch to the .. c:macro: syntax rather than :c:macro:, so this is a definition.
Example code would be very helpful, yes. Please test that it works, though.
| debugging and tracing. | ||
|
|
||
| Tools like debuggers and profilers can use this to identify the type of execution | ||
| context associated with a frame (e.g. to filter out internal frames). |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not use latin abbreviations, see our style guide for more information.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you mentioned this before, I'm sorry it slipped my mind, fixing now.
| * - .. c:macro:: PyUnstable_EXECUTABLE_KIND_PY_FUNCTION | ||
| - The frame corresponds to a standard Python function. | ||
|
|
||
| .. versionadded:: 3.13 |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .. versionadded:: ... should be the last thing in a function's/macro's/type's/etc. doc, please move it after the example.
| .. code-block:: c | ||
|
|
||
| // Check if a frame should be skipped | ||
| if (kind == PyUnstable_EXECUTABLE_KIND_SKIP) { |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is kind? How do you get it?
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@encukou kind here refers to the executable kind field stored in the frame's executor (e.g. _PyFrame_GetExecutableKind(frame))
Do you think it's better to explicitly show _PyFrame_GetExecutableKind (if exposed), or should I just remove the example block to avoid confusion?
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, explicitly show your _PyFrame_GetExecutableKind. We'll also need to make it public (or at least unstable) if we want users to use it.
@encukou could u check if these changes are satisfactory
@encukou
i've made changes to
modified: Doc/c-api/frame.rst
modified: Include/cpython/frameobject.h
modified: Modules/_testcapi/frame.c
modified: Python/frame.c
the tests seem to pass and the build works
| return PyLong_FromLong(kind); | ||
| } | ||
|
|
||
| return PyLong_FromLong(kind); |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test emits a DeprecationWarning:
ERROR: test_my_doc_example (test.test_capi.test_misc.Test_testcapi.test_my_doc_example)
----------------------------------------------------------------------
DeprecationWarning: It is deprecated to return a value that is not None from a test case (<built-in function test_my_doc_example> returned 'int')
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vstinner Honestly, i think im a little stuck on this issue, could you help?