: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
and :cve:`2025-4435`.)
+types
+------
+
+* Expose the write-through :func:`locals` proxy type
+ as :data:`types.FrameLocalsProxyType`.
+ This represents the type of the :attr:`frame.f_locals` attribute,
+ as described in :pep:`667`.
+
+
unittest
--------
'AsyncGeneratorType': {'athrow'},
'CoroutineType': {'throw'},
'GeneratorType': {'throw'},
+ 'FrameLocalsProxyType': {'setdefault', 'pop', 'get'},
}
self._test_module_has_signatures(types,
unsupported_signature=unsupported_signature,
'AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType',
'CapsuleType', 'CellType', 'ClassMethodDescriptorType', 'CodeType',
'CoroutineType', 'EllipsisType', 'FrameType', 'FunctionType',
+ 'FrameLocalsProxyType',
'GeneratorType', 'GenericAlias', 'GetSetDescriptorType',
'LambdaType', 'MappingProxyType', 'MemberDescriptorType',
'MethodDescriptorType', 'MethodType', 'MethodWrapperType',
"""
assert_python_ok("-c", code)
+ def test_frame_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')
+
+ frame = inspect.currentframe()
+ self.assertIsNotNone(frame)
+ self.assertIsInstance(frame.f_locals, types.FrameLocalsProxyType)
+
class UnionTests(unittest.TestCase):
raise TypeError
except TypeError as exc:
TracebackType = type(exc.__traceback__)
- FrameType = type(exc.__traceback__.tb_frame)
+
+ _f = (lambda: sys._getframe())()
+ FrameType = type(_f)
+ FrameLocalsProxyType = type(_f.f_locals)
GetSetDescriptorType = type(FunctionType.__code__)
MemberDescriptorType = type(FunctionType.__globals__)
--- /dev/null
+Expose :pep:`667`'s :data:`~types.FrameLocalsProxyType` in the :mod:`types` module.
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);
{NULL, NULL} /* sentinel */
};
+PyDoc_STRVAR(framelocalsproxy_doc,
+"FrameLocalsProxy($frame)\n"
+"--\n"
+"\n"
+"Create a write-through view of the locals dictionary for a frame.\n"
+"\n"
+" frame\n"
+" the frame object to wrap.");
+
PyTypeObject PyFrameLocalsProxy_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
.tp_name = "FrameLocalsProxy",
.tp_alloc = PyType_GenericAlloc,
.tp_new = framelocalsproxy_new,
.tp_free = PyObject_GC_Del,
+ .tp_doc = framelocalsproxy_doc,
};
PyObject *