gh-101100: Properly document frame object attributes (#112735)

This commit is contained in:
Alex Waygood 2023-12-05 19:27:59 +00:00 committed by GitHub
parent c2e2df8356
commit d109f637c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 88 additions and 49 deletions

View file

@ -50,7 +50,7 @@ See also :ref:`Reflection <reflection>`.
.. c:function:: PyObject* PyFrame_GetBuiltins(PyFrameObject *frame)
Get the *frame*'s ``f_builtins`` attribute.
Get the *frame*'s :attr:`~frame.f_builtins` attribute.
Return a :term:`strong reference`. The result cannot be ``NULL``.
@ -81,7 +81,7 @@ See also :ref:`Reflection <reflection>`.
.. c:function:: PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
Get the *frame*'s ``f_globals`` attribute.
Get the *frame*'s :attr:`~frame.f_globals` attribute.
Return a :term:`strong reference`. The result cannot be ``NULL``.
@ -90,7 +90,7 @@ See also :ref:`Reflection <reflection>`.
.. c:function:: int PyFrame_GetLasti(PyFrameObject *frame)
Get the *frame*'s ``f_lasti`` attribute.
Get the *frame*'s :attr:`~frame.f_lasti` attribute.
Returns -1 if ``frame.f_lasti`` is ``None``.
@ -120,7 +120,7 @@ See also :ref:`Reflection <reflection>`.
.. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame)
Get the *frame*'s ``f_locals`` attribute (:class:`dict`).
Get the *frame*'s :attr:`~frame.f_locals` attribute (:class:`dict`).
Return a :term:`strong reference`.

View file

@ -1662,7 +1662,8 @@ Python-level trace functions in previous versions.
The value passed as the *what* parameter to a :c:type:`Py_tracefunc` function
(but not a profiling function) when a line-number event is being reported.
It may be disabled for a frame by setting :attr:`f_trace_lines` to *0* on that frame.
It may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to
*0* on that frame.
.. c:var:: int PyTrace_RETURN
@ -1694,7 +1695,7 @@ Python-level trace functions in previous versions.
The value for the *what* parameter to :c:type:`Py_tracefunc` functions (but not
profiling functions) when a new opcode is about to be executed. This event is
not emitted by default: it must be explicitly requested by setting
:attr:`f_trace_opcodes` to *1* on the frame.
:attr:`~frame.f_trace_opcodes` to *1* on the frame.
.. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)

View file

@ -865,8 +865,8 @@ iterations of the loop.
.. opcode:: RERAISE
Re-raises the exception currently on top of the stack. If oparg is non-zero,
pops an additional value from the stack which is used to set ``f_lasti``
of the current frame.
pops an additional value from the stack which is used to set
:attr:`~frame.f_lasti` of the current frame.
.. versionadded:: 3.9

View file

@ -1605,8 +1605,8 @@ the following flags:
.. data:: CO_NEWLOCALS
If set, a new dict will be created for the frame's ``f_locals`` when
the code object is executed.
If set, a new dict will be created for the frame's :attr:`~frame.f_locals`
when the code object is executed.
.. data:: CO_VARARGS

View file

@ -1600,7 +1600,8 @@ always available.
:file:`Objects/lnotab_notes.txt` for a detailed explanation of how this
works.
Per-line events may be disabled for a frame by setting
:attr:`!f_trace_lines` to :const:`False` on that :ref:`frame <frame-objects>`.
:attr:`~frame.f_trace_lines` to :const:`False` on that
:ref:`frame <frame-objects>`.
``'return'``
A function (or other code block) is about to return. The local trace
@ -1618,7 +1619,7 @@ always available.
opcode details). The local trace function is called; *arg* is
``None``; the return value specifies the new local trace function.
Per-opcode events are not emitted by default: they must be explicitly
requested by setting :attr:`!f_trace_opcodes` to :const:`True` on the
requested by setting :attr:`~frame.f_trace_opcodes` to :const:`True` on the
:ref:`frame <frame-objects>`.
Note that as an exception is propagated down the chain of callers, an
@ -1648,8 +1649,8 @@ always available.
.. versionchanged:: 3.7
``'opcode'`` event type added; :attr:`!f_trace_lines` and
:attr:`!f_trace_opcodes` attributes added to frames
``'opcode'`` event type added; :attr:`~frame.f_trace_lines` and
:attr:`~frame.f_trace_opcodes` attributes added to frames
.. function:: set_asyncgen_hooks(firstiter, finalizer)

