Skip to content

gh-136492: Add FrameLocalsProxyType to types #136546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
78b842c
Expose FrameLocalsProxy in types and _types
ZeroIntensity Jul 11, 2025
e2ddcbe
Add a test case.
ZeroIntensity Jul 11, 2025
22e056d
Add a documentation entry.
ZeroIntensity Jul 11, 2025
b8fd733
Use the 'type' suffix.
ZeroIntensity Jul 11, 2025
abbe1d3
Add a whatsnew entry.
ZeroIntensity Jul 11, 2025
753c9bc
Add blurb.
ZeroIntensity Jul 11, 2025
b087d9b
Fix the tests.
ZeroIntensity Jul 11, 2025
1971a14
Sort the name alphabetically.
ZeroIntensity Jul 11, 2025
fdeb2d0
Sort alphabetically in _types.
ZeroIntensity Jul 11, 2025
c8600b9
Move whatsnew section.
ZeroIntensity Jul 11, 2025
70cc4db
Somewhat fix the tests.
ZeroIntensity Jul 11, 2025
fee5256
Reduce the diff.
ZeroIntensity Jul 11, 2025
a110148
Use a workaround for the tests.
ZeroIntensity Jul 11, 2025
929f81e
Move PEP note and remove locals() reference.
ZeroIntensity Jul 11, 2025
fb710eb
Update Doc/whatsnew/3.15.rst
ZeroIntensity Jul 12, 2025
5923263
Add a signature for FrameLocalsProxy()
ZeroIntensity Jul 12, 2025
22c2bbe
Change the tp_name to types.FrameLocalsProxyType.
ZeroIntensity Jul 15, 2025
9bca253
Merge branch 'main' into frameslocalsproxy-types
ZeroIntensity Jul 15, 2025
58e8577
Fix type name in test_frame.
ZeroIntensity Jul 15, 2025
bdabeaf
Merge branch 'frameslocalsproxy-types' of https://github.com/zerointe…
ZeroIntensity Jul 15, 2025
7a649c2
Apply suggestions from code review
ZeroIntensity Jul 15, 2025
e0f674d
Revert "Fix type name in test_frame."
ZeroIntensity Jul 15, 2025
faa4cf4
Revert "Change the tp_name to types.FrameLocalsProxyType."
ZeroIntensity Jul 15, 2025
ca05198
Merge branch 'frameslocalsproxy-types' of https://github.com/zerointe…
ZeroIntensity Jul 15, 2025
0463c30
Revert "Reduce the diff."
ZeroIntensity Jul 15, 2025
59daace
Fix tests that were broken by the tp_name revert.
ZeroIntensity Jul 15, 2025
349374d
Unify how FrameType and FrameLocalsProxyType are created.
ZeroIntensity Jul 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Doc/library/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,17 @@ Standard names are defined for the following types:
:attr:`tb.tb_frame <traceback.tb_frame>` if ``tb`` is a traceback object.


.. data:: FrameLocalsProxyType

The type of frame locals proxy objects, as found on the
:attr:`frame.f_locals` attribute.

.. versionadded:: next

.. seealso::
:pep:`667`


.. data:: GetSetDescriptorType

The type of objects defined in extension modules with ``PyGetSetDef``, such
Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,13 @@ tarfile
and :cve:`2025-4435`.)


types
------

* Added :data:`types.FrameLocalsProxyType` for representing the type of
the :attr:`frame.f_locals` attribute, as determined in :pep:`667`.


zlib
----

Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -5786,10 +5786,13 @@ def test_types_module_has_signatures(self):
'AsyncGeneratorType': {'athrow'},
'CoroutineType': {'throw'},
'GeneratorType': {'throw'},
'FrameLocalsProxyType': {'setdefault', 'pop', 'get'}
}
no_signature = {'FrameLocalsProxyType'}
self._test_module_has_signatures(types,
unsupported_signature=unsupported_signature,
methods_no_signature=methods_no_signature)
methods_no_signature=methods_no_signature,
no_signature=no_signature)

def test_sys_module_has_signatures(self):
no_signature = {'getsizeof', 'set_asyncgen_hooks'}
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def test_names(self):
'MethodDescriptorType', 'MethodType', 'MethodWrapperType',
'ModuleType', 'NoneType', 'NotImplementedType', 'SimpleNamespace',
'TracebackType', 'UnionType', 'WrapperDescriptorType',
'FrameLocalsProxyType'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the list sorted (GH doesn't let me add a suggestion)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had that originally but @picnixz had reservations about it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to keep the list sorted rather than attempt to minimise 3-4 lines of diff here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion was to keep it sorted but by just adding the export on its own line.

}
self.assertEqual(all_names, set(c_types.__all__))
self.assertEqual(all_names - c_only_names, set(py_types.__all__))
Expand Down Expand Up @@ -711,6 +712,11 @@ def call(part):
"""
assert_python_ok("-c", code)

def test_frame_locals_proxy(self):
frame = inspect.currentframe()
self.assertIsNotNone(frame)
self.assertIsInstance(frame.f_locals, types.FrameLocalsProxyType)


class UnionTests(unittest.TestCase):

Expand Down
1 change: 1 addition & 0 deletions Lib/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def _m(self): pass
EllipsisType = type(Ellipsis)
NoneType = type(None)
NotImplementedType = type(NotImplemented)
FrameLocalsProxyType = (lambda: type(sys._getframe().f_locals))()

# CapsuleType cannot be accessed from pure Python,
# so there is no fallback definition.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :data:`~types.FrameLocalsProxyType` to the :mod:`types` module.
1 change: 1 addition & 0 deletions Modules/_typesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ _types_exec(PyObject *m)
EXPORT_STATIC_TYPE("CoroutineType", PyCoro_Type);
EXPORT_STATIC_TYPE("EllipsisType", PyEllipsis_Type);
EXPORT_STATIC_TYPE("FrameType", PyFrame_Type);
EXPORT_STATIC_TYPE("FrameLocalsProxyType", PyFrameLocalsProxy_Type);
EXPORT_STATIC_TYPE("FunctionType", PyFunction_Type);
EXPORT_STATIC_TYPE("GeneratorType", PyGen_Type);
EXPORT_STATIC_TYPE("GenericAlias", Py_GenericAliasType);
Expand Down
Loading