New submission from STINNER Victor <vstin...@python.org>:

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 <rep...@bugs.python.org>
<https://bugs.python.org/issue47092>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to