Patch 8.2.1538
Problem:    Python: iteration over vim objects fails to keep reference.
Solution:   Keep a reference for the object. (Paul Ollis, closes #6803,
            closes #6806)
Files:      src/if_py_both.h, src/testdir/test_python3.vim


*** ../vim-8.2.1537/src/if_py_both.h    2020-07-14 21:08:44.350001848 +0200
--- src/if_py_both.h    2020-08-29 12:54:00.708370457 +0200
***************
*** 1442,1452 ****
      destructorfun destruct;
      traversefun traverse;
      clearfun clear;
  } IterObject;
  
      static PyObject *
  IterNew(void *start, destructorfun destruct, nextfun next, traversefun 
traverse,
!       clearfun clear)
  {
      IterObject *self;
  
--- 1442,1453 ----
      destructorfun destruct;
      traversefun traverse;
      clearfun clear;
+     PyObject *iter_object;
  } IterObject;
  
      static PyObject *
  IterNew(void *start, destructorfun destruct, nextfun next, traversefun 
traverse,
!       clearfun clear, PyObject *iter_object)
  {
      IterObject *self;
  
***************
*** 1456,1461 ****
--- 1457,1466 ----
      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,1468 ****
--- 1468,1475 ----
      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,1850 ****
  
      return IterNew(dii,
            (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
!           NULL, NULL);
  }
  
      static PyInt
--- 1851,1857 ----
  
      return IterNew(dii,
            (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
!           NULL, NULL, (PyObject *)self);
  }
  
      static PyInt
***************
*** 2842,2848 ****
  
      return IterNew(lii,
            (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
!           NULL, NULL);
  }
  
  static char *ListAttrs[] = {
--- 2849,2855 ----
  
      return IterNew(lii,
            (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
!           NULL, NULL, (PyObject *)self);
  }
  
  static char *ListAttrs[] = {
***************
*** 3491,3497 ****
  
      return IterNew(oii,
            (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
!           NULL, NULL);
  }
  
      static int
--- 3498,3504 ----
  
      return IterNew(oii,
            (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
!           NULL, NULL, (PyObject *)self);
  }
  
      static int
***************
*** 5488,5501 ****
  }
  
      static PyObject *
! BufMapIter(PyObject *self UNUSED)
  {
      PyObject *buffer;
  
      buffer = BufferNew(firstbuf);
      return IterNew(buffer,
            (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
!           (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
  }
  
  static PyMappingMethods BufMapAsMapping = {
--- 5495,5509 ----
  }
  
      static PyObject *
! BufMapIter(PyObject *self)
  {
      PyObject *buffer;
  
      buffer = BufferNew(firstbuf);
      return IterNew(buffer,
            (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
!           (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear,
!           (PyObject *)self);
  }
  
  static PyMappingMethods BufMapAsMapping = {
*** ../vim-8.2.1537/src/testdir/test_python3.vim        2020-07-11 
22:14:54.314422214 +0200
--- src/testdir/test_python3.vim        2020-08-29 12:54:00.712370444 +0200
***************
*** 4,9 ****
--- 4,18 ----
  CheckFeature python3
  source shared.vim
  
+ func Create_vim_list()
+   return [1]
+ endfunction
+ 
+ func Create_vim_dict()
+   return {'a': 1}
+ endfunction
+ 
+ 
  " This function should be called first. This sets up python functions used by
  " the other tests.
  func Test_AAA_python3_setup()
***************
*** 3944,3947 ****
--- 3953,3999 ----
    close!
  endfunc
  
+ " Regression: Iterator for a Vim object should hold a reference.
+ func Test_python3_iter_ref()
+   let g:list_iter_ref_count_increase = -1
+   let g:dict_iter_ref_count_increase = -1
+   let g:bufmap_iter_ref_count_increase = -1
+   let g:options_iter_ref_count_increase = -1
+ 
+   py3 << trim EOF
+     import sys
+     import vim
+ 
+     def test_python3_iter_ref():
+       create_list = vim.Function('Create_vim_list')
+       v = create_list()
+       base_ref_count = sys.getrefcount(v)
+       for el in v:
+           vim.vars['list_iter_ref_count_increase'] = sys.getrefcount(v) - 
base_ref_count
+ 
+       create_dict = vim.Function('Create_vim_dict')
+       v = create_dict()
+       base_ref_count = sys.getrefcount(v)
+       for el in v:
+           vim.vars['dict_iter_ref_count_increase'] = sys.getrefcount(v) - 
base_ref_count
+ 
+       v = vim.buffers
+       base_ref_count = sys.getrefcount(v)
+       for el in v:
+           vim.vars['bufmap_iter_ref_count_increase'] = sys.getrefcount(v) - 
base_ref_count
+ 
+       v = vim.options
+       base_ref_count = sys.getrefcount(v)
+       for el in v:
+           vim.vars['options_iter_ref_count_increase'] = sys.getrefcount(v) - 
base_ref_count
+ 
+     test_python3_iter_ref()
+   EOF
+ 
+   call assert_equal(1, g:list_iter_ref_count_increase)
+   call assert_equal(1, g:dict_iter_ref_count_increase)
+   call assert_equal(1, g:bufmap_iter_ref_count_increase)
+   call assert_equal(1, g:options_iter_ref_count_increase)
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.1537/src/version.c       2020-08-28 23:27:16.932923997 +0200
--- src/version.c       2020-08-29 12:56:15.951977902 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1538,
  /**/

-- 
GALAHAD: No. Look, I can tackle this lot single-handed!
GIRLS:   Yes, yes, let him Tackle us single-handed!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202008291057.07TAvp6D2502812%40masaka.moolenaar.net.

Raspunde prin e-mail lui