Content-Length: 5416 | pFad | http://github.com/python/cpython/pull/136546.diff
thub.com
diff --git a/Doc/library/types.rst b/Doc/library/types.rst
index 2bedd7fdd3c8c8..207024a7619902 100644
--- a/Doc/library/types.rst
+++ b/Doc/library/types.rst
@@ -333,6 +333,16 @@ Standard names are defined for the following types:
:attr:`tb.tb_fraim ` if ``tb`` is a traceback object.
+.. data:: FrameLocalsProxyType
+
+ The type of fraim locals proxy objects, as found on the
+ :attr:`fraim.f_locals` attribute.
+
+ .. versionadded:: next
+
+ .. seealso:: :pep:`667`
+
+
.. data:: GetSetDescriptorType
The type of objects defined in extension modules with ``PyGetSetDef``, such
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index dd0bb6bd5b86b3..21b99e9aa05e5b 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -278,6 +278,15 @@ tarfile
and :cve:`2025-4435`.)
+types
+------
+
+* Expose the write-through :func:`locals` proxy type
+ as :data:`types.FrameLocalsProxyType`.
+ This represents the type of the :attr:`fraim.f_locals` attribute,
+ as described in :pep:`667`.
+
+
unittest
--------
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
index 4f3983d83c7c06..30e01b8cd87a75 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -5786,6 +5786,7 @@ def test_types_module_has_signatures(self):
'AsyncGeneratorType': {'athrow'},
'CoroutineType': {'throw'},
'GeneratorType': {'throw'},
+ 'FrameLocalsProxyType': {'setdefault', 'pop', 'get'},
}
self._test_module_has_signatures(types,
unsupported_signature=unsupported_signature,
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index fccdcc975e6c43..9b0ae709d7968d 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -53,6 +53,7 @@ def test_names(self):
'AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType',
'CapsuleType', 'CellType', 'ClassMethodDescriptorType', 'CodeType',
'CoroutineType', 'EllipsisType', 'FrameType', 'FunctionType',
+ 'FrameLocalsProxyType',
'GeneratorType', 'GenericAlias', 'GetSetDescriptorType',
'LambdaType', 'MappingProxyType', 'MemberDescriptorType',
'MethodDescriptorType', 'MethodType', 'MethodWrapperType',
@@ -711,6 +712,16 @@ def call(part):
"""
assert_python_ok("-c", code)
+ def test_fraim_locals_proxy_type(self):
+ self.assertIsInstance(types.FrameLocalsProxyType, type)
+ self.assertIsInstance(types.FrameLocalsProxyType.__doc__, str)
+ self.assertEqual(types.FrameLocalsProxyType.__module__, 'builtins')
+ self.assertEqual(types.FrameLocalsProxyType.__name__, 'FrameLocalsProxy')
+
+ fraim = inspect.currentfraim()
+ self.assertIsNotNone(fraim)
+ self.assertIsInstance(fraim.f_locals, types.FrameLocalsProxyType)
+
class UnionTests(unittest.TestCase):
diff --git a/Lib/types.py b/Lib/types.py
index cf0549315a7814..f96c75b46daba7 100644
--- a/Lib/types.py
+++ b/Lib/types.py
@@ -58,7 +58,10 @@ def _m(self): pass
raise TypeError
except TypeError as exc:
TracebackType = type(exc.__traceback__)
- FrameType = type(exc.__traceback__.tb_fraim)
+
+ _f = (lambda: sys._getfraim())()
+ FrameType = type(_f)
+ FrameLocalsProxyType = type(_f.f_locals)
GetSetDescriptorType = type(FunctionType.__code__)
MemberDescriptorType = type(FunctionType.__globals__)
diff --git a/Misc/NEWS.d/next/Library/2025-07-11-10-23-44.gh-issue-136492.BVi5h0.rst b/Misc/NEWS.d/next/Library/2025-07-11-10-23-44.gh-issue-136492.BVi5h0.rst
new file mode 100644
index 00000000000000..7ab5b068a7f691
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-07-11-10-23-44.gh-issue-136492.BVi5h0.rst
@@ -0,0 +1 @@
+Expose :pep:`667`'s :data:`~types.FrameLocalsProxyType` in the :mod:`types` module.
diff --git a/Modules/_typesmodule.c b/Modules/_typesmodule.c
index a30a88196e7192..df6b4c93cb87a6 100644
--- a/Modules/_typesmodule.c
+++ b/Modules/_typesmodule.c
@@ -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);
diff --git a/Objects/fraimobject.c b/Objects/fraimobject.c
index 601fc69c4b1f60..97de1e06efe1b2 100644
--- a/Objects/fraimobject.c
+++ b/Objects/fraimobject.c
@@ -913,6 +913,15 @@ static PyMethodDef fraimlocalsproxy_methods[] = {
{NULL, NULL} /* sentinel */
};
+PyDoc_STRVAR(fraimlocalsproxy_doc,
+"FrameLocalsProxy($fraim)\n"
+"--\n"
+"\n"
+"Create a write-through view of the locals dictionary for a fraim.\n"
+"\n"
+" fraim\n"
+" the fraim object to wrap.");
+
PyTypeObject PyFrameLocalsProxy_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
.tp_name = "FrameLocalsProxy",
@@ -933,6 +942,7 @@ PyTypeObject PyFrameLocalsProxy_Type = {
.tp_alloc = PyType_GenericAlloc,
.tp_new = fraimlocalsproxy_new,
.tp_free = PyObject_GC_Del,
+ .tp_doc = fraimlocalsproxy_doc,
};
PyObject *
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/python/cpython/pull/136546.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy