gh-136492: Add FrameLocalsProxyType to types (GH-136546)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
This commit is contained in:
@@ -333,6 +333,16 @@ Standard names are defined for the following types:
|
|||||||
:attr:`tb.tb_frame <traceback.tb_frame>` if ``tb`` is a traceback object.
|
: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
|
.. data:: GetSetDescriptorType
|
||||||
|
|
||||||
The type of objects defined in extension modules with ``PyGetSetDef``, such
|
The type of objects defined in extension modules with ``PyGetSetDef``, such
|
||||||
|
|||||||
@@ -312,6 +312,15 @@ tarfile
|
|||||||
and :cve:`2025-4435`.)
|
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
|
unittest
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -5786,6 +5786,7 @@ class TestSignatureDefinitions(unittest.TestCase):
|
|||||||
'AsyncGeneratorType': {'athrow'},
|
'AsyncGeneratorType': {'athrow'},
|
||||||
'CoroutineType': {'throw'},
|
'CoroutineType': {'throw'},
|
||||||
'GeneratorType': {'throw'},
|
'GeneratorType': {'throw'},
|
||||||
|
'FrameLocalsProxyType': {'setdefault', 'pop', 'get'},
|
||||||
}
|
}
|
||||||
self._test_module_has_signatures(types,
|
self._test_module_has_signatures(types,
|
||||||
unsupported_signature=unsupported_signature,
|
unsupported_signature=unsupported_signature,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class TypesTests(unittest.TestCase):
|
|||||||
'AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType',
|
'AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType',
|
||||||
'CapsuleType', 'CellType', 'ClassMethodDescriptorType', 'CodeType',
|
'CapsuleType', 'CellType', 'ClassMethodDescriptorType', 'CodeType',
|
||||||
'CoroutineType', 'EllipsisType', 'FrameType', 'FunctionType',
|
'CoroutineType', 'EllipsisType', 'FrameType', 'FunctionType',
|
||||||
|
'FrameLocalsProxyType',
|
||||||
'GeneratorType', 'GenericAlias', 'GetSetDescriptorType',
|
'GeneratorType', 'GenericAlias', 'GetSetDescriptorType',
|
||||||
'LambdaType', 'MappingProxyType', 'MemberDescriptorType',
|
'LambdaType', 'MappingProxyType', 'MemberDescriptorType',
|
||||||
'MethodDescriptorType', 'MethodType', 'MethodWrapperType',
|
'MethodDescriptorType', 'MethodType', 'MethodWrapperType',
|
||||||
@@ -711,6 +712,16 @@ class TypesTests(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
assert_python_ok("-c", code)
|
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):
|
class UnionTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ except ImportError:
|
|||||||
raise TypeError
|
raise TypeError
|
||||||
except TypeError as exc:
|
except TypeError as exc:
|
||||||
TracebackType = type(exc.__traceback__)
|
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__)
|
GetSetDescriptorType = type(FunctionType.__code__)
|
||||||
MemberDescriptorType = type(FunctionType.__globals__)
|
MemberDescriptorType = type(FunctionType.__globals__)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Expose :pep:`667`'s :data:`~types.FrameLocalsProxyType` in the :mod:`types` module.
|
||||||
@@ -28,6 +28,7 @@ _types_exec(PyObject *m)
|
|||||||
EXPORT_STATIC_TYPE("CoroutineType", PyCoro_Type);
|
EXPORT_STATIC_TYPE("CoroutineType", PyCoro_Type);
|
||||||
EXPORT_STATIC_TYPE("EllipsisType", PyEllipsis_Type);
|
EXPORT_STATIC_TYPE("EllipsisType", PyEllipsis_Type);
|
||||||
EXPORT_STATIC_TYPE("FrameType", PyFrame_Type);
|
EXPORT_STATIC_TYPE("FrameType", PyFrame_Type);
|
||||||
|
EXPORT_STATIC_TYPE("FrameLocalsProxyType", PyFrameLocalsProxy_Type);
|
||||||
EXPORT_STATIC_TYPE("FunctionType", PyFunction_Type);
|
EXPORT_STATIC_TYPE("FunctionType", PyFunction_Type);
|
||||||
EXPORT_STATIC_TYPE("GeneratorType", PyGen_Type);
|
EXPORT_STATIC_TYPE("GeneratorType", PyGen_Type);
|
||||||
EXPORT_STATIC_TYPE("GenericAlias", Py_GenericAliasType);
|
EXPORT_STATIC_TYPE("GenericAlias", Py_GenericAliasType);
|
||||||
|
|||||||
@@ -913,6 +913,15 @@ static PyMethodDef framelocalsproxy_methods[] = {
|
|||||||
{NULL, NULL} /* sentinel */
|
{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 = {
|
PyTypeObject PyFrameLocalsProxy_Type = {
|
||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
.tp_name = "FrameLocalsProxy",
|
.tp_name = "FrameLocalsProxy",
|
||||||
@@ -933,6 +942,7 @@ PyTypeObject PyFrameLocalsProxy_Type = {
|
|||||||
.tp_alloc = PyType_GenericAlloc,
|
.tp_alloc = PyType_GenericAlloc,
|
||||||
.tp_new = framelocalsproxy_new,
|
.tp_new = framelocalsproxy_new,
|
||||||
.tp_free = PyObject_GC_Del,
|
.tp_free = PyObject_GC_Del,
|
||||||
|
.tp_doc = framelocalsproxy_doc,
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
|||||||
Reference in New Issue
Block a user