New submission from STINNER Victor <[email protected]>:
In Python 3.10, it's possible to call PyFrame_FastToLocalsWithError() on a
frame to get all variables as a dictionary. In Python, getting frame.f_locals
calls PyFrame_FastToLocalsWithError(). It's used by the pdb module for example:
self.curframe_locals = self.curframe.f_locals
The PyFrame_FastToLocalsWithError() function has multiple issues:
* It's inefficient.
* It may create a Python dictionary.
* It can fail to add items to the dictionary.
* Allocating memory can fail with memory allocation failure.
The problem is that a debugger or profiler should not modify a process when it
inspects it. It should avoid allocation memory for example. I propose adding a
new API to prevent that.
In Python 3.11, the PyFrameObject structure became opaque and changed deeply.
There are differend kinds of variables stored differently:
* Free variables: maybe in frame->f_func->func_closure[index], maybe in
frame->localsplus[index]
* Fast variable: frame->f_frame->localsplus[index]
* Cell variable: also need to call PyCell_GET()
Well... Look at _PyFrame_FastToLocalsWithError(), it's quite complicated ;-)
I propose to add a new public C API just to get a single variable value:
PyObject* PyFrame_GetVar(PyFrameObject *frame, PyObject *name)
I prefer to use a PyObject* for the name. You can use PyUnicode_FromString() to
get a PyObject* from a const char*.
This function would get the value where the variable is stored, it doesn't have
a to create a dictionary. Return NULL if the variable doesn't exist.
If I understand correctly, it should be possible to ensure that this function
would never raise an exception (never "fail"). So it should be possible to call
it even if an exception is raised, which is convenient for a debugger.
--
I plan to implement this API, but first I would like to make sure that there is
an agreement that such API is needed and helpful ;-)
--
See also draft PEP 558 and PEP 667 which propose API to *modify* variables and
make sure that they remain consistent when they are set and then get. The scope
of these PEPs is way wider than the simple propose PyFrame_GetVar() which would
be simpler implementation than PyFrame_FastToLocalsWithError().
----------
components: C API
messages: 415776
nosy: Mark.Shannon, ncoghlan, vstinner
priority: normal
severity: normal
status: open
title: [C API] Add PyFrame_GetVar(frame, name) function
versions: Python 3.11
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue47092>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com