diff src/if_py_both.h @ 21977:d1a7088c6efe v8.2.1538

patch 8.2.1538: Python: iteration over vim objects fails to keep reference Commit: https://github.com/vim/vim/commit/423a85a11a9d3d658906aea715fed7fe6aa83cd8 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 29 12:57:16 2020 +0200 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 https://github.com/vim/vim/issues/6803, closes #6806)
author Bram Moolenaar <Bram@vim.org>
date Sat, 29 Aug 2020 13:00:04 +0200
parents fb3dcd8ed14d
children 0fd4d7548b07
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -1442,11 +1442,12 @@ typedef struct
     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 @@ IterNew(void *start, destructorfun destr
     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 @@ IterNew(void *start, destructorfun destr
     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 @@ DictionaryIter(DictionaryObject *self)
 
     return IterNew(dii,
 	    (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
-	    NULL, NULL);
+	    NULL, NULL, (PyObject *)self);
 }
 
     static PyInt
@@ -2842,7 +2849,7 @@ ListIter(ListObject *self)
 
     return IterNew(lii,
 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
-	    NULL, NULL);
+	    NULL, NULL, (PyObject *)self);
 }
 
 static char *ListAttrs[] = {
@@ -3491,7 +3498,7 @@ OptionsIter(OptionsObject *self)
 
     return IterNew(oii,
 	    (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
-	    NULL, NULL);
+	    NULL, NULL, (PyObject *)self);
 }
 
     static int
@@ -5488,14 +5495,15 @@ BufMapIterNext(PyObject **buffer)
 }
 
     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 = {