View file

@ -388,7 +388,8 @@ Standard names are defined for the following types:
.. data:: GetSetDescriptorType
The type of objects defined in extension modules with ``PyGetSetDef``, such
as ``FrameType.f_locals`` or ``array.array.typecode``. This type is used as
as :attr:`FrameType.f_locals <frame.f_locals>` or ``array.array.typecode``.
This type is used as
descriptor for object attributes; it has the same purpose as the
:class:`property` type, but for classes defined in extension modules.

View file

@ -1174,16 +1174,36 @@ Frame objects represent execution frames. They may occur in traceback objects
single: f_lasti (frame attribute)
single: f_builtins (frame attribute)
Special read-only attributes: :attr:`f_back` is to the previous stack frame
(towards the caller), or ``None`` if this is the bottom stack frame;
:attr:`f_code` is the code object being executed in this frame; :attr:`f_locals`
is the dictionary used to look up local variables; :attr:`f_globals` is used for
global variables; :attr:`f_builtins` is used for built-in (intrinsic) names;
:attr:`f_lasti` gives the precise instruction (this is an index into the
bytecode string of the code object).
Special read-only attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Accessing ``f_code`` raises an :ref:`auditing event <auditing>`
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
.. list-table::
* - .. attribute:: frame.f_back
- Points to the previous stack frame (towards the caller),
or ``None`` if this is the bottom stack frame
* - .. attribute:: frame.f_code
- The :ref:`code object <code-objects>` being executed in this frame.
Accessing this attribute raises an :ref:`auditing event <auditing>`
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
* - .. attribute:: frame.f_locals
- The dictionary used by the frame to look up
:ref:`local variables <naming>`
* - .. attribute:: frame.f_globals
- The dictionary used by the frame to look up
:ref:`global variables <naming>`
* - .. attribute:: frame.f_builtins
- The dictionary used by the frame to look up
:ref:`built-in (intrinsic) names <naming>`
* - .. attribute:: frame.f_lasti
- The "precise instruction" of the frame object
(this is an index into the :term:`bytecode` string of the
:ref:`code object <code-objects>`)
.. index::
single: f_trace (frame attribute)
@ -1191,30 +1211,44 @@ Accessing ``f_code`` raises an :ref:`auditing event <auditing>`
single: f_trace_opcodes (frame attribute)
single: f_lineno (frame attribute)
Special writable attributes: :attr:`f_trace`, if not ``None``, is a function
called for various events during code execution (this is used by the debugger).
Normally an event is triggered for each new source line - this can be
disabled by setting :attr:`f_trace_lines` to :const:`False`.
Special writable attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Implementations *may* allow per-opcode events to be requested by setting
:attr:`f_trace_opcodes` to :const:`True`. Note that this may lead to
undefined interpreter behaviour if exceptions raised by the trace
function escape to the function being traced.
.. list-table::
:attr:`f_lineno` is the current line number of the frame --- writing to this
from within a trace function jumps to the given line (only for the bottom-most
frame). A debugger can implement a Jump command (aka Set Next Statement)
by writing to f_lineno.
* - .. attribute:: frame.f_trace
- If not ``None``, this is a function called for various events during
code execution (this is used by debuggers). Normally an event is
triggered for each new source line (see :attr:`~frame.f_trace_lines`).
* - .. attribute:: frame.f_trace_lines
- Set this attribute to :const:`False` to disable triggering a tracing
event for each source line.
* - .. attribute:: frame.f_trace_opcodes
- Set this attribute to :const:`True` to allow per-opcode events to be
requested. Note that this may lead to
undefined interpreter behaviour if exceptions raised by the trace
function escape to the function being traced.
* - .. attribute:: frame.f_lineno
- The current line number of the frame -- writing to this
from within a trace function jumps to the given line (only for the bottom-most
frame). A debugger can implement a Jump command (aka Set Next Statement)
by writing to this attribute.
Frame object methods
~~~~~~~~~~~~~~~~~~~~
Frame objects support one method:
.. method:: frame.clear()
This method clears all references to local variables held by the
frame. Also, if the frame belonged to a generator, the generator
This method clears all references to :ref:`local variables <naming>` held by the
frame. Also, if the frame belonged to a :term:`generator`, the generator
is finalized. This helps break reference cycles involving frame
objects (for example when catching an exception and storing its
traceback for later use).
objects (for example when catching an :ref:`exception <bltin-exceptions>`
and storing its :ref:`traceback <traceback-objects>` for later use).
:exc:`RuntimeError` is raised if the frame is currently executing
or suspended.

View file

@ -1998,13 +1998,13 @@ Some of the more notable changes are:
It would be difficult to detect any resulting difference from Python code, apart
from a slight speed up when Python is run without :option:`-O`.
C extensions that access the :attr:`f_lineno` field of frame objects should
C extensions that access the :attr:`~frame.f_lineno` field of frame objects should
instead call ``PyCode_Addr2Line(f->f_code, f->f_lasti)``. This will have the
added effect of making the code work as desired under "python -O" in earlier
versions of Python.
A nifty new feature is that trace functions can now assign to the
:attr:`f_lineno` attribute of frame objects, changing the line that will be
:attr:`~frame.f_lineno` attribute of frame objects, changing the line that will be
executed next. A ``jump`` command has been added to the :mod:`pdb` debugger
taking advantage of this new feature. (Implemented by Richie Hindle.)

View file

@ -399,7 +399,8 @@ PEP 626: Precise line numbers for debugging and other tools
PEP 626 brings more precise and reliable line numbers for debugging, profiling and coverage tools.
Tracing events, with the correct line number, are generated for all lines of code executed and only for lines of code that are executed.
The ``f_lineno`` attribute of frame objects will always contain the expected line number.
The :attr:`~frame.f_lineno` attribute of frame objects will always contain the
expected line number.
The ``co_lnotab`` attribute of code objects is deprecated and will be removed in 3.12.
Code that needs to convert from offset to line number should use the new ``co_lines()`` method instead.
@ -1959,11 +1960,11 @@ Changes in the C API
source_buf = PyBytes_AsString(source_bytes_object);
code = Py_CompileString(source_buf, filename, Py_file_input);
* For ``FrameObject`` objects, the ``f_lasti`` member now represents a wordcode
* For ``FrameObject`` objects, the :attr:`~frame.f_lasti` member now represents a wordcode
offset instead of a simple offset into the bytecode string. This means that this
number needs to be multiplied by 2 to be used with APIs that expect a byte offset
instead (like :c:func:`PyCode_Addr2Line` for example). Notice as well that the
``f_lasti`` member of ``FrameObject`` objects is not considered stable: please
:attr:`!f_lasti` member of ``FrameObject`` objects is not considered stable: please
use :c:func:`PyFrame_GetLineNumber` instead.
CPython bytecode changes

View file

@ -2458,11 +2458,12 @@ Porting to Python 3.11
* ``f_valuestack``: removed.
The Python frame object is now created lazily. A side effect is that the
``f_back`` member must not be accessed directly, since its value is now also
:attr:`~frame.f_back` member must not be accessed directly,
since its value is now also
computed lazily. The :c:func:`PyFrame_GetBack` function must be called
instead.
Debuggers that accessed the ``f_locals`` directly *must* call
Debuggers that accessed the :attr:`~frame.f_locals` directly *must* call
:c:func:`PyFrame_GetLocals` instead. They no longer need to call
:c:func:`PyFrame_FastToLocalsWithError` or :c:func:`PyFrame_LocalsToFast`,
in fact they should not call those functions. The necessary updating of the

View file

@ -2162,7 +2162,7 @@ Changes in the Python API
* The format of the ``co_lnotab`` attribute of code objects changed to support
a negative line number delta. By default, Python does not emit bytecode with
a negative line number delta. Functions using ``frame.f_lineno``,
a negative line number delta. Functions using :attr:`frame.f_lineno`,
``PyFrame_GetLineNumber()`` or ``PyCode_Addr2Line()`` are not affected.
Functions directly decoding ``co_lnotab`` should be updated to use a signed
8-bit integer type for the line number delta, but this is only required to

View file

@ -1891,7 +1891,7 @@ Other CPython Implementation Changes
* Trace hooks may now opt out of receiving the ``line`` and opt into receiving
the ``opcode`` events from the interpreter by setting the corresponding new
``f_trace_lines`` and ``f_trace_opcodes`` attributes on the
:attr:`~frame.f_trace_lines` and :attr:`~frame.f_trace_opcodes` attributes on the
frame being traced. (Contributed by Nick Coghlan in :issue:`31344`.)
* Fixed some consistency problems with namespace package module attributes.