mirror of https://github.com/swig/swig
Python: add weakref support to builtin types
These changes add a weakreflist member to SwigPyObject, and set tp_weaklistoffset to its offset. This fixes #1792. The Py_TPFLAGS_MANAGED_WEAKREF introduced in Python 3.12 requires Py_TPFLAGS_HAVE_GC to be set as well, which it currently isn't for SwigPyObjectType. (See https://github.com/python/cpython/issues/134786).
This commit is contained in:
parent
40378d0405
commit
976205ef0d
|
@ -111,6 +111,7 @@ C_TEST_CASES += \
|
|||
li_cwstring \
|
||||
python_nondynamic \
|
||||
python_varargs_typemap \
|
||||
python_weakref \
|
||||
|
||||
MULTI_CPP_TEST_CASES += \
|
||||
import_callback \
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import weakref
|
||||
|
||||
import python_weakref
|
||||
|
||||
ts = python_weakref.TestStruct()
|
||||
ts_ref = weakref.ref(ts)
|
|
@ -0,0 +1,9 @@
|
|||
// Test if SwigPyObject derived class can be weakrefed
|
||||
|
||||
%module python_weakref
|
||||
|
||||
%inline %{
|
||||
struct TestStruct {
|
||||
int x;
|
||||
};
|
||||
%}
|
|
@ -540,6 +540,8 @@ SWIGINTERN void
|
|||
SwigPyBuiltin_destructor_closure(SwigPyWrapperFunction wrapper, const char *wrappername, PyObject *a) {
|
||||
SwigPyObject *sobj;
|
||||
sobj = (SwigPyObject *)a;
|
||||
if (sobj->weakreflist != NULL)
|
||||
PyObject_ClearWeakRefs(a);
|
||||
SWIG_Py_XDECREF(sobj->swigdict);
|
||||
if (sobj->own) {
|
||||
PyObject *o;
|
||||
|
|
|
@ -627,6 +627,7 @@ typedef struct {
|
|||
int own;
|
||||
PyObject *next;
|
||||
PyObject *swigdict;
|
||||
PyObject *weakreflist;
|
||||
} SwigPyObject;
|
||||
|
||||
|
||||
|
@ -1019,7 +1020,7 @@ SwigPyObject_TypeOnce(void) {
|
|||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
(richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
offsetof(SwigPyObject, weakreflist), /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
SwigPyObject_methods, /* tp_methods */
|
||||
|
@ -1108,6 +1109,8 @@ SwigPyObject_TypeOnce(void) {
|
|||
((PyTypeObject *)pytype)->tp_dictoffset = offsetof(SwigPyObject, swigdict);
|
||||
#endif
|
||||
#endif
|
||||
if (pytype)
|
||||
((PyTypeObject *)pytype)->tp_weaklistoffset = offsetof(SwigPyObject, weakreflist);
|
||||
if (pytype && PyModule_AddObject(runtime_data_module, "SwigPyObject", pytype) == 0)
|
||||
SWIG_Py_INCREF(pytype);
|
||||
return (PyTypeObject *)pytype;
|
||||
|
@ -1124,6 +1127,7 @@ SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
|
|||
sobj->own = own;
|
||||
sobj->next = 0;
|
||||
sobj->swigdict = 0;
|
||||
sobj->weakreflist = 0;
|
||||
if (own == SWIG_POINTER_OWN) {
|
||||
/* Obtain a reference to the Python capsule wrapping the module information, so that the
|
||||
* module information is correctly destroyed after all SWIG python objects have been freed
|
||||
|
@ -1789,11 +1793,13 @@ SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int f
|
|||
newobj->next = next_self;
|
||||
newobj = (SwigPyObject *)next_self;
|
||||
newobj->swigdict = 0;
|
||||
newobj->weakreflist = 0;
|
||||
}
|
||||
} else {
|
||||
newobj = PyObject_New(SwigPyObject, clientdata->pytype);
|
||||
if (newobj) {
|
||||
newobj->swigdict = 0;
|
||||
newobj->weakreflist = 0;
|
||||
}
|
||||
}
|
||||
if (newobj) {
|
||||
|
|
Loading…
Reference in New Issue