Closed
Description
The gr_frame
attribute refers to the innermost frame (the frame that called switch()
), but its f_back attribute points nowhere.
% python3.12
Python 3.12.0 (v3.12.0:0fb18b02c8, Oct 2 2023, 09:45:56) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import greenlet
>>> def inner(): greenlet.getcurrent().parent.switch(42)
...
>>> def outer(): inner()
...
>>> gr = greenlet.greenlet(outer)
>>> gr.switch()
42
>>> gr.gr_frame
<frame at 0x10438b7e0, file '<stdin>', line 1, code inner>
>>> gr.gr_frame.f_back
>>> greenlet.__version__
'3.0.1'
>>>
On 3.11 I see instead:
>>> gr.gr_frame
<frame at 0x7feb24db2700, file '<stdin>', line 1, code inner>
>>> gr.gr_frame.f_back
<frame at 0x7feb24db2660, file '<stdin>', line 1, code outer>
>>> gr.gr_frame.f_back.f_back
>>>
which is what I would expect from the documentation. This looks related to some logic in TPythonState.cpp
that moves the previous ptr into greenlet-local storage when suspending:
if (frame) {
this->_prev_frame = frame->f_frame->previous;
frame->f_frame->previous = nullptr;
}
How is greenlet introspection supposed to work on 3.12?