Python weakref support for builtin wrappers and limited API

Adds weakref support to the SwigPyObject class used as a base for all
builtin wrapper types defined as heap types (the default).

However, like __dictoffset__, the __weaklistoffset__ members slot is only
available in the limited API from python-3.9 onwards.

Document the previous commit which adds the bulk of the weakref support
to builtin wrappers.
This commit is contained in:
William S Fulton 2025-07-23 22:17:03 +01:00
parent 0242c35936
commit 3438289cad
3 changed files with 10 additions and 5 deletions

View File

@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.4.0 (in progress)
===========================
2025-07-23: jim-easterbrook
[Python] #3218 Added weakref support to builtin wrappers.
2025-07-18: crusaderky
[Python] #3215 Added -nogil flag to mark modules as free-threading compatible.

View File

@ -36,6 +36,7 @@ if sys.version_info >= (3,0):
check("weakref proxy not usable", ts_ref_cb.x, 123)
# delete object
check("callback was called", callbacks, [])
del ts
check("deref'd weakref is not None", ts_ref() is None, True)
check("callback wasn't called", callbacks, [ts_ref_cb])
check("deref'd weakref is not None", ts_ref() is None, True)

View File

@ -1084,6 +1084,7 @@ SwigPyObject_TypeOnce(void) {
#else
static PyMemberDef SwigPyObject_members[] = {
{ (char *)"__dictoffset__", Py_T_PYSSIZET, offsetof(SwigPyObject, swigdict), Py_READONLY, NULL },
{ (char *)"__weaklistoffset__", Py_T_PYSSIZET, offsetof(SwigPyObject, weakreflist), Py_READONLY },
{ NULL, 0, 0, 0, NULL }
};
PyType_Slot slots[] = {
@ -1110,12 +1111,12 @@ SwigPyObject_TypeOnce(void) {
/* While this __dictoffset__ is only used with the builtin wrappers, SwigPyObject ought to be
identical when created for use by proxy class wrappers in case it is shared across multiple modules. */
#if PY_VERSION_HEX < 0x03090000
/* Workaround as __dictoffset__ above is only supported from python-3.9 */
if (pytype)
/* Workaround as __dictoffset__ and __weaklistoffset__ above are only supported from python-3.9 */
if (pytype) {
((PyTypeObject *)pytype)->tp_dictoffset = offsetof(SwigPyObject, swigdict);
#endif
if (pytype)
((PyTypeObject *)pytype)->tp_weaklistoffset = offsetof(SwigPyObject, weakreflist);
}
#endif
#endif
if (pytype && PyModule_AddObject(runtime_data_module, "SwigPyObject", pytype) == 0)
SWIG_Py_INCREF(pytype);