patch 8.2.1538: Python: iteration over vim objects fails to keep reference
Problem: Python: iteration over vim objects fails to keep reference.
Solution: Keep a reference for the object. (Paul Ollis, closes #6803,
closes #6806)
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 8eb7747..86942b6 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -1442,11 +1442,12 @@
destructorfun destruct;
traversefun traverse;
clearfun clear;
+ PyObject *iter_object;
} IterObject;
static PyObject *
IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
- clearfun clear)
+ clearfun clear, PyObject *iter_object)
{
IterObject *self;
@@ -1456,6 +1457,10 @@
self->destruct = destruct;
self->traverse = traverse;
self->clear = clear;
+ self->iter_object = iter_object;
+
+ if (iter_object)
+ Py_INCREF(iter_object);
return (PyObject *)(self);
}
@@ -1463,6 +1468,8 @@
static void
IterDestructor(IterObject *self)
{
+ if (self->iter_object)
+ Py_DECREF(self->iter_object);
PyObject_GC_UnTrack((void *)(self));
self->destruct(self->cur);
PyObject_GC_Del((void *)(self));
@@ -1844,7 +1851,7 @@
return IterNew(dii,
(destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
- NULL, NULL);
+ NULL, NULL, (PyObject *)self);
}
static PyInt
@@ -2842,7 +2849,7 @@
return IterNew(lii,
(destructorfun) ListIterDestruct, (nextfun) ListIterNext,
- NULL, NULL);
+ NULL, NULL, (PyObject *)self);
}
static char *ListAttrs[] = {
@@ -3491,7 +3498,7 @@
return IterNew(oii,
(destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
- NULL, NULL);
+ NULL, NULL, (PyObject *)self);
}
static int
@@ -5488,14 +5495,15 @@
}
static PyObject *
-BufMapIter(PyObject *self UNUSED)
+BufMapIter(PyObject *self)
{
PyObject *buffer;
buffer = BufferNew(firstbuf);
return IterNew(buffer,
(destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
- (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
+ (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear,
+ (PyObject *)self);
}
static PyMappingMethods BufMapAsMapping = {