[New-bugs-announce] [issue47092] [C API] Add PyFrame_GetVar(frame, name) function

STINNER Victor report at bugs.python.org
Tue Mar 22 10:41:38 EDT 2022

New submission from STINNER Victor <vstinner at 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 <report at bugs.python.org>

More information about the New-bugs-announce mailing list