build: MyFrame_lasti() uses PyObject_GetAttrString()#1331
Conversation
Reimplement the MyFrame_lasti() function using PyObject_GetAttrString(frame, "f_lasti") to avoid using the internal C API on Python 3.11. Add assertions in CTracer_handle_call() and CTracer_handle_return() to ensure that f_lasti is the in expected bounds.
I'm not sure that this part is correct :-) But the current code doesn't seem to handle negative lasti. With my change, lasti can be negative if something goes wrong, but it should not happen in practice: a frame always has a |
|
@nedbat: Would you mind to have a look? Do you prefer to read directly the PyFrameObject.f_lasti on Python 3.10 and older? Or are you fine with using the same code path on all Python versions? It's up to you. |
| #endif | ||
| static inline Py_ssize_t MyFrame_lasti(PyFrameObject *frame) | ||
| { | ||
| PyObject *obj = PyObject_GetAttrString((PyObject*)frame, "f_lasti"); |
There was a problem hiding this comment.
I guess I shouldn't be concerned about the overhead of this function?
There was a problem hiding this comment.
I don't know how to measure that. If you measure that the overhead is too large, I can consider adding a getter function to Python 3.11.
Does coverage performance overhead matter in general? Usually, I don't care much about performance of debugging or profiler tools.
There was a problem hiding this comment.
People run their test suites under coverage, and test suites are always too slow. "debugging and profiling" is a more occasional activity. I'll take a look at it.
There was a problem hiding this comment.
Right, I get it. But I would prefer to not add getter functions just for coverage if the performance overhead of this PR is "acceptable". I would prefer to only consider new functions to the Python C API if it's "needed". So it would be nice if you could provide a benchmark (and benchmark results) so measure the performance impact of this PR. Sorry, I don't know how to do that.
|
|
The Python |
|
yes, I just meant this PR was all the more necessary :) |
|
there are also new errors related to direct access to and |
|
You haven't said, but I assume you are using 3.11.0a7? I could use some help adjusting to all of the frame changes. |
|
and |
|
python/cpython#32413 adds |
I also added PyFrame_GetLasti() to the pythoncapi-compat project API, so it's available on Python 2.7-3.10: https://github.com/python/pythoncapi_compat You can use pythoncapi_compat.h to get the function on all Python versions. |
|
I wrote #1352 to use PyFrame_GetLasti() in coverage: replace MyFrame_lasti() with PyFrame_GetLasti() using pythoncapi_compat.h. Sadly this PR drops support for Python 3.11a1..3.11a7. |
And #1353 is an attempt to keep support for Python 3.11 alpha versions. |
|
Since there are concerns about worse performance caused by the usage of PyObject_GetAttrString(), I close this PR in favor of #1353 which is the newly added public function PyFrame_GetLasti(). |
Reimplement the MyFrame_lasti() function using
PyObject_GetAttrString(frame, "f_lasti") to avoid using the internal
C API on Python 3.11.
Add assertions in CTracer_handle_call() and CTracer_handle_return()
to ensure that f_lasti is the in expected bounds.