-
-
Notifications
You must be signed in to change notification settings - Fork 35.3k
gh-156133: Add PyUnstable_InterpreterFrame_GetLocal
#156134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Add :c:func:`PyUnstable_InterpreterFrame_GetLocal` to read a local variable of | ||
| an internal interpreter frame by its localsplus index. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2247,6 +2247,42 @@ frame_get_var(_PyInterpreterFrame *frame, PyCodeObject *co, int i, | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| PyObject * | ||||||||||||||||||||||||||||||||||
| PyUnstable_InterpreterFrame_GetLocal(_PyInterpreterFrame *frame, | ||||||||||||||||||||||||||||||||||
| Py_ssize_t index) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| PyCodeObject *co = _PyFrame_GetCode(frame); | ||||||||||||||||||||||||||||||||||
| if (index < 0 || index >= co->co_nlocalsplus) { | ||||||||||||||||||||||||||||||||||
| PyErr_Format( | ||||||||||||||||||||||||||||||||||
| PyExc_IndexError, | ||||||||||||||||||||||||||||||||||
| "PyUnstable_InterpreterFrame_GetLocal: index %zd out of range [0, %d)", | ||||||||||||||||||||||||||||||||||
| index, co->co_nlocalsplus); | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| int offset = PyUnstable_Code_GetFirstFree(co); // co_nlocalsplus - co_nfreevars | ||||||||||||||||||||||||||||||||||
| if (index < offset) { | ||||||||||||||||||||||||||||||||||
| // Local or cell variable. frame_get_var unboxes cells and copes with | ||||||||||||||||||||||||||||||||||
| // not-yet-started frames and arguments not yet promoted by MAKE_CELL. | ||||||||||||||||||||||||||||||||||
| if (_PyLocals_GetKind(co->co_localspluskinds, (int)index) & CO_FAST_HIDDEN) { | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| PyObject *value = NULL; | ||||||||||||||||||||||||||||||||||
| frame_get_var(frame, co, (int)index, &value); | ||||||||||||||||||||||||||||||||||
| return value; // strong reference, or NULL if unset | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Free variable: read from the function closure rather than localsplus. | ||||||||||||||||||||||||||||||||||
| if ((co->co_flags & CO_OPTIMIZED) | ||||||||||||||||||||||||||||||||||
| && PyStackRef_FunctionCheck(frame->f_funcobj)) { | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
See PEP7:
|
||||||||||||||||||||||||||||||||||
| PyFunctionObject *func = _PyFrame_GetFunction(frame); | ||||||||||||||||||||||||||||||||||
| PyObject *cell = PyTuple_GET_ITEM(func->func_closure, index - offset); | ||||||||||||||||||||||||||||||||||
| return Py_XNewRef(PyCell_GET(cell)); | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may have concurrency issue under free-thread build, we can use PyCell_GetRef here instead, see it's defination: cpython/Include/internal/pycore_cell.h Lines 36 to 49 in 65e149a
Suggested change
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| bool | ||||||||||||||||||||||||||||||||||
| _PyFrame_HasHiddenLocals(_PyInterpreterFrame *frame) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.