-
-
Notifications
You must be signed in to change notification settings - Fork 448
Use PyFrame_GetLasti() #1353
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
Use PyFrame_GetLasti() #1353
Conversation
With this header file, it also becomes possible to drop MyFrame_GetCode() from coverage/ctracer/util.h and use PyFrame_GetCode() on all Python versions. It would allow to fix a reference leak in coverage affecting Python 3.9 and newer: PyFrame_GetCode() returns a strong reference, whereas MyFrame_GetCode() returns a borrow reference on Python 3.8 and older. Currently, coverage always make the assumption that MyFrame_GetCode() returns a borrow reference which is wrong on Python 3.9 and newer. I chose to restrict this PR to PyFrame_GetLasti() to keep it short. |
Current implementation of PyFrame_GetLasti() in upstream pythoncapi_compat.h:
In this PR, I replaced IMO it's better to rely on pythoncapi_compat.h since this code is non trivial. |
@nedbat: Are you ok to use pythoncapi_compat.h? As I wrote, it would allow to fix the coverage MyFrame_GetCode() refleak (I can work on a fix, once this PR is merged). |
@vstinner Yes, I am fine with using pythoncapi_compat.h. But when I try this pull request on main, I still have compile errors:
I'm going to work on this, but if you have suggestions, I would welcome them! |
I deleted my comment. I went 1 week in holiday and it is way enough for me to forget the context :-) This PR is supposed to support Python 3.11 alpha versions. I'm not sure what's going on. |
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.
@nedbat as a drive-by reviewer, I hope I'm not repeating anything you already know:
_PyInterpreterFrame
is the internal frame object used in CPython since 3.11a1. We no longer use PyFrameObject
except when a debugger requests it. When a debugger does ask for it, it's created on the fly.
coverage/ctracer/util.h
Outdated
#define MyFrame_lasti(f) ((f)->f_lasti * 2) | ||
#else | ||
#define MyFrame_lasti(f) ((f)->f_lasti) | ||
#define PyFrame_GetLasti(f) ((f)->f_frame->f_lasti * 2) |
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.
The version check is off because since 3.11a1, f->f_frame
refers to the internal _PyInterpreterFrame
/_interpreter_frame
struct, not PyFrameObject
. Unfortunately I suspect you need to add the _PyInterpreterFrame_LASTI
macro and use it like how GetLastI
uses it for 3.11a1-a7, like what CPython does https://github.com/python/cpython/blob/64a54e511debaac6d3a6e53685824fce435c440c/Objects/frameobject.c#L1162.
_PyInterpreterFrame_LASTI
:
https://github.com/python/cpython/blob/main/Include/internal/pycore_frame.h#L69.
Alternatively, you can manually expand that macro in pythoncapi_compat.h
:).
Also, You could access |
No. Please don't use an internal C API to read co_code. This attribute is accessible in Python, so we should provide a public function for that. |
Or you can already use |
See python/cpython#91397 "Move the PyCodeObject structure to the internal C API (make the structure opaque)". |
Sorry I wasn't trying to suggest people use it. Anyways, its in the internal API and completely private/hidden so its impossible to use :). Also I highly do not recommend accessing the struct member |
I've solved the |
@nedbat I have a WIP branch 1 which uses Footnotes |
Replace MyFrame_lasti() with PyFrame_GetLasti(): Python 3.11.0b1 adds PyFrame_GetLasti(). Add pythoncapi_compat.h header file to get PyFrame_GetLasti() on Python 3.10 and older. File copied from: https://github.com/python/pythoncapi_compat Drop support for alpha versions of Python 3.11 which don't have PyFrame_GetLasti().
I rebased my PR on the master branch and I updated pythoncapi_compat.h. My PR drops support for Python 3.11 alpha versions. IMO it's too complicated to support 3.11 alpha versions and it's not worth it. I prefer to write a separated PR for PyCode_GetCode(), since it requires to add Py_DECREF(). I prefer to keep this PR easy to review. |
0c14f1a
to
82169a6
Compare
Replace MyFrame_lasti() with PyFrame_GetLasti(): Python 3.11.0b1 adds
PyFrame_GetLasti().
Add pythoncapi_compat.h header file to get PyFrame_GetLasti() on
Python 3.10 and older. File copied from:
https://github.com/python/pythoncapi_compat
Keep compatibility code for alpha versions of Python 3.11 (alpha 1 to
alpha 7). Remove PyFrame_GetLocals(), PyFrame_GetGlobals() and
PyFrame_GetBuiltins() in pythoncapi_compat.h which are not compatible
with alpha versions of Python 3.11. Hack pythoncapi_compat.h to not
define PyFrame_GetLasti() on Python 3.11a1 and newer.