aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/py-event.c
diff options
context:
space:
mode:
authorMatthieu Longo <matthieu.longo@arm.com>2025-07-17 18:36:41 +0100
committerMatthieu Longo <matthieu.longo@arm.com>2026-01-29 16:46:14 +0000
commit9a84753aa7f8b8939cf4eea9c7f1db4b42e171e1 (patch)
tree027a0af3564eff86d5d6800a436d757945e91cec /gdb/python/py-event.c
parent8b0f0d5fbf8d870c433dc62ceaaf740740af9923 (diff)
downloadbinutils-9a84753aa7f8b8939cf4eea9c7f1db4b42e171e1.tar.gz
binutils-9a84753aa7f8b8939cf4eea9c7f1db4b42e171e1.tar.bz2
binutils-9a84753aa7f8b8939cf4eea9c7f1db4b42e171e1.zip
gdb: new setters and getters for __dict__, and attributes
GDB is currently using the Python unlimited API. Migrating the codebase to the Python limited API would have for benefit to make a GDB build artifacts compatible with older and newer versions of Python that they were built with. This patch prepares the ground for migrating the existing C extension types from static types to heap-allocated ones, by removing the dependency on tp_dictoffset, which is unavailable when using the limited API. One of the most common incompatibilities in the current static type declarations is the tp_dictoffset slot, which specifies the dictionary offset within the instance structure. Historically, the unlimited API has provided two approaches to supply a dictionary for __dict__: * A managed dictionary. Setting Py_TPFLAGS_MANAGED_DICT in tp_flags indicates that the instances of the type have a __dict__ attribute, and that the dictionary is managed by Python. According to the Python documentation, this is the recommended approach. However, this flag was introduced in 3.12, together with PyObject_VisitManagedDict() and PyObject_ClearManagedDict(), neither of which is part of the limited API (at least for now). As a result, this recommended approach is not viable in the context of the limited API. * An instance dictionary, for which the offset in the instance is provided via tp_dictoffset. According to the Python documentation, this "tp slot" is on the deprecation path, and Py_TPFLAGS_MANAGED_DICT should be used instead. Given the age of the GDB codebase and the requirement to support older Python versions (>= 3.4), no need to argue that today, the implementation of __dict__ relies on tp_dictoffset. However, in the context of the limited API, PyType_Slot does not provide a Py_tp_dictoffset member, so another approach is needed to provide __dict__ to instances of C extension types. Given the constraints of the limited API, the proposed solution consists in providing a dictionary through a common base class, gdbpy__dict__wrapper. This helper class owns a dictionary member corresponding to __dict__, and any C extension type requiring a __dict__ must inherit from it. Since extension object must also be convertible to PyObject, this wrapper class publicly inherits from PyObject as well. Access to the dictionary is provided via a custom getter defined in a PyGetSetDef, similarily to what was previously done with gdb_py_generic_dict(). Because __dict__ participates in attribute look-up, and since this dictionary is neither managed by Python nor exposed via tp_dictoffset, custom implementations of tp_getattro and tp_setattro are required to correctly redirect attribute look-ups to the dictionary. These custom implementations — equivalent to PyObject_GenericGetAttr() and PyObject_GenericSetAttr() — must be installed via tp_getattro / tp_setattro for static types, or Py_tp_getattro / Py_tp_setattro for heap-allocated types. - gdbpy__dict__wrapper: a base class for C extension objects that own a __dict__. - gdb_py_generic_dict_getter: a __dict__ getter for extension types derived from gdbpy__dict__wrapper. - gdb_py_generic_getattro: equivalent of PyObject_GenericGetAttr, but fixes the look-up of __dict__. - gdb_py_generic_setattro: equivalent of PyObject_GenericSetAttr, but fixes the look-up of __dict__. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830 Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/python/py-event.c')
-rw-r--r--gdb/python/py-event.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index c985159a6f7..8fb21b7fdad 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -101,8 +101,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_event);
static gdb_PyGetSetDef event_object_getset[] =
{
- { "__dict__", gdb_py_generic_dict, NULL,
- "The __dict__ for this event.", &event_object_type },
+ { "__dict__", gdb_py_generic_dict_getter, NULL,
+ "The __dict__ for this event.", NULL },
{ NULL }
};
@@ -124,8 +124,8 @@ PyTypeObject event_object_type =
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
+ gdb_py_generic_getattro, /* tp_getattro */
+ gdb_py_generic_setattro, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"GDB event object", /* tp_doc */
@@ -142,7 +142,7 @@ PyTypeObject event_object_type =
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
- offsetof (event_object, dict), /* tp_dictoffset */
+ 0, /* tp_dictoffset */
0, /* tp_init */
0 /* tp_alloc */
};