Skip to content

Commit

Permalink
pythongh-101100: Properly document frame object attributes (python#11…
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood authored Dec 5, 2023
1 parent c2e2df8 commit d109f63
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 49 deletions.
8 changes: 4 additions & 4 deletions Doc/c-api/frame.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``.
Expand Down Expand Up @@ -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``.
Expand All @@ -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``.
Expand Down Expand Up @@ -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`.
Expand Down
5 changes: 3 additions & 2 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 5 additions & 4 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion Doc/library/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
84 changes: 59 additions & 25 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1174,47 +1174,81 @@ 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)
single: f_trace_lines (frame attribute)
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. list-table::

* - .. 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.

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.
* - .. 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.

: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.
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.
Expand Down
4 changes: 2 additions & 2 deletions Doc/whatsnew/2.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.)

Expand Down
7 changes: 4 additions & 3 deletions Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit d109f63

Please sign in to comment.