Blob Blame History Raw
To: vim_dev@googlegroups.com
Subject: Patch 7.3.569
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.3.569
Problem:    Evaluating Vim expression in Python is insufficient.
Solution:   Add vim.bindeval().  Also add pyeval() and py3eval(). (ZyX)
Files:	    runtime/doc/eval.txt, runtime/doc/if_pyth.txt, src/eval.c,
	    src/if_lua.c, src/if_py_both.h, src/if_python.c, src/if_python3.c,
	    src/proto/eval.pro, src/proto/if_python.pro,
	    src/proto/if_python3.pro, src/testdir/Make_amiga.mak,
	    src/testdir/Make_dos.mak, src/testdir/Make_ming.mak,
	    src/testdir/Make_os2.mak, src/testdir/Makefile,
	    src/testdir/test86.in, src/testdir/test86.ok,
	    src/testdir/test87.in, src/testdir/test87.ok


*** ../vim-7.3.568/runtime/doc/eval.txt	2012-03-07 19:16:49.000000000 +0100
--- runtime/doc/eval.txt	2012-06-20 18:01:02.000000000 +0200
***************
*** 1836,1844 ****
  localtime()			Number	current time
  log( {expr})			Float	natural logarithm (base e) of {expr}
  log10( {expr})			Float	logarithm of Float {expr} to base 10
  map( {expr}, {string})		List/Dict  change each item in {expr} to {expr}
  maparg( {name}[, {mode} [, {abbr} [, {dict}]]])
! 				String	rhs of mapping {name} in mode {mode}
  mapcheck( {name}[, {mode} [, {abbr}]])
  				String	check for mappings matching {name}
  match( {expr}, {pat}[, {start}[, {count}]])
--- 1847,1857 ----
  localtime()			Number	current time
  log( {expr})			Float	natural logarithm (base e) of {expr}
  log10( {expr})			Float	logarithm of Float {expr} to base 10
+ luaeval( {expr}[, {expr}])	any	evaluate |Lua| expression
  map( {expr}, {string})		List/Dict  change each item in {expr} to {expr}
  maparg( {name}[, {mode} [, {abbr} [, {dict}]]])
! 				String or Dict
! 					rhs of mapping {name} in mode {mode}
  mapcheck( {name}[, {mode} [, {abbr}]])
  				String	check for mappings matching {name}
  match( {expr}, {pat}[, {start}[, {count}]])
***************
*** 1867,1872 ****
--- 1880,1887 ----
  prevnonblank( {lnum})		Number	line nr of non-blank line <= {lnum}
  printf( {fmt}, {expr1}...)	String	format text
  pumvisible()			Number	whether popup menu is visible
+ pyeval( {expr})			any	evaluate |Python| expression
+ py3eval( {expr})		any	evaluate |python3| expression
  range( {expr} [, {max} [, {stride}]])
  				List	items from {expr} to {max}
  readfile( {fname} [, {binary} [, {max}]])
***************
*** 3980,3985 ****
--- 4003,4022 ----
  <			-2.0
  		{only available when compiled with the |+float| feature}
  		
+ luaeval({expr}[, {expr}])					*luaeval()*
+ 		Evaluate Lua expression {expr} and return its result converted 
+ 		to Vim data structures. Second {expr} may hold additional 
+ 		argument accessible as _A inside first {expr}.
+ 		Strings are returned as they are.
+ 		Boolean objects are converted to numbers.
+ 		Numbers are converted to |Float| values if vim was compiled 
+ 		with |+float| and to numbers otherwise.
+ 		Dictionaries and lists obtained by vim.eval() are returned 
+ 		as-is.
+ 		Other objects are returned as zero without any errors.
+ 		See |lua-luaeval| for more details.
+ 		{only available when compiled with the |+lua| feature}
+ 
  map({expr}, {string})					*map()*
  		{expr} must be a |List| or a |Dictionary|.
  		Replace each item in {expr} with the result of evaluating
***************
*** 4574,4579 ****
--- 4612,4640 ----
  		This can be used to avoid some things that would remove the
  		popup menu.
  
+ 							*E860* *E861*
+ py3eval({expr})						*py3eval()*
+ 		Evaluate Python expression {expr} and return its result
+ 		converted to Vim data structures.
+ 		Numbers and strings are returned as they are (strings are 
+ 		copied though, unicode strings are additionally converted to 
+ 		'encoding').
+ 		Lists are represented as Vim |List| type.
+ 		Dictionaries are represented as Vim |Dictionary| type with 
+ 		keys converted to strings.
+ 		{only available when compiled with the |+python3| feature}
+ 
+ 							*E858* *E859*
+ pyeval({expr})						*pyeval()*
+ 		Evaluate Python expression {expr} and return its result
+ 		converted to Vim data structures.
+ 		Numbers and strings are returned as they are (strings are 
+ 		copied though).
+ 		Lists are represented as Vim |List| type.
+ 		Dictionaries are represented as Vim |Dictionary| type with 
+ 		keys converted to strings.
+ 		{only available when compiled with the |+python| feature}
+ 
  							*E726* *E727*
  range({expr} [, {max} [, {stride}]])				*range()*
  		Returns a |List| with Numbers:
***************
*** 4807,4812 ****
--- 4868,4877 ----
  		Search for regexp pattern {pattern}.  The search starts at the
  		cursor position (you can use |cursor()| to set it).
  
+ 		If there is no match a 0 is returned and the cursor doesn't
+ 		move.  No error message is given.
+ 		When a match has been found its line number is returned.
+ 
  		{flags} is a String, which can contain these character flags:
  		'b'	search backward instead of forward
  		'c'	accept a match at the cursor position
*** ../vim-7.3.568/runtime/doc/if_pyth.txt	2010-08-15 21:57:12.000000000 +0200
--- runtime/doc/if_pyth.txt	2012-06-20 18:01:02.000000000 +0200
***************
*** 1,4 ****
! *if_pyth.txt*   For Vim version 7.3.  Last change: 2010 Aug 13
  
  
  		  VIM REFERENCE MANUAL    by Paul Moore
--- 1,4 ----
! *if_pyth.txt*   For Vim version 7.3.  Last change: 2012 Feb 04
  
  
  		  VIM REFERENCE MANUAL    by Paul Moore
***************
*** 6,18 ****
  
  The Python Interface to Vim				*python* *Python*
  
! 1. Commands			|python-commands|
! 2. The vim module		|python-vim|
! 3. Buffer objects		|python-buffer|
! 4. Range objects		|python-range|
! 5. Window objects		|python-window|
! 6. Dynamic loading		|python-dynamic|
! 7. Python 3			|python3|
  
  {Vi does not have any of these commands}
  
--- 6,19 ----
  
  The Python Interface to Vim				*python* *Python*
  
! 1. Commands					|python-commands|
! 2. The vim module				|python-vim|
! 3. Buffer objects				|python-buffer|
! 4. Range objects				|python-range|
! 5. Window objects				|python-window|
! 6. pyeval(), py3eval() Vim functions		|python-pyeval|
! 7. Dynamic loading				|python-dynamic|
! 8. Python 3					|python3|
  
  {Vi does not have any of these commands}
  
***************
*** 150,155 ****
--- 151,172 ----
  	[{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name':
  	'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}]
  
+ vim.bindeval(str)					*python-bindeval*
+ 	Like |python-eval|, but
+ 	1. if expression evaluates to |List| or |Dictionary| it is returned as 
+ 	   vimlist or vimdictionary python type that are connected to original 
+ 	   list or dictionary. Thus modifications to these objects imply 
+ 	   modifications of the original.
+ 	2. if expression evaluates to a function reference, then it returns 
+ 	   callable vimfunction object. Use self keyword argument to assign 
+ 	   |self| object for dictionary functions.
+ 
+ 	Note: this function has the same behavior as |lua-eval| (except that 
+ 	      lua does not support running vim functions), |python-eval| is 
+ 	      kept for backwards compatibility in order not to make scripts 
+ 	      relying on outputs of vim.eval() being a copy of original or 
+ 	      vim.eval("1") returning a string.
+ 
  
  
  Error object of the "vim" module
***************
*** 222,229 ****
  	- from indexing vim.buffers (|python-buffers|)
  	- from the "buffer" attribute of a window (|python-window|)
  
! Buffer objects have one read-only attribute - name - the full file name for
! the buffer.  They also have three methods (append, mark, and range; see below).
  
  You can also treat buffer objects as sequence objects.  In this context, they
  act as if they were lists (yes, they are mutable) of strings, with each
--- 239,247 ----
  	- from indexing vim.buffers (|python-buffers|)
  	- from the "buffer" attribute of a window (|python-window|)
  
! Buffer objects have two read-only attributes - name - the full file name for
! the buffer, and number - the buffer number.  They also have three methods
! (append, mark, and range; see below).
  
  You can also treat buffer objects as sequence objects.  In this context, they
  act as if they were lists (yes, they are mutable) of strings, with each
***************
*** 318,324 ****
  The width attribute is writable only if the screen is split vertically.
  
  ==============================================================================
! 6. Dynamic loading					*python-dynamic*
  
  On MS-Windows the Python library can be loaded dynamically.  The |:version|
  output then includes |+python/dyn|.
--- 336,348 ----
  The width attribute is writable only if the screen is split vertically.
  
  ==============================================================================
! 6. pyeval() and py3eval() Vim functions			*python-pyeval*
! 
! To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()| 
! functions to evaluate Python expressions and pass their values to VimL.
! 
! ==============================================================================
! 7. Dynamic loading					*python-dynamic*
  
  On MS-Windows the Python library can be loaded dynamically.  The |:version|
  output then includes |+python/dyn|.
***************
*** 335,347 ****
  sure edit "gvim.exe" and search for "python\d*.dll\c".
  
  ==============================================================================
! 7. Python 3						*python3*
  
  							*:py3* *:python3*
  The |:py3| and |:python3| commands work similar to |:python|.
  							*:py3file*
  The |:py3file| command works similar to |:pyfile|.
  
  Vim can be built in four ways (:version output):
  1. No Python support	    (-python, -python3)
  2. Python 2 support only    (+python or +python/dyn, -python3)
--- 359,372 ----
  sure edit "gvim.exe" and search for "python\d*.dll\c".
  
  ==============================================================================
! 8. Python 3						*python3*
  
  							*:py3* *:python3*
  The |:py3| and |:python3| commands work similar to |:python|.
  							*:py3file*
  The |:py3file| command works similar to |:pyfile|.
  
+ 
  Vim can be built in four ways (:version output):
  1. No Python support	    (-python, -python3)
  2. Python 2 support only    (+python or +python/dyn, -python3)
***************
*** 355,361 ****
  When doing this on Linux/Unix systems and importing global symbols, this leads
  to a crash when the second Python version is used.  So either global symbols
  are loaded but only one Python version is activated, or no global symbols are
! loaded. The latter makes Python's "import" fail on libaries that expect the
  symbols to be provided by Vim.
  							*E836* *E837*
  Vim's configuration script makes a guess for all libraries based on one
--- 380,386 ----
  When doing this on Linux/Unix systems and importing global symbols, this leads
  to a crash when the second Python version is used.  So either global symbols
  are loaded but only one Python version is activated, or no global symbols are
! loaded. The latter makes Python's "import" fail on libraries that expect the
  symbols to be provided by Vim.
  							*E836* *E837*
  Vim's configuration script makes a guess for all libraries based on one
***************
*** 377,382 ****
--- 402,419 ----
  3. You undefine PY_NO_RTLD_GLOBAL in auto/config.h after configuration.  This
     may crash Vim though.
  
+ 							*has-python*
+ You can test what Python version is available with: >
+ 	if has('python')
+ 	  echo 'there is Python 2.x'
+   	elseif has('python3')
+ 	  echo 'there is Python 3.x'
+ 	endif
+ 
+ Note however, that when Python 2 and 3 are both available and loaded
+ dynamically, these has() calls will try to load them.  If only one can be
+ loaded at a time, just checking if Python 2 or 3 are available will prevent
+ the other one from being available.
  
  ==============================================================================
   vim:tw=78:ts=8:ft=help:norl:
*** ../vim-7.3.568/src/eval.c	2012-06-20 14:13:02.000000000 +0200
--- src/eval.c	2012-06-20 18:29:15.000000000 +0200
***************
*** 424,453 ****
  static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
  static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
  static int rettv_list_alloc __ARGS((typval_T *rettv));
- static listitem_T *listitem_alloc __ARGS((void));
  static void listitem_free __ARGS((listitem_T *item));
- static void listitem_remove __ARGS((list_T *l, listitem_T *item));
  static long list_len __ARGS((list_T *l));
  static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
  static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
  static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic, int recursive));
- static listitem_T *list_find __ARGS((list_T *l, long n));
  static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
  static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
- static void list_append __ARGS((list_T *l, listitem_T *item));
  static int list_append_number __ARGS((list_T *l, varnumber_T n));
- static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
  static int list_extend __ARGS((list_T	*l1, list_T *l2, listitem_T *bef));
  static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
  static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
- static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
  static char_u *list2string __ARGS((typval_T *tv, int copyID));
  static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap));
  static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
  static int free_unref_items __ARGS((int copyID));
- static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
- static void set_ref_in_list __ARGS((list_T *l, int copyID));
- static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
  static int rettv_dict_alloc __ARGS((typval_T *rettv));
  static void dict_free __ARGS((dict_T *d, int recurse));
  static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
--- 424,444 ----
***************
*** 654,659 ****
--- 645,656 ----
  static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_printf __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv));
+ #ifdef FEAT_PYTHON3
+ static void f_py3eval __ARGS((typval_T *argvars, typval_T *rettv));
+ #endif
+ #ifdef FEAT_PYTHON
+ static void f_pyeval __ARGS((typval_T *argvars, typval_T *rettv));
+ #endif
  static void f_range __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 824,831 ****
  static char_u *autoload_name __ARGS((char_u *name));
  static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
  static void func_free __ARGS((ufunc_T *fp));
- static void func_unref __ARGS((char_u *name));
- static void func_ref __ARGS((char_u *name));
  static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict));
  static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
  static void free_funccal __ARGS((funccall_T *fc, int free_val));
--- 821,826 ----
***************
*** 5927,5933 ****
  /*
   * Allocate a list item.
   */
!     static listitem_T *
  listitem_alloc()
  {
      return (listitem_T *)alloc(sizeof(listitem_T));
--- 5922,5928 ----
  /*
   * Allocate a list item.
   */
!     listitem_T *
  listitem_alloc()
  {
      return (listitem_T *)alloc(sizeof(listitem_T));
***************
*** 5947,5953 ****
  /*
   * Remove a list item from a List and free it.  Also clears the value.
   */
!     static void
  listitem_remove(l, item)
      list_T  *l;
      listitem_T *item;
--- 5942,5948 ----
  /*
   * Remove a list item from a List and free it.  Also clears the value.
   */
!     void
  listitem_remove(l, item)
      list_T  *l;
      listitem_T *item;
***************
*** 6123,6129 ****
   * A negative index is counted from the end; -1 is the last item.
   * Returns NULL when "n" is out of range.
   */
!     static listitem_T *
  list_find(l, n)
      list_T	*l;
      long	n;
--- 6118,6124 ----
   * A negative index is counted from the end; -1 is the last item.
   * Returns NULL when "n" is out of range.
   */
!     listitem_T *
  list_find(l, n)
      list_T	*l;
      long	n;
***************
*** 6265,6271 ****
  /*
   * Append item "item" to the end of list "l".
   */
!     static void
  list_append(l, item)
      list_T	*l;
      listitem_T	*item;
--- 6260,6266 ----
  /*
   * Append item "item" to the end of list "l".
   */
!     void
  list_append(l, item)
      list_T	*l;
      listitem_T	*item;
***************
*** 6378,6384 ****
   * If "item" is NULL append at the end.
   * Return FAIL when out of memory.
   */
!     static int
  list_insert_tv(l, tv, item)
      list_T	*l;
      typval_T	*tv;
--- 6373,6379 ----
   * If "item" is NULL append at the end.
   * Return FAIL when out of memory.
   */
!     int
  list_insert_tv(l, tv, item)
      list_T	*l;
      typval_T	*tv;
***************
*** 6523,6529 ****
   * Remove items "item" to "item2" from list "l".
   * Does not free the listitem or the value!
   */
!     static void
  list_remove(l, item, item2)
      list_T	*l;
      listitem_T	*item;
--- 6518,6524 ----
   * Remove items "item" to "item2" from list "l".
   * Does not free the listitem or the value!
   */
!     void
  list_remove(l, item, item2)
      list_T	*l;
      listitem_T	*item;
***************
*** 6785,6790 ****
--- 6780,6793 ----
      set_ref_in_lua(copyID);
  #endif
  
+ #ifdef FEAT_PYTHON
+     set_ref_in_python(copyID);
+ #endif
+ 
+ #ifdef FEAT_PYTHON3
+     set_ref_in_python3(copyID);
+ #endif
+ 
      /*
       * 2. Free lists and dictionaries that are not referenced.
       */
***************
*** 6870,6876 ****
  /*
   * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
   */
!     static void
  set_ref_in_ht(ht, copyID)
      hashtab_T	*ht;
      int		copyID;
--- 6873,6879 ----
  /*
   * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
   */
!     void
  set_ref_in_ht(ht, copyID)
      hashtab_T	*ht;
      int		copyID;
***************
*** 6890,6896 ****
  /*
   * Mark all lists and dicts referenced through list "l" with "copyID".
   */
!     static void
  set_ref_in_list(l, copyID)
      list_T	*l;
      int		copyID;
--- 6893,6899 ----
  /*
   * Mark all lists and dicts referenced through list "l" with "copyID".
   */
!     void
  set_ref_in_list(l, copyID)
      list_T	*l;
      int		copyID;
***************
*** 6904,6910 ****
  /*
   * Mark all lists and dicts referenced through typval "tv" with "copyID".
   */
!     static void
  set_ref_in_item(tv, copyID)
      typval_T	*tv;
      int		copyID;
--- 6907,6913 ----
  /*
   * Mark all lists and dicts referenced through typval "tv" with "copyID".
   */
!     void
  set_ref_in_item(tv, copyID)
      typval_T	*tv;
      int		copyID;
***************
*** 7986,7991 ****
--- 7989,8000 ----
      {"prevnonblank",	1, 1, f_prevnonblank},
      {"printf",		2, 19, f_printf},
      {"pumvisible",	0, 0, f_pumvisible},
+ #ifdef FEAT_PYTHON3
+     {"py3eval",		1, 1, f_py3eval},
+ #endif
+ #ifdef FEAT_PYTHON
+     {"pyeval",		1, 1, f_pyeval},
+ #endif
      {"range",		1, 3, f_range},
      {"readfile",	1, 3, f_readfile},
      {"reltime",		0, 2, f_reltime},
***************
*** 9150,9155 ****
--- 9159,9203 ----
  #endif
  }
  
+     int
+ func_call(name, args, selfdict, rettv)
+     char_u	*name;
+     typval_T	*args;
+     dict_T	*selfdict;
+     typval_T	*rettv;
+ {
+     listitem_T	*item;
+     typval_T	argv[MAX_FUNC_ARGS + 1];
+     int		argc = 0;
+     int		dummy;
+     int		r = 0;
+ 
+     for (item = args->vval.v_list->lv_first; item != NULL;
+ 							 item = item->li_next)
+     {
+ 	if (argc == MAX_FUNC_ARGS)
+ 	{
+ 	    EMSG(_("E699: Too many arguments"));
+ 	    break;
+ 	}
+ 	/* Make a copy of each argument.  This is needed to be able to set
+ 	 * v_lock to VAR_FIXED in the copy without changing the original list.
+ 	 */
+ 	copy_tv(&item->li_tv, &argv[argc++]);
+     }
+ 
+     if (item == NULL)
+ 	r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
+ 				 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ 						      &dummy, TRUE, selfdict);
+ 
+     /* Free the arguments. */
+     while (argc > 0)
+ 	clear_tv(&argv[--argc]);
+ 
+     return r;
+ }
+ 
  /*
   * "call(func, arglist)" function
   */
***************
*** 9159,9168 ****
      typval_T	*rettv;
  {
      char_u	*func;
-     typval_T	argv[MAX_FUNC_ARGS + 1];
-     int		argc = 0;
-     listitem_T	*item;
-     int		dummy;
      dict_T	*selfdict = NULL;
  
      if (argvars[1].v_type != VAR_LIST)
--- 9207,9212 ----
***************
*** 9190,9217 ****
  	selfdict = argvars[2].vval.v_dict;
      }
  
!     for (item = argvars[1].vval.v_list->lv_first; item != NULL;
! 							 item = item->li_next)
!     {
! 	if (argc == MAX_FUNC_ARGS)
! 	{
! 	    EMSG(_("E699: Too many arguments"));
! 	    break;
! 	}
! 	/* Make a copy of each argument.  This is needed to be able to set
! 	 * v_lock to VAR_FIXED in the copy without changing the original list.
! 	 */
! 	copy_tv(&item->li_tv, &argv[argc++]);
!     }
! 
!     if (item == NULL)
! 	(void)call_func(func, (int)STRLEN(func), rettv, argc, argv,
! 				 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
! 						      &dummy, TRUE, selfdict);
! 
!     /* Free the arguments. */
!     while (argc > 0)
! 	clear_tv(&argv[--argc]);
  }
  
  #ifdef FEAT_FLOAT
--- 9234,9240 ----
  	selfdict = argvars[2].vval.v_dict;
      }
  
!     (void)func_call(func, &argvars[1], selfdict, rettv);
  }
  
  #ifdef FEAT_FLOAT
***************
*** 14424,14429 ****
--- 14447,14486 ----
  #endif
  }
  
+ #ifdef FEAT_PYTHON3
+ /*
+  * "py3eval()" function
+  */
+     static void
+ f_py3eval(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     char_u	*str;
+     char_u	buf[NUMBUFLEN];
+ 
+     str = get_tv_string_buf(&argvars[0], buf);
+     do_py3eval(str, rettv);
+ }
+ #endif
+ 
+ #ifdef FEAT_PYTHON
+ /*
+  * "pyeval()" function
+  */
+     static void
+ f_pyeval(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     char_u	*str;
+     char_u	buf[NUMBUFLEN];
+ 
+     str = get_tv_string_buf(&argvars[0], buf);
+     do_pyeval(str, rettv);
+ }
+ #endif
+ 
  /*
   * "range()" function
   */
***************
*** 22139,22145 ****
   * Unreference a Function: decrement the reference count and free it when it
   * becomes zero.  Only for numbered functions.
   */
!     static void
  func_unref(name)
      char_u	*name;
  {
--- 22196,22202 ----
   * Unreference a Function: decrement the reference count and free it when it
   * becomes zero.  Only for numbered functions.
   */
!     void
  func_unref(name)
      char_u	*name;
  {
***************
*** 22163,22169 ****
  /*
   * Count a reference to a Function.
   */
!     static void
  func_ref(name)
      char_u	*name;
  {
--- 22220,22226 ----
  /*
   * Count a reference to a Function.
   */
!     void
  func_ref(name)
      char_u	*name;
  {
*** ../vim-7.3.568/src/if_lua.c	2012-04-06 14:30:55.000000000 +0200
--- src/if_lua.c	2012-06-20 18:16:33.000000000 +0200
***************
*** 199,207 ****
  lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
  lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
  void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
!         lua_CFunction k);
  int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
!         int ctx, lua_CFunction k);
  void (*dll_lua_getglobal) (lua_State *L, const char *var);
  void (*dll_lua_setglobal) (lua_State *L, const char *var);
  #endif
--- 199,207 ----
  lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
  lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
  void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
! 	lua_CFunction k);
  int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
! 	int ctx, lua_CFunction k);
  void (*dll_lua_getglobal) (lua_State *L, const char *var);
  void (*dll_lua_setglobal) (lua_State *L, const char *var);
  #endif
***************
*** 394,400 ****
  luaL_typeerror (lua_State *L, int narg, const char *tname)
  {
      const char *msg = lua_pushfstring(L, "%s expected, got %s",
!             tname, luaL_typename(L, narg));
      return luaL_argerror(L, narg, msg);
  }
  #endif
--- 394,400 ----
  luaL_typeerror (lua_State *L, int narg, const char *tname)
  {
      const char *msg = lua_pushfstring(L, "%s expected, got %s",
! 	    tname, luaL_typename(L, narg));
      return luaL_argerror(L, narg, msg);
  }
  #endif
***************
*** 646,786 ****
  	return 1; \
      }
  
- 
- /* adapted from eval.c */
- 
- #define listitem_alloc() (listitem_T *)alloc(sizeof(listitem_T))
- 
-     static listitem_T *
- list_find (list_T *l, long n)
- {
-     listitem_T *li;
-     if (l == NULL || n < -l->lv_len || n >= l->lv_len)
- 	return NULL;
-     if (n < 0) /* search backward? */
- 	for (li = l->lv_last; n < -1; li = li->li_prev)
- 	    n++;
-     else /* search forward */
- 	for (li = l->lv_first; n > 0; li = li->li_next)
- 	    n--;
-     return li;
- }
- 
-     static void
- list_remove (list_T *l, listitem_T *li)
- {
-     listwatch_T *lw;
-     --l->lv_len;
-     /* fix watchers */
-     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
- 	if (lw->lw_item == li)
- 	    lw->lw_item = li->li_next;
-     /* fix list pointers */
-     if (li->li_next == NULL) /* last? */
- 	l->lv_last = li->li_prev;
-     else
- 	li->li_next->li_prev = li->li_prev;
-     if (li->li_prev == NULL) /* first? */
- 	l->lv_first = li->li_next;
-     else
- 	li->li_prev->li_next = li->li_next;
-     l->lv_idx_item = NULL;
- }
- 
-     static void
- list_append(list_T *l, listitem_T *item)
- {
-     if (l->lv_last == NULL) /* empty list? */
- 	l->lv_first = item;
-     else
- 	l->lv_last->li_next = item;
-     item->li_prev = l->lv_last;
-     item->li_next = NULL;
-     l->lv_last = item;
-     ++l->lv_len;
- }
- 
-     static int
- list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
- {
-     listitem_T	*ni = listitem_alloc();
- 
-     if (ni == NULL)
- 	return FAIL;
-     copy_tv(tv, &ni->li_tv);
-     if (item == NULL)
- 	list_append(l, ni);
-     else
-     {
- 	ni->li_prev = item->li_prev;
- 	ni->li_next = item;
- 	if (item->li_prev == NULL)
- 	{
- 	    l->lv_first = ni;
- 	    ++l->lv_idx;
- 	}
- 	else
- 	{
- 	    item->li_prev->li_next = ni;
- 	    l->lv_idx_item = NULL;
- 	}
- 	item->li_prev = ni;
- 	++l->lv_len;
-     }
-     return OK;
- }
- 
- /* set references */
- 
- static void set_ref_in_tv (typval_T *tv, int copyID);
- 
-     static void
- set_ref_in_dict(dict_T *d, int copyID)
- {
-     hashtab_T *ht = &d->dv_hashtab;
-     int n = ht->ht_used;
-     hashitem_T *hi;
-     for (hi = ht->ht_array; n > 0; ++hi)
- 	if (!HASHITEM_EMPTY(hi))
- 	{
- 	    dictitem_T *di = dict_lookup(hi);
- 	    set_ref_in_tv(&di->di_tv, copyID);
- 	    --n;
- 	}
- }
- 
-     static void
- set_ref_in_list(list_T *l, int copyID)
- {
-     listitem_T *li;
-     for (li = l->lv_first; li != NULL; li = li->li_next)
- 	set_ref_in_tv(&li->li_tv, copyID);
- }
- 
-     static void
- set_ref_in_tv(typval_T *tv, int copyID)
- {
-     if (tv->v_type == VAR_LIST)
-     {
- 	list_T *l = tv->vval.v_list;
- 	if (l != NULL && l->lv_copyID != copyID)
- 	{
- 	    l->lv_copyID = copyID;
- 	    set_ref_in_list(l, copyID);
- 	}
-     }
-     else if (tv->v_type == VAR_DICT)
-     {
- 	dict_T *d = tv->vval.v_dict;
- 	if (d != NULL && d->dv_copyID != copyID)
- 	{
- 	    d->dv_copyID = copyID;
- 	    set_ref_in_dict(d, copyID);
- 	}
-     }
- }
- 
- 
  /* =======   List type   ======= */
  
      static luaV_List *
--- 646,651 ----
***************
*** 876,882 ****
      if (li == NULL) return 0;
      if (lua_isnil(L, 3)) /* remove? */
      {
! 	list_remove(l, li);
  	clear_tv(&li->li_tv);
  	vim_free(li);
      }
--- 741,747 ----
      if (li == NULL) return 0;
      if (lua_isnil(L, 3)) /* remove? */
      {
! 	list_remove(l, li, li);
  	clear_tv(&li->li_tv);
  	vim_free(li);
      }
***************
*** 904,911 ****
  	typval_T v;
  	lua_settop(L, 2);
  	luaV_totypval(L, 2, &v);
! 	copy_tv(&v, &li->li_tv);
! 	list_append(l, li);
      }
      lua_settop(L, 1);
      return 1;
--- 769,775 ----
  	typval_T v;
  	lua_settop(L, 2);
  	luaV_totypval(L, 2, &v);
! 	list_append_tv(l, &v);
      }
      lua_settop(L, 1);
      return 1;
***************
*** 1682,1688 ****
  	    tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
  	}
  	lua_pop(L, 2); /* metatable and value */
! 	set_ref_in_tv(&tv, copyID);
      }
      return 0;
  }
--- 1546,1552 ----
  	    tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
  	}
  	lua_pop(L, 2); /* metatable and value */
! 	set_ref_in_item(&tv, copyID);
      }
      return 0;
  }
*** ../vim-7.3.568/src/if_py_both.h	2012-04-20 13:31:16.000000000 +0200
--- src/if_py_both.h	2012-06-29 12:03:52.000000000 +0200
***************
*** 1,4 ****
! /* vi:set ts=8 sts=4 sw=4:
   *
   * VIM - Vi IMproved	by Bram Moolenaar
   *
--- 1,4 ----
! /* vi:set ts=8 sts=4 sw=4 noet:
   *
   * VIM - Vi IMproved	by Bram Moolenaar
   *
***************
*** 105,111 ****
  	return NULL;
      Py_INCREF(list);
  
!     if (!PyList_Check(list)) {
  	PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
  	Py_DECREF(list);
  	return NULL;
--- 105,112 ----
  	return NULL;
      Py_INCREF(list);
  
!     if (!PyList_Check(list))
!     {
  	PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
  	Py_DECREF(list);
  	return NULL;
***************
*** 119,125 ****
  	char *str = NULL;
  	PyInt len;
  
! 	if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len)) {
  	    PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
  	    Py_DECREF(list);
  	    return NULL;
--- 120,127 ----
  	char *str = NULL;
  	PyInt len;
  
! 	if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
! 	{
  	    PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
  	    Py_DECREF(list);
  	    return NULL;
***************
*** 297,303 ****
  {
      PyObject	*result;
      PyObject	*newObj;
!     char	ptrBuf[NUMBUFLEN];
  
      /* Avoid infinite recursion */
      if (depth > 100)
--- 299,305 ----
  {
      PyObject	*result;
      PyObject	*newObj;
!     char	ptrBuf[sizeof(void *) * 2 + 3];
  
      /* Avoid infinite recursion */
      if (depth > 100)
***************
*** 312,320 ****
      if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
  	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
      {
! 	sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
! 		our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
! 					   : (long_u)our_tv->vval.v_dict);
  	result = PyDict_GetItemString(lookupDict, ptrBuf);
  	if (result != NULL)
  	{
--- 314,322 ----
      if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
  	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
      {
! 	sprintf(ptrBuf, "%p",
! 		our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
! 					   : (void *)our_tv->vval.v_dict);
  	result = PyDict_GetItemString(lookupDict, ptrBuf);
  	if (result != NULL)
  	{
***************
*** 374,509 ****
  	    hashitem_T	*hi;
  	    dictitem_T	*di;
  
! 	    PyDict_SetItemString(lookupDict, ptrBuf, result);
  
! 	    for (hi = ht->ht_array; todo > 0; ++hi)
  	    {
! 		if (!HASHITEM_EMPTY(hi))
! 		{
! 		    --todo;
! 
! 		    di = dict_lookup(hi);
! 		    newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
! 		    PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
! 		    Py_DECREF(newObj);
! 		}
  	    }
  	}
      }
!     else
      {
! 	Py_INCREF(Py_None);
! 	result = Py_None;
      }
  
!     return result;
  }
- #endif
  
      static PyObject *
! VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
  {
! #ifdef FEAT_EVAL
!     char	*expr;
!     typval_T	*our_tv;
!     PyObject	*result;
!     PyObject    *lookup_dict;
  
!     if (!PyArg_ParseTuple(args, "s", &expr))
  	return NULL;
  
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     our_tv = eval_expr((char_u *)expr, NULL);
! 
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     if (our_tv == NULL)
      {
! 	PyErr_SetVim(_("invalid expression"));
  	return NULL;
      }
  
-     /* Convert the Vim type into a Python type.  Create a dictionary that's
-      * used to check for recursive loops. */
      lookup_dict = PyDict_New();
!     result = VimToPython(our_tv, 1, lookup_dict);
      Py_DECREF(lookup_dict);
  
! 
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     free_tv(our_tv);
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     return result;
! #else
!     PyErr_SetVim(_("expressions disabled at compile time"));
!     return NULL;
! #endif
  }
  
! /*
!  * Vim module - Definitions
!  */
! 
! static struct PyMethodDef VimMethods[] = {
!     /* name,	     function,		calling,    documentation */
!     {"command",	     VimCommand,	1,	    "Execute a Vim ex-mode command" },
!     {"eval",	     VimEval,		1,	    "Evaluate an expression using Vim evaluator" },
!     { NULL,	     NULL,		0,	    NULL }
  };
  
  typedef struct
  {
      PyObject_HEAD
!     buf_T *buf;
! }
! BufferObject;
  
! #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
! 
! /*
!  * Buffer list object - Implementation
!  */
  
!     static PyInt
! BufListLength(PyObject *self UNUSED)
  {
!     buf_T	*b = firstbuf;
!     PyInt	n = 0;
  
!     while (b)
      {
! 	++n;
! 	b = b->b_next;
      }
! 
!     return n;
  }
  
      static PyObject *
! BufListItem(PyObject *self UNUSED, PyInt n)
  {
!     buf_T *b;
  
!     for (b = firstbuf; b; b = b->b_next, --n)
      {
! 	if (n == 0)
! 	    return BufferNew(b);
      }
  
!     PyErr_SetString(PyExc_IndexError, _("no such buffer"));
!     return NULL;
  }
  
! typedef struct
! {
!     PyObject_HEAD
!     win_T	*win;
! } WindowObject;
  
  #define INVALID_WINDOW_VALUE ((win_T *)(-1))
  
--- 376,1325 ----
  	    hashitem_T	*hi;
  	    dictitem_T	*di;
  
! 	    PyDict_SetItemString(lookupDict, ptrBuf, result);
! 
! 	    for (hi = ht->ht_array; todo > 0; ++hi)
! 	    {
! 		if (!HASHITEM_EMPTY(hi))
! 		{
! 		    --todo;
! 
! 		    di = dict_lookup(hi);
! 		    newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
! 		    PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
! 		    Py_DECREF(newObj);
! 		}
! 	    }
! 	}
!     }
!     else
!     {
! 	Py_INCREF(Py_None);
! 	result = Py_None;
!     }
! 
!     return result;
! }
! #endif
! 
!     static PyObject *
! VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
! {
! #ifdef FEAT_EVAL
!     char	*expr;
!     typval_T	*our_tv;
!     PyObject	*result;
!     PyObject    *lookup_dict;
! 
!     if (!PyArg_ParseTuple(args, "s", &expr))
! 	return NULL;
! 
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     our_tv = eval_expr((char_u *)expr, NULL);
! 
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     if (our_tv == NULL)
!     {
! 	PyErr_SetVim(_("invalid expression"));
! 	return NULL;
!     }
! 
!     /* Convert the Vim type into a Python type.  Create a dictionary that's
!      * used to check for recursive loops. */
!     lookup_dict = PyDict_New();
!     result = VimToPython(our_tv, 1, lookup_dict);
!     Py_DECREF(lookup_dict);
! 
! 
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     free_tv(our_tv);
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     return result;
! #else
!     PyErr_SetVim(_("expressions disabled at compile time"));
!     return NULL;
! #endif
! }
! 
! static PyObject *ConvertToPyObject(typval_T *);
! 
!     static PyObject *
! VimEvalPy(PyObject *self UNUSED, PyObject *args UNUSED)
! {
! #ifdef FEAT_EVAL
!     char	*expr;
!     typval_T	*our_tv;
!     PyObject	*result;
! 
!     if (!PyArg_ParseTuple(args, "s", &expr))
! 	return NULL;
! 
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     our_tv = eval_expr((char_u *)expr, NULL);
! 
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     if (our_tv == NULL)
!     {
! 	PyErr_SetVim(_("invalid expression"));
! 	return NULL;
!     }
! 
!     result = ConvertToPyObject(our_tv);
!     Py_BEGIN_ALLOW_THREADS
!     Python_Lock_Vim();
!     free_tv(our_tv);
!     Python_Release_Vim();
!     Py_END_ALLOW_THREADS
! 
!     return result;
! #else
!     PyErr_SetVim(_("expressions disabled at compile time"));
!     return NULL;
! #endif
! }
! 
!     static PyObject *
! VimStrwidth(PyObject *self UNUSED, PyObject *args)
! {
!     char	*expr;
! 
!     if (!PyArg_ParseTuple(args, "s", &expr))
! 	return NULL;
! 
!     return PyLong_FromLong(mb_string2cells((char_u *)expr, STRLEN(expr)));
! }
! 
! /*
!  * Vim module - Definitions
!  */
! 
! static struct PyMethodDef VimMethods[] = {
!     /* name,	     function,		calling,    documentation */
!     {"command",	     VimCommand,	1,	    "Execute a Vim ex-mode command" },
!     {"eval",	     VimEval,		1,	    "Evaluate an expression using Vim evaluator" },
!     {"bindeval",     VimEvalPy,         1,          "Like eval(), but returns objects attached to vim ones"},
!     {"strwidth",     VimStrwidth,       1,          "Screen string width, counts <Tab> as having width 1"},
!     { NULL,	     NULL,		0,	    NULL }
! };
! 
! typedef struct
! {
!     PyObject_HEAD
!     buf_T *buf;
! } BufferObject;
! 
! #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
! 
! /*
!  * Buffer list object - Implementation
!  */
! 
!     static PyInt
! BufListLength(PyObject *self UNUSED)
! {
!     buf_T	*b = firstbuf;
!     PyInt	n = 0;
! 
!     while (b)
!     {
! 	++n;
! 	b = b->b_next;
!     }
! 
!     return n;
! }
! 
!     static PyObject *
! BufListItem(PyObject *self UNUSED, PyInt n)
! {
!     buf_T *b;
! 
!     for (b = firstbuf; b; b = b->b_next, --n)
!     {
! 	if (n == 0)
! 	    return BufferNew(b);
!     }
! 
!     PyErr_SetString(PyExc_IndexError, _("no such buffer"));
!     return NULL;
! }
! 
! typedef struct
! {
!     PyObject_HEAD
!     win_T	*win;
! } WindowObject;
! 
! static int ConvertFromPyObject(PyObject *, typval_T *);
! static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
! 
! typedef struct pylinkedlist_S {
!     struct pylinkedlist_S	*pll_next;
!     struct pylinkedlist_S	*pll_prev;
!     PyObject			*pll_obj;
! } pylinkedlist_T;
! 
! static pylinkedlist_T *lastdict = NULL;
! static pylinkedlist_T *lastlist = NULL;
! 
!     static void
! pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
! {
!     if (ref->pll_prev == NULL)
!     {
! 	if (ref->pll_next == NULL)
! 	{
! 	    *last = NULL;
! 	    return;
! 	}
!     }
!     else
! 	ref->pll_prev->pll_next = ref->pll_next;
! 
!     if (ref->pll_next == NULL)
! 	*last = ref->pll_prev;
!     else
! 	ref->pll_next->pll_prev = ref->pll_prev;
! }
! 
!     static void
! pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
! {
!     if (*last == NULL)
! 	ref->pll_prev = NULL;
!     else
!     {
! 	(*last)->pll_next = ref;
! 	ref->pll_prev = *last;
!     }
!     ref->pll_next = NULL;
!     ref->pll_obj = self;
!     *last = ref;
! }
! 
! static PyTypeObject DictionaryType;
! 
! typedef struct
! {
!     PyObject_HEAD
!     dict_T	*dict;
!     pylinkedlist_T	ref;
! } DictionaryObject;
! 
!     static PyObject *
! DictionaryNew(dict_T *dict)
! {
!     DictionaryObject	*self;
! 
!     self = PyObject_NEW(DictionaryObject, &DictionaryType);
!     if (self == NULL)
! 	return NULL;
!     self->dict = dict;
!     ++dict->dv_refcount;
! 
!     pyll_add((PyObject *)(self), &self->ref, &lastdict);
! 
!     return (PyObject *)(self);
! }
! 
!     static int
! pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
! {
!     dict_T	*d;
!     char_u	*key;
!     dictitem_T	*di;
!     PyObject	*keyObject;
!     PyObject	*valObject;
!     Py_ssize_t	iter = 0;
! 
!     d = dict_alloc();
!     if (d == NULL)
!     {
! 	PyErr_NoMemory();
! 	return -1;
!     }
! 
!     tv->v_type = VAR_DICT;
!     tv->vval.v_dict = d;
! 
!     while (PyDict_Next(obj, &iter, &keyObject, &valObject))
!     {
! 	DICTKEY_DECL
! 
! 	if (keyObject == NULL)
! 	    return -1;
! 	if (valObject == NULL)
! 	    return -1;
! 
! 	DICTKEY_GET(-1)
! 
! 	di = dictitem_alloc(key);
! 
! 	DICTKEY_UNREF
! 
! 	if (di == NULL)
! 	{
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	di->di_tv.v_lock = 0;
! 
! 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
! 	{
! 	    vim_free(di);
! 	    return -1;
! 	}
! 	if (dict_add(d, di) == FAIL)
! 	{
! 	    vim_free(di);
! 	    PyErr_SetVim(_("failed to add key to dictionary"));
! 	    return -1;
! 	}
!     }
!     return 0;
! }
! 
!     static int
! pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
! {
!     dict_T	*d;
!     char_u	*key;
!     dictitem_T	*di;
!     PyObject	*list;
!     PyObject	*litem;
!     PyObject	*keyObject;
!     PyObject	*valObject;
!     Py_ssize_t	lsize;
! 
!     d = dict_alloc();
!     if (d == NULL)
!     {
! 	PyErr_NoMemory();
! 	return -1;
!     }
! 
!     tv->v_type = VAR_DICT;
!     tv->vval.v_dict = d;
! 
!     list = PyMapping_Items(obj);
!     lsize = PyList_Size(list);
!     while (lsize--)
!     {
! 	DICTKEY_DECL
! 
! 	litem = PyList_GetItem(list, lsize);
! 	if (litem == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    return -1;
! 	}
! 
! 	keyObject = PyTuple_GetItem(litem, 0);
! 	if (keyObject == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 
! 	DICTKEY_GET(-1)
! 
! 	valObject = PyTuple_GetItem(litem, 1);
! 	if (valObject == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 
! 	di = dictitem_alloc(key);
! 
! 	DICTKEY_UNREF
! 
! 	if (di == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	di->di_tv.v_lock = 0;
! 
! 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
! 	{
! 	    vim_free(di);
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 	if (dict_add(d, di) == FAIL)
! 	{
! 	    vim_free(di);
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    PyErr_SetVim(_("failed to add key to dictionary"));
! 	    return -1;
! 	}
! 	Py_DECREF(litem);
!     }
!     Py_DECREF(list);
!     return 0;
! }
! 
!     static PyInt
! DictionaryLength(PyObject *self)
! {
!     return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
! }
! 
!     static PyObject *
! DictionaryItem(PyObject *self, PyObject *keyObject)
! {
!     char_u	*key;
!     dictitem_T	*val;
!     DICTKEY_DECL
! 
!     DICTKEY_GET(NULL)
! 
!     val = dict_find(((DictionaryObject *) (self))->dict, key, -1);
! 
!     DICTKEY_UNREF
! 
!     return ConvertToPyObject(&val->di_tv);
! }
! 
!     static PyInt
! DictionaryAssItem(PyObject *self, PyObject *keyObject, PyObject *valObject)
! {
!     char_u	*key;
!     typval_T	tv;
!     dict_T	*d = ((DictionaryObject *)(self))->dict;
!     dictitem_T	*di;
!     DICTKEY_DECL
! 
!     if (d->dv_lock)
!     {
! 	PyErr_SetVim(_("dict is locked"));
! 	return -1;
!     }
! 
!     DICTKEY_GET(-1)
! 
!     di = dict_find(d, key, -1);
! 
!     if (valObject == NULL)
!     {
! 	if (di == NULL)
! 	{
! 	    PyErr_SetString(PyExc_IndexError, _("no such key in dictionary"));
! 	    return -1;
! 	}
! 	hashitem_T	*hi = hash_find(&d->dv_hashtab, di->di_key);
! 	hash_remove(&d->dv_hashtab, hi);
! 	dictitem_free(di);
! 	return 0;
!     }
! 
!     if (ConvertFromPyObject(valObject, &tv) == -1)
!     {
! 	return -1;
!     }
! 
!     if (di == NULL)
!     {
! 	di = dictitem_alloc(key);
! 	if (di == NULL)
! 	{
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	di->di_tv.v_lock = 0;
! 
! 	if (dict_add(d, di) == FAIL)
! 	{
! 	    vim_free(di);
! 	    PyErr_SetVim(_("failed to add key to dictionary"));
! 	    return -1;
! 	}
!     }
!     else
! 	clear_tv(&di->di_tv);
! 
!     DICTKEY_UNREF
! 
!     copy_tv(&tv, &di->di_tv);
!     return 0;
! }
! 
!     static PyObject *
! DictionaryListKeys(PyObject *self)
! {
!     dict_T	*dict = ((DictionaryObject *)(self))->dict;
!     long_u	todo = dict->dv_hashtab.ht_used;
!     Py_ssize_t	i = 0;
!     PyObject	*r;
!     hashitem_T	*hi;
! 
!     r = PyList_New(todo);
!     for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
!     {
! 	if (!HASHITEM_EMPTY(hi))
! 	{
! 	    PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
! 	    --todo;
! 	    ++i;
! 	}
!     }
!     return r;
! }
! 
! static struct PyMethodDef DictionaryMethods[] = {
!     {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
!     { NULL,	    NULL,		0,	    NULL }
! };
! 
! static PyTypeObject ListType;
! 
! typedef struct
! {
!     PyObject_HEAD
!     list_T	*list;
!     pylinkedlist_T	ref;
! } ListObject;
! 
!     static PyObject *
! ListNew(list_T *list)
! {
!     ListObject	*self;
! 
!     self = PyObject_NEW(ListObject, &ListType);
!     if (self == NULL)
! 	return NULL;
!     self->list = list;
!     ++list->lv_refcount;
! 
!     pyll_add((PyObject *)(self), &self->ref, &lastlist);
! 
!     return (PyObject *)(self);
! }
! 
!     static int
! list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
! {
!     Py_ssize_t	i;
!     Py_ssize_t	lsize = PySequence_Size(obj);
!     PyObject	*litem;
!     listitem_T	*li;
! 
!     for(i=0; i<lsize; i++)
!     {
! 	li = listitem_alloc();
! 	if (li == NULL)
! 	{
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	li->li_tv.v_lock = 0;
! 
! 	litem = PySequence_GetItem(obj, i);
! 	if (litem == NULL)
! 	    return -1;
! 	if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
! 	    return -1;
! 
! 	list_append(l, li);
!     }
!     return 0;
! }
! 
!     static int
! pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
! {
!     list_T	*l;
! 
!     l = list_alloc();
!     if (l == NULL)
!     {
! 	PyErr_NoMemory();
! 	return -1;
!     }
! 
!     tv->v_type = VAR_LIST;
!     tv->vval.v_list = l;
! 
!     if (list_py_concat(l, obj, lookupDict) == -1)
! 	return -1;
! 
!     return 0;
! }
! 
!     static int
! pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
! {
!     PyObject	*iterator = PyObject_GetIter(obj);
!     PyObject	*item;
!     list_T	*l;
!     listitem_T	*li;
! 
!     l = list_alloc();
! 
!     if (l == NULL)
!     {
! 	PyErr_NoMemory();
! 	return -1;
!     }
! 
!     tv->vval.v_list = l;
!     tv->v_type = VAR_LIST;
! 
! 
!     if (iterator == NULL)
! 	return -1;
! 
!     while ((item = PyIter_Next(obj)))
!     {
! 	li = listitem_alloc();
! 	if (li == NULL)
! 	{
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	li->li_tv.v_lock = 0;
! 
! 	if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
! 	    return -1;
! 
! 	list_append(l, li);
! 
! 	Py_DECREF(item);
!     }
! 
!     Py_DECREF(iterator);
!     return 0;
! }
! 
!     static PyInt
! ListLength(PyObject *self)
! {
!     return ((PyInt) (((ListObject *) (self))->list->lv_len));
! }
! 
!     static PyObject *
! ListItem(PyObject *self, Py_ssize_t index)
! {
!     listitem_T	*li;
! 
!     if (index>=ListLength(self))
!     {
! 	PyErr_SetString(PyExc_IndexError, "list index out of range");
! 	return NULL;
!     }
!     li = list_find(((ListObject *) (self))->list, (long) index);
!     if (li == NULL)
!     {
! 	PyErr_SetVim(_("internal error: failed to get vim list item"));
! 	return NULL;
!     }
!     return ConvertToPyObject(&li->li_tv);
! }
! 
! #define PROC_RANGE \
!     if (last < 0) {\
! 	if (last < -size) \
! 	    last = 0; \
! 	else \
! 	    last += size; \
!     } \
!     if (first < 0) \
! 	first = 0; \
!     if (first > size) \
! 	first = size; \
!     if (last > size) \
! 	last = size;
! 
!     static PyObject *
! ListSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last)
! {
!     PyInt	i;
!     PyInt	size = ListLength(self);
!     PyInt	n;
!     PyObject	*list;
!     int		reversed = 0;
! 
!     PROC_RANGE
!     if (first >= last)
! 	first = last;
! 
!     n = last-first;
!     list = PyList_New(n);
!     if (list == NULL)
! 	return NULL;
! 
!     for (i = 0; i < n; ++i)
!     {
! 	PyObject	*item = ListItem(self, i);
! 	if (item == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    return NULL;
! 	}
! 
! 	if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
! 	{
! 	    Py_DECREF(item);
! 	    Py_DECREF(list);
! 	    return NULL;
! 	}
!     }
! 
!     return list;
! }
! 
!     static int
! ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj)
! {
!     typval_T	tv;
!     list_T	*l = ((ListObject *) (self))->list;
!     listitem_T	*li;
!     Py_ssize_t	length = ListLength(self);
! 
!     if (l->lv_lock)
!     {
! 	PyErr_SetVim(_("list is locked"));
! 	return -1;
!     }
!     if (index>length || (index==length && obj==NULL))
!     {
! 	PyErr_SetString(PyExc_IndexError, "list index out of range");
! 	return -1;
!     }
! 
!     if (obj == NULL)
!     {
! 	li = list_find(l, (long) index);
! 	list_remove(l, li, li);
! 	clear_tv(&li->li_tv);
! 	vim_free(li);
! 	return 0;
!     }
! 
!     if (ConvertFromPyObject(obj, &tv) == -1)
! 	return -1;
! 
!     if (index == length)
!     {
! 	if (list_append_tv(l, &tv) == FAIL)
! 	{
! 	    PyErr_SetVim(_("Failed to add item to list"));
! 	    return -1;
! 	}
!     }
!     else
!     {
! 	li = list_find(l, (long) index);
! 	clear_tv(&li->li_tv);
! 	copy_tv(&tv, &li->li_tv);
!     }
!     return 0;
! }
! 
!     static int
! ListAssSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
! {
!     PyInt	size = ListLength(self);
!     Py_ssize_t	i;
!     Py_ssize_t	lsize;
!     PyObject	*litem;
!     listitem_T	*li;
!     listitem_T	*next;
!     typval_T	v;
!     list_T	*l = ((ListObject *) (self))->list;
! 
!     if (l->lv_lock)
!     {
! 	PyErr_SetVim(_("list is locked"));
! 	return -1;
!     }
! 
!     PROC_RANGE
  
!     if (first == size)
! 	li = NULL;
!     else
!     {
! 	li = list_find(l, (long) first);
! 	if (li == NULL)
! 	{
! 	    PyErr_SetVim(_("internal error: no vim list item"));
! 	    return -1;
! 	}
! 	if (last > first)
! 	{
! 	    i = last - first;
! 	    while (i-- && li != NULL)
  	    {
! 		next = li->li_next;
! 		listitem_remove(l, li);
! 		li = next;
  	    }
  	}
      }
! 
!     if (obj == NULL)
! 	return 0;
! 
!     if (!PyList_Check(obj))
      {
! 	PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
! 	return -1;
      }
  
!     lsize = PyList_Size(obj);
! 
!     for(i=0; i<lsize; i++)
!     {
! 	litem = PyList_GetItem(obj, i);
! 	if (litem == NULL)
! 	    return -1;
! 	if (ConvertFromPyObject(litem, &v) == -1)
! 	    return -1;
! 	if (list_insert_tv(l, &v, li) == FAIL)
! 	{
! 	    PyErr_SetVim(_("internal error: failed to add item to list"));
! 	    return -1;
! 	}
!     }
!     return 0;
  }
  
      static PyObject *
! ListConcatInPlace(PyObject *self, PyObject *obj)
  {
!     list_T	*l = ((ListObject *) (self))->list;
!     PyObject	*lookup_dict;
  
!     if (l->lv_lock)
!     {
! 	PyErr_SetVim(_("list is locked"));
  	return NULL;
+     }
  
!     if (!PySequence_Check(obj))
      {
! 	PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
  	return NULL;
      }
  
      lookup_dict = PyDict_New();
!     if (list_py_concat(l, obj, lookup_dict) == -1)
!     {
! 	Py_DECREF(lookup_dict);
! 	return NULL;
!     }
      Py_DECREF(lookup_dict);
  
!     Py_INCREF(self);
!     return self;
  }
  
! static struct PyMethodDef ListMethods[] = {
!     {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
!     { NULL,	    NULL,		0,	    NULL }
  };
  
  typedef struct
  {
      PyObject_HEAD
!     char_u	*name;
! } FunctionObject;
  
! static PyTypeObject FunctionType;
  
!     static PyObject *
! FunctionNew(char_u *name)
  {
!     FunctionObject	*self;
  
!     self = PyObject_NEW(FunctionObject, &FunctionType);
!     if (self == NULL)
! 	return NULL;
!     self->name = PyMem_New(char_u, STRLEN(name) + 1);
!     if (self->name == NULL)
      {
! 	PyErr_NoMemory();
! 	return NULL;
      }
!     STRCPY(self->name, name);
!     func_ref(name);
!     return (PyObject *)(self);
  }
  
      static PyObject *
! FunctionCall(PyObject *self, PyObject *argsObject, PyObject *kwargs)
  {
!     FunctionObject	*this = (FunctionObject *)(self);
!     char_u	*name = this->name;
!     typval_T	args;
!     typval_T	selfdicttv;
!     typval_T	rettv;
!     dict_T	*selfdict = NULL;
!     PyObject	*selfdictObject;
!     PyObject	*result;
!     int		error;
  
!     if (ConvertFromPyObject(argsObject, &args) == -1)
! 	return NULL;
! 
!     if (kwargs != NULL)
      {
! 	selfdictObject = PyDict_GetItemString(kwargs, "self");
! 	if (selfdictObject != NULL)
! 	{
! 	    if (!PyDict_Check(selfdictObject))
! 	    {
! 		PyErr_SetString(PyExc_TypeError, _("'self' argument must be a dictionary"));
! 		clear_tv(&args);
! 		return NULL;
! 	    }
! 	    if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
! 		return NULL;
! 	    selfdict = selfdicttv.vval.v_dict;
! 	}
      }
  
!     error = func_call(name, &args, selfdict, &rettv);
!     if (error != OK)
!     {
! 	result = NULL;
! 	PyErr_SetVim(_("failed to run function"));
!     }
!     else
! 	result = ConvertToPyObject(&rettv);
! 
!     /* FIXME Check what should really be cleared. */
!     clear_tv(&args);
!     clear_tv(&rettv);
!     /*
!      * if (selfdict!=NULL)
!      *     clear_tv(selfdicttv);
!      */
! 
!     return result;
  }
  
! static struct PyMethodDef FunctionMethods[] = {
!     {"__call__",    (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
!     { NULL,	    NULL,		0,	    NULL }
! };
  
  #define INVALID_WINDOW_VALUE ((win_T *)(-1))
  
***************
*** 1567,1569 ****
--- 2383,2638 ----
      { NULL,	    NULL,		0,	    NULL }
  };
  
+     static void
+ set_ref_in_py(const int copyID)
+ {
+     pylinkedlist_T	*cur;
+     dict_T	*dd;
+     list_T	*ll;
+ 
+     if (lastdict != NULL)
+ 	for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
+ 	{
+ 	    dd = ((DictionaryObject *) (cur->pll_obj))->dict;
+ 	    if (dd->dv_copyID != copyID)
+ 	    {
+ 		dd->dv_copyID = copyID;
+ 		set_ref_in_ht(&dd->dv_hashtab, copyID);
+ 	    }
+ 	}
+ 
+     if (lastlist != NULL)
+ 	for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
+ 	{
+ 	    ll = ((ListObject *) (cur->pll_obj))->list;
+ 	    if (ll->lv_copyID != copyID)
+ 	    {
+ 		ll->lv_copyID = copyID;
+ 		set_ref_in_list(ll, copyID);
+ 	    }
+ 	}
+ }
+ 
+     static int
+ set_string_copy(char_u *str, typval_T *tv)
+ {
+     tv->vval.v_string = vim_strsave(str);
+     if (tv->vval.v_string == NULL)
+     {
+ 	PyErr_NoMemory();
+ 	return -1;
+     }
+     return 0;
+ }
+ 
+ #ifdef FEAT_EVAL
+ typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
+ 
+     static int
+ convert_dl(PyObject *obj, typval_T *tv,
+ 				    pytotvfunc py_to_tv, PyObject *lookupDict)
+ {
+     PyObject	*capsule;
+     char	hexBuf[sizeof(void *) * 2 + 3];
+ 
+     sprintf(hexBuf, "%p", obj);
+ 
+     capsule = PyDict_GetItemString(lookupDict, hexBuf);
+     if (capsule == NULL)
+     {
+ 	capsule = PyCapsule_New(tv, NULL, NULL);
+ 	PyDict_SetItemString(lookupDict, hexBuf, capsule);
+ 	Py_DECREF(capsule);
+ 	if (py_to_tv(obj, tv, lookupDict) == -1)
+ 	{
+ 	    tv->v_type = VAR_UNKNOWN;
+ 	    return -1;
+ 	}
+ 	/* As we are not using copy_tv which increments reference count we must
+ 	 * do it ourself. */
+ 	switch(tv->v_type)
+ 	{
+ 	    case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
+ 	    case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
+ 	}
+     }
+     else
+     {
+ 	typval_T	*v = PyCapsule_GetPointer(capsule, NULL);
+ 	copy_tv(v, tv);
+     }
+     return 0;
+ }
+ 
+     static int
+ ConvertFromPyObject(PyObject *obj, typval_T *tv)
+ {
+     PyObject	*lookup_dict;
+     int		r;
+ 
+     lookup_dict = PyDict_New();
+     r = _ConvertFromPyObject(obj, tv, lookup_dict);
+     Py_DECREF(lookup_dict);
+     return r;
+ }
+ 
+     static int
+ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
+ {
+     if (obj->ob_type == &DictionaryType)
+     {
+ 	tv->v_type = VAR_DICT;
+ 	tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
+ 	++tv->vval.v_dict->dv_refcount;
+     }
+     else if (obj->ob_type == &ListType)
+     {
+ 	tv->v_type = VAR_LIST;
+ 	tv->vval.v_list = (((ListObject *)(obj))->list);
+ 	++tv->vval.v_list->lv_refcount;
+     }
+     else if (obj->ob_type == &FunctionType)
+     {
+ 	if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
+ 	    return -1;
+ 
+ 	tv->v_type = VAR_FUNC;
+ 	func_ref(tv->vval.v_string);
+     }
+ #if PY_MAJOR_VERSION >= 3
+     else if (PyBytes_Check(obj))
+     {
+ 	char_u	*result = (char_u *) PyBytes_AsString(obj);
+ 
+ 	if (result == NULL)
+ 	    return -1;
+ 
+ 	if (set_string_copy(result, tv) == -1)
+ 	    return -1;
+ 
+ 	tv->v_type = VAR_STRING;
+     }
+     else if (PyUnicode_Check(obj))
+     {
+ 	PyObject	*bytes;
+ 	char_u	*result;
+ 
+ 	bytes = PyString_AsBytes(obj);
+ 	if (bytes == NULL)
+ 	    return -1;
+ 
+ 	result = (char_u *) PyBytes_AsString(bytes);
+ 	if (result == NULL)
+ 	    return -1;
+ 
+ 	if (set_string_copy(result, tv) == -1)
+ 	{
+ 	    Py_XDECREF(bytes);
+ 	    return -1;
+ 	}
+ 	Py_XDECREF(bytes);
+ 
+ 	tv->v_type = VAR_STRING;
+     }
+ #else
+     else if (PyUnicode_Check(obj))
+     {
+ 	PyObject	*bytes;
+ 	char_u	*result;
+ 
+ 	bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
+ 	if (bytes == NULL)
+ 	    return -1;
+ 
+ 	result=(char_u *) PyString_AsString(bytes);
+ 	if (result == NULL)
+ 	    return -1;
+ 
+ 	if (set_string_copy(result, tv) == -1)
+ 	{
+ 	    Py_XDECREF(bytes);
+ 	    return -1;
+ 	}
+ 	Py_XDECREF(bytes);
+ 
+ 	tv->v_type = VAR_STRING;
+     }
+     else if (PyString_Check(obj))
+     {
+ 	char_u	*result = (char_u *) PyString_AsString(obj);
+ 
+ 	if (result == NULL)
+ 	    return -1;
+ 
+ 	if (set_string_copy(result, tv) == -1)
+ 	    return -1;
+ 
+ 	tv->v_type = VAR_STRING;
+     }
+     else if (PyInt_Check(obj))
+     {
+ 	tv->v_type = VAR_NUMBER;
+ 	tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
+     }
+ #endif
+     else if (PyLong_Check(obj))
+     {
+ 	tv->v_type = VAR_NUMBER;
+ 	tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
+     }
+     else if (PyDict_Check(obj))
+ 	return convert_dl(obj, tv, pydict_to_tv, lookupDict);
+ #ifdef FEAT_FLOAT
+     else if (PyFloat_Check(obj))
+     {
+ 	tv->v_type = VAR_FLOAT;
+ 	tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
+     }
+ #endif
+     else if (PyIter_Check(obj))
+ 	return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
+     else if (PySequence_Check(obj))
+ 	return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
+     else if (PyMapping_Check(obj))
+ 	return convert_dl(obj, tv, pymap_to_tv, lookupDict);
+     else
+     {
+ 	PyErr_SetString(PyExc_TypeError, _("unable to convert to vim structure"));
+ 	return -1;
+     }
+     return 0;
+ }
+ 
+     static PyObject *
+ ConvertToPyObject(typval_T *tv)
+ {
+     if (tv == NULL)
+     {
+ 	PyErr_SetVim(_("NULL reference passed"));
+ 	return NULL;
+     }
+     switch (tv->v_type)
+     {
+ 	case VAR_STRING:
+ 	    return PyBytes_FromString((char *) tv->vval.v_string);
+ 	case VAR_NUMBER:
+ 	    return PyLong_FromLong((long) tv->vval.v_number);
+ #ifdef FEAT_FLOAT
+ 	case VAR_FLOAT:
+ 	    return PyFloat_FromDouble((double) tv->vval.v_float);
+ #endif
+ 	case VAR_LIST:
+ 	    return ListNew(tv->vval.v_list);
+ 	case VAR_DICT:
+ 	    return DictionaryNew(tv->vval.v_dict);
+ 	case VAR_FUNC:
+ 	    return FunctionNew(tv->vval.v_string);
+ 	case VAR_UNKNOWN:
+ 	    Py_INCREF(Py_None);
+ 	    return Py_None;
+ 	default:
+ 	    PyErr_SetVim(_("internal error: invalid value type"));
+ 	    return NULL;
+     }
+ }
+ #endif
*** ../vim-7.3.568/src/if_python.c	2011-08-28 16:00:14.000000000 +0200
--- src/if_python.c	2012-06-29 12:47:48.000000000 +0200
***************
*** 1,4 ****
! /* vi:set ts=8 sts=4 sw=4:
   *
   * VIM - Vi IMproved	by Bram Moolenaar
   *
--- 1,4 ----
! /* vi:set ts=8 sts=4 sw=4 noet:
   *
   * VIM - Vi IMproved	by Bram Moolenaar
   *
***************
*** 56,61 ****
--- 56,63 ----
  
  static void init_structs(void);
  
+ #define PyBytes_FromString PyString_FromString
+ 
  /* No-op conversion functions, use with care! */
  #define PyString_AsBytes(obj) (obj)
  #define PyString_FreeBytes(obj)
***************
*** 122,132 ****
--- 124,136 ----
  /* This makes if_python.c compile without warnings against Python 2.5
   * on Win32 and Win64. */
  # undef PyRun_SimpleString
+ # undef PyRun_String
  # undef PyArg_Parse
  # undef PyArg_ParseTuple
  # undef Py_BuildValue
  # undef Py_InitModule4
  # undef Py_InitModule4_64
+ # undef PyObject_CallMethod
  
  /*
   * Wrapper defines
***************
*** 134,139 ****
--- 138,144 ----
  # define PyArg_Parse dll_PyArg_Parse
  # define PyArg_ParseTuple dll_PyArg_ParseTuple
  # define PyMem_Free dll_PyMem_Free
+ # define PyMem_Malloc dll_PyMem_Malloc
  # define PyDict_SetItemString dll_PyDict_SetItemString
  # define PyErr_BadArgument dll_PyErr_BadArgument
  # define PyErr_Clear dll_PyErr_Clear
***************
*** 150,172 ****
--- 155,202 ----
  # endif
  # define PyInt_AsLong dll_PyInt_AsLong
  # define PyInt_FromLong dll_PyInt_FromLong
+ # define PyLong_AsLong dll_PyLong_AsLong
+ # define PyLong_FromLong dll_PyLong_FromLong
  # define PyInt_Type (*dll_PyInt_Type)
+ # define PyLong_Type (*dll_PyLong_Type)
  # define PyList_GetItem dll_PyList_GetItem
  # define PyList_Append dll_PyList_Append
  # define PyList_New dll_PyList_New
  # define PyList_SetItem dll_PyList_SetItem
  # define PyList_Size dll_PyList_Size
  # define PyList_Type (*dll_PyList_Type)
+ # define PySequence_Check dll_PySequence_Check
+ # define PySequence_Size dll_PySequence_Size
+ # define PySequence_GetItem dll_PySequence_GetItem
+ # define PyTuple_Size dll_PyTuple_Size
+ # define PyTuple_GetItem dll_PyTuple_GetItem
+ # define PyTuple_Type (*dll_PyTuple_Type)
  # define PyImport_ImportModule dll_PyImport_ImportModule
  # define PyDict_New dll_PyDict_New
  # define PyDict_GetItemString dll_PyDict_GetItemString
+ # define PyDict_Next dll_PyDict_Next
+ # ifdef PyMapping_Items
+ #  define PY_NO_MAPPING_ITEMS
+ # else
+ #  define PyMapping_Items dll_PyMapping_Items
+ # endif
+ # define PyObject_CallMethod dll_PyObject_CallMethod
+ # define PyMapping_Check dll_PyMapping_Check
+ # define PyIter_Next dll_PyIter_Next
  # define PyModule_GetDict dll_PyModule_GetDict
  # define PyRun_SimpleString dll_PyRun_SimpleString
+ # define PyRun_String dll_PyRun_String
  # define PyString_AsString dll_PyString_AsString
  # define PyString_FromString dll_PyString_FromString
  # define PyString_FromStringAndSize dll_PyString_FromStringAndSize
  # define PyString_Size dll_PyString_Size
  # define PyString_Type (*dll_PyString_Type)
+ # define PyUnicode_Type (*dll_PyUnicode_Type)
+ # define PyUnicodeUCS4_AsEncodedString (*dll_PyUnicodeUCS4_AsEncodedString)
+ # define PyFloat_AsDouble dll_PyFloat_AsDouble
+ # define PyFloat_FromDouble dll_PyFloat_FromDouble
+ # define PyFloat_Type (*dll_PyFloat_Type)
+ # define PyImport_AddModule (*dll_PyImport_AddModule)
  # define PySys_SetObject dll_PySys_SetObject
  # define PySys_SetArgv dll_PySys_SetArgv
  # define PyType_Type (*dll_PyType_Type)
***************
*** 179,186 ****
--- 209,218 ----
  # define Py_Finalize dll_Py_Finalize
  # define Py_IsInitialized dll_Py_IsInitialized
  # define _PyObject_New dll__PyObject_New
+ # define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
  # define _Py_NoneStruct (*dll__Py_NoneStruct)
  # define PyObject_Init dll__PyObject_Init
+ # define PyObject_GetIter dll_PyObject_GetIter
  # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
  #  define PyType_IsSubtype dll_PyType_IsSubtype
  # endif
***************
*** 188,193 ****
--- 220,227 ----
  #  define PyObject_Malloc dll_PyObject_Malloc
  #  define PyObject_Free dll_PyObject_Free
  # endif
+ # define PyCapsule_New dll_PyCapsule_New
+ # define PyCapsule_GetPointer dll_PyCapsule_GetPointer
  
  /*
   * Pointers for dynamic link
***************
*** 195,200 ****
--- 229,235 ----
  static int(*dll_PyArg_Parse)(PyObject *, char *, ...);
  static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...);
  static int(*dll_PyMem_Free)(void *);
+ static void* (*dll_PyMem_Malloc)(size_t);
  static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
  static int(*dll_PyErr_BadArgument)(void);
  static void(*dll_PyErr_Clear)(void);
***************
*** 208,233 ****
  # ifdef PY_CAN_RECURSE
  static PyGILState_STATE	(*dll_PyGILState_Ensure)(void);
  static void (*dll_PyGILState_Release)(PyGILState_STATE);
! #endif
  static long(*dll_PyInt_AsLong)(PyObject *);
  static PyObject*(*dll_PyInt_FromLong)(long);
  static PyTypeObject* dll_PyInt_Type;
  static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
  static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
  static PyObject*(*dll_PyList_New)(PyInt size);
  static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
  static PyInt(*dll_PyList_Size)(PyObject *);
  static PyTypeObject* dll_PyList_Type;
  static PyObject*(*dll_PyImport_ImportModule)(const char *);
  static PyObject*(*dll_PyDict_New)(void);
  static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
  static PyObject*(*dll_PyModule_GetDict)(PyObject *);
  static int(*dll_PyRun_SimpleString)(char *);
  static char*(*dll_PyString_AsString)(PyObject *);
  static PyObject*(*dll_PyString_FromString)(const char *);
  static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
  static PyInt(*dll_PyString_Size)(PyObject *);
  static PyTypeObject* dll_PyString_Type;
  static int(*dll_PySys_SetObject)(char *, PyObject *);
  static int(*dll_PySys_SetArgv)(int, char **);
  static PyTypeObject* dll_PyType_Type;
--- 243,290 ----
  # ifdef PY_CAN_RECURSE
  static PyGILState_STATE	(*dll_PyGILState_Ensure)(void);
  static void (*dll_PyGILState_Release)(PyGILState_STATE);
! # endif
  static long(*dll_PyInt_AsLong)(PyObject *);
  static PyObject*(*dll_PyInt_FromLong)(long);
+ static long(*dll_PyLong_AsLong)(PyObject *);
+ static PyObject*(*dll_PyLong_FromLong)(long);
  static PyTypeObject* dll_PyInt_Type;
+ static PyTypeObject* dll_PyLong_Type;
  static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
  static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
  static PyObject*(*dll_PyList_New)(PyInt size);
  static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
  static PyInt(*dll_PyList_Size)(PyObject *);
  static PyTypeObject* dll_PyList_Type;
+ static int (*dll_PySequence_Check)(PyObject *);
+ static PyInt(*dll_PySequence_Size)(PyObject *);
+ static PyObject*(*dll_PySequence_GetItem)(PyObject *, PyInt);
+ static PyInt(*dll_PyTuple_Size)(PyObject *);
+ static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt);
+ static PyTypeObject* dll_PyTuple_Type;
  static PyObject*(*dll_PyImport_ImportModule)(const char *);
  static PyObject*(*dll_PyDict_New)(void);
  static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
+ static int (*dll_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **);
+ # ifndef PY_NO_MAPPING_ITEMS
+ static PyObject* (*dll_PyMapping_Items)(PyObject *);
+ # endif
+ static PyObject* (*dll_PyObject_CallMethod)(PyObject *, char *, PyObject *);
+ static int (*dll_PyMapping_Check)(PyObject *);
+ static PyObject* (*dll_PyIter_Next)(PyObject *);
  static PyObject*(*dll_PyModule_GetDict)(PyObject *);
  static int(*dll_PyRun_SimpleString)(char *);
+ static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *);
  static char*(*dll_PyString_AsString)(PyObject *);
  static PyObject*(*dll_PyString_FromString)(const char *);
  static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
  static PyInt(*dll_PyString_Size)(PyObject *);
  static PyTypeObject* dll_PyString_Type;
+ static PyTypeObject* dll_PyUnicode_Type;
+ static PyObject *(*PyUnicodeUCS4_AsEncodedString)(PyObject *, char *, char *);
+ static double(*dll_PyFloat_AsDouble)(PyObject *);
+ static PyObject*(*dll_PyFloat_FromDouble)(double);
+ static PyTypeObject* dll_PyFloat_Type;
  static int(*dll_PySys_SetObject)(char *, PyObject *);
  static int(*dll_PySys_SetArgv)(int, char **);
  static PyTypeObject* dll_PyType_Type;
***************
*** 235,246 ****
--- 292,306 ----
  static PyObject*(*dll_Py_BuildValue)(char *, ...);
  static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *);
  static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int);
+ static PyObject*(*dll_PyImport_AddModule)(char *);
  static void(*dll_Py_SetPythonHome)(char *home);
  static void(*dll_Py_Initialize)(void);
  static void(*dll_Py_Finalize)(void);
  static int(*dll_Py_IsInitialized)(void);
  static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
  static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
+ static PyObject* (*dll_PyObject_GetIter)(PyObject *);
+ static iternextfunc dll__PyObject_NextNotImplemented;
  static PyObject* dll__Py_NoneStruct;
  # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
  static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
***************
*** 249,254 ****
--- 309,316 ----
  static void* (*dll_PyObject_Malloc)(size_t);
  static void (*dll_PyObject_Free)(void*);
  # endif
+ static PyObject* (*dll_PyCapsule_New)(void *, char *, PyCapsule_Destructor);
+ static void* (*dll_PyCapsule_GetPointer)(PyObject *, char *);
  
  static HINSTANCE hinstPython = 0; /* Instance of python.dll */
  
***************
*** 278,283 ****
--- 340,346 ----
      {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse},
      {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple},
      {"PyMem_Free", (PYTHON_PROC*)&dll_PyMem_Free},
+     {"PyMem_Malloc", (PYTHON_PROC*)&dll_PyMem_Malloc},
      {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString},
      {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
      {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
***************
*** 294,316 ****
--- 357,402 ----
  # endif
      {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong},
      {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong},
+     {"PyLong_AsLong", (PYTHON_PROC*)&dll_PyLong_AsLong},
+     {"PyLong_FromLong", (PYTHON_PROC*)&dll_PyLong_FromLong},
      {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type},
+     {"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type},
      {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
      {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
      {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
      {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
      {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
      {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type},
+     {"PySequence_GetItem", (PYTHON_PROC*)&dll_PySequence_GetItem},
+     {"PySequence_Size", (PYTHON_PROC*)&dll_PySequence_Size},
+     {"PySequence_Check", (PYTHON_PROC*)&dll_PySequence_Check},
+     {"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem},
+     {"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size},
+     {"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type},
      {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
      {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
+     {"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next},
      {"PyDict_New", (PYTHON_PROC*)&dll_PyDict_New},
+ # ifndef PY_NO_MAPPING_ITEMS
+     {"PyMapping_Items", (PYTHON_PROC*)&dll_PyMapping_Items},
+ # endif
+     {"PyObject_CallMethod", (PYTHON_PROC*)&dll_PyObject_CallMethod},
+     {"PyMapping_Check", (PYTHON_PROC*)&dll_PyMapping_Check},
+     {"PyIter_Next", (PYTHON_PROC*)&dll_PyIter_Next},
      {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
      {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
+     {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String},
      {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
      {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
      {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize},
      {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size},
      {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type},
+     {"PyUnicode_Type", (PYTHON_PROC*)&dll_PyUnicode_Type},
+     {"PyUnicodeUCS4_AsEncodedString", (PYTHON_PROC*)&dll_PyUnicodeUCS4_AsEncodedString},
+     {"PyFloat_Type", (PYTHON_PROC*)&dll_PyFloat_Type},
+     {"PyFloat_AsDouble", (PYTHON_PROC*)&dll_PyFloat_AsDouble},
+     {"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble},
+     {"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule},
      {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
      {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
      {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
***************
*** 328,333 ****
--- 414,421 ----
      {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
      {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
      {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
+     {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
+     {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&dll__PyObject_NextNotImplemented},
      {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct},
  # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
      {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype},
***************
*** 336,341 ****
--- 424,431 ----
      {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc},
      {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free},
  # endif
+     {"PyCapsule_New", (PYTHON_PROC*)&dll_PyCapsule_New},
+     {"PyCapsule_GetPointer", (PYTHON_PROC*)&dll_PyCapsule_GetPointer},
      {"", NULL},
  };
  
***************
*** 434,443 ****
--- 524,548 ----
  
  static PyObject *BufferNew (buf_T *);
  static PyObject *WindowNew(win_T *);
+ static PyObject *DictionaryNew(dict_T *);
  static PyObject *LineToString(const char *);
  
  static PyTypeObject RangeType;
  
+ static int initialised = 0;
+ #define PYINITIALISED initialised
+ 
+ /* Add conversion from PyInt? */
+ #define DICTKEY_GET(err) \
+     if (!PyString_Check(keyObject)) \
+     { \
+ 	PyErr_SetString(PyExc_TypeError, _("only string keys are allowed")); \
+ 	return err; \
+     } \
+     key = (char_u *) PyString_AsString(keyObject);
+ #define DICTKEY_UNREF
+ #define DICTKEY_DECL
+ 
  /*
   * Include the code shared with if_python3.c
   */
***************
*** 451,456 ****
--- 556,563 ----
  static PyInt RangeStart;
  static PyInt RangeEnd;
  
+ static PyObject *globals;
+ 
  static void PythonIO_Flush(void);
  static int PythonIO_Init(void);
  static int PythonMod_Init(void);
***************
*** 466,473 ****
   * 1. Python interpreter main program.
   */
  
- static int initialised = 0;
- 
  #if PYTHON_API_VERSION < 1007 /* Python 1.4 */
  typedef PyObject PyThreadState;
  #endif
--- 573,578 ----
***************
*** 581,586 ****
--- 686,693 ----
  	if (PythonMod_Init())
  	    goto fail;
  
+ 	globals = PyModule_GetDict(PyImport_AddModule("__main__"));
+ 
  	/* Remove the element from sys.path that was added because of our
  	 * argv[0] value in PythonMod_Init().  Previously we used an empty
  	 * string, but dependinding on the OS we then get an empty entry or
***************
*** 609,615 ****
   * External interface
   */
      static void
! DoPythonCommand(exarg_T *eap, const char *cmd)
  {
  #ifndef PY_CAN_RECURSE
      static int		recursive = 0;
--- 716,722 ----
   * External interface
   */
      static void
! DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv)
  {
  #ifndef PY_CAN_RECURSE
      static int		recursive = 0;
***************
*** 639,646 ****
      if (Python_Init())
  	goto theend;
  
!     RangeStart = eap->line1;
!     RangeEnd = eap->line2;
      Python_Release_Vim();	    /* leave vim */
  
  #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
--- 746,761 ----
      if (Python_Init())
  	goto theend;
  
!     if (rettv == NULL)
!     {
! 	RangeStart = eap->line1;
! 	RangeEnd = eap->line2;
!     }
!     else
!     {
! 	RangeStart = (PyInt) curwin->w_cursor.lnum;
! 	RangeEnd = RangeStart;
!     }
      Python_Release_Vim();	    /* leave vim */
  
  #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
***************
*** 658,664 ****
  
      Python_RestoreThread();	    /* enter python */
  
!     PyRun_SimpleString((char *)(cmd));
  
      Python_SaveThread();	    /* leave python */
  
--- 773,795 ----
  
      Python_RestoreThread();	    /* enter python */
  
!     if (rettv == NULL)
! 	PyRun_SimpleString((char *)(cmd));
!     else
!     {
! 	PyObject	*r;
! 
! 	r = PyRun_String((char *)(cmd), Py_eval_input, globals, globals);
! 	if (r == NULL)
! 	    EMSG(_("E858: Eval did not return a valid python object"));
! 	else
! 	{
! 	    if (ConvertFromPyObject(r, rettv) == -1)
! 		EMSG(_("E859: Failed to convert returned python object to vim value"));
! 	    Py_DECREF(r);
! 	}
! 	PyErr_Clear();
!     }
  
      Python_SaveThread();	    /* leave python */
  
***************
*** 680,686 ****
  #ifndef PY_CAN_RECURSE
      --recursive;
  #endif
!     return;	    /* keeps lint happy */
  }
  
  /*
--- 811,817 ----
  #ifndef PY_CAN_RECURSE
      --recursive;
  #endif
!     return;
  }
  
  /*
***************
*** 695,703 ****
      if (!eap->skip)
      {
  	if (script == NULL)
! 	    DoPythonCommand(eap, (char *)eap->arg);
  	else
! 	    DoPythonCommand(eap, (char *)script);
      }
      vim_free(script);
  }
--- 826,834 ----
      if (!eap->skip)
      {
  	if (script == NULL)
! 	    DoPythonCommand(eap, (char *)eap->arg, NULL);
  	else
! 	    DoPythonCommand(eap, (char *)script, NULL);
      }
      vim_free(script);
  }
***************
*** 743,749 ****
      *p++ = '\0';
  
      /* Execute the file */
!     DoPythonCommand(eap, buffer);
  }
  
  /******************************************************
--- 874,880 ----
      *p++ = '\0';
  
      /* Execute the file */
!     DoPythonCommand(eap, buffer, NULL);
  }
  
  /******************************************************
***************
*** 765,778 ****
      static int
  OutputSetattr(PyObject *self, char *name, PyObject *val)
  {
!     if (val == NULL) {
  	PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
  	return -1;
      }
  
      if (strcmp(name, "softspace") == 0)
      {
! 	if (!PyInt_Check(val)) {
  	    PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
  	    return -1;
  	}
--- 896,911 ----
      static int
  OutputSetattr(PyObject *self, char *name, PyObject *val)
  {
!     if (val == NULL)
!     {
  	PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
  	return -1;
      }
  
      if (strcmp(name, "softspace") == 0)
      {
! 	if (!PyInt_Check(val))
! 	{
  	    PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
  	    return -1;
  	}
***************
*** 800,805 ****
--- 933,941 ----
   * 3. Implementation of the Vim module for Python
   */
  
+ static PyObject *ConvertToPyObject(typval_T *);
+ static int ConvertFromPyObject(PyObject *, typval_T *);
+ 
  /* Window type - Implementation functions
   * --------------------------------------
   */
***************
*** 1441,1446 ****
--- 1577,1748 ----
      return result;
  }
  
+ static void DictionaryDestructor(PyObject *);
+ static PyObject *DictionaryGetattr(PyObject *, char*);
+ 
+ static PyMappingMethods DictionaryAsMapping = {
+     (PyInquiry)		DictionaryLength,
+     (binaryfunc)	DictionaryItem,
+     (objobjargproc)	DictionaryAssItem,
+ };
+ 
+ static PyTypeObject DictionaryType = {
+     PyObject_HEAD_INIT(0)
+     0,
+     "vimdictionary",
+     sizeof(DictionaryObject),
+     0,
+ 
+     (destructor)  DictionaryDestructor,
+     (printfunc)   0,
+     (getattrfunc) DictionaryGetattr,
+     (setattrfunc) 0,
+     (cmpfunc)     0,
+     (reprfunc)    0,
+ 
+     0,			    /* as number */
+     0,			    /* as sequence */
+     &DictionaryAsMapping,   /* as mapping */
+ 
+     (hashfunc)    0,
+     (ternaryfunc) 0,
+     (reprfunc)    0,
+ };
+ 
+     static void
+ DictionaryDestructor(PyObject *self)
+ {
+     DictionaryObject	*this = ((DictionaryObject *) (self));
+ 
+     pyll_remove(&this->ref, &lastdict);
+     dict_unref(this->dict);
+ 
+     Py_DECREF(self);
+ }
+ 
+     static PyObject *
+ DictionaryGetattr(PyObject *self, char *name)
+ {
+     return Py_FindMethod(DictionaryMethods, self, name);
+ }
+ 
+ static void ListDestructor(PyObject *);
+ static PyObject *ListGetattr(PyObject *, char *);
+ 
+ static PySequenceMethods ListAsSeq = {
+     (PyInquiry)			ListLength,
+     (binaryfunc)		0,
+     (PyIntArgFunc)		0,
+     (PyIntArgFunc)		ListItem,
+     (PyIntIntArgFunc)		ListSlice,
+     (PyIntObjArgProc)		ListAssItem,
+     (PyIntIntObjArgProc)	ListAssSlice,
+     (objobjproc)		0,
+ #if PY_MAJOR_VERSION >= 2
+     (binaryfunc)		ListConcatInPlace,
+     0,
+ #endif
+ };
+ 
+ static PyTypeObject ListType = {
+     PyObject_HEAD_INIT(0)
+     0,
+     "vimlist",
+     sizeof(ListObject),
+     0,
+ 
+     (destructor)  ListDestructor,
+     (printfunc)   0,
+     (getattrfunc) ListGetattr,
+     (setattrfunc) 0,
+     (cmpfunc)     0,
+     (reprfunc)    0,
+ 
+     0,			    /* as number */
+     &ListAsSeq,		    /* as sequence */
+     0,			    /* as mapping */
+ 
+     (hashfunc)    0,
+     (ternaryfunc) 0,
+     (reprfunc)    0,
+ };
+ 
+     static void
+ ListDestructor(PyObject *self)
+ {
+     ListObject	*this = ((ListObject *) (self));
+ 
+     pyll_remove(&this->ref, &lastlist);
+     list_unref(this->list);
+ 
+     Py_DECREF(self);
+ }
+ 
+     static PyObject *
+ ListGetattr(PyObject *self, char *name)
+ {
+     return Py_FindMethod(ListMethods, self, name);
+ }
+ 
+ static void FunctionDestructor(PyObject *);
+ static PyObject *FunctionGetattr(PyObject *, char *);
+ 
+ static PyTypeObject FunctionType = {
+     PyObject_HEAD_INIT(0)
+     0,
+     "vimfunction",
+     sizeof(FunctionObject),
+     0,
+ 
+     (destructor)  FunctionDestructor,
+     (printfunc)   0,
+     (getattrfunc) FunctionGetattr,
+     (setattrfunc) 0,
+     (cmpfunc)     0,
+     (reprfunc)    0,
+ 
+     0,			    /* as number */
+     0,			    /* as sequence */
+     0,			    /* as mapping */
+ 
+     (hashfunc)    0,
+     (ternaryfunc) FunctionCall,
+     (reprfunc)    0,
+ };
+ 
+     static void
+ FunctionDestructor(PyObject *self)
+ {
+     FunctionObject	*this = (FunctionObject *) (self);
+ 
+     func_unref(this->name);
+     PyMem_Del(this->name);
+ 
+     Py_DECREF(self);
+ }
+ 
+     static PyObject *
+ FunctionGetattr(PyObject *self, char *name)
+ {
+     FunctionObject	*this = (FunctionObject *)(self);
+ 
+     if (strcmp(name, "name") == 0)
+ 	return PyString_FromString((char *)(this->name));
+     else
+ 	return Py_FindMethod(FunctionMethods, self, name);
+ }
+ 
+     void
+ do_pyeval (char_u *str, typval_T *rettv)
+ {
+     DoPythonCommand(NULL, (char *) str, rettv);
+     switch(rettv->v_type)
+     {
+ 	case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
+ 	case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;
+ 	case VAR_FUNC: func_ref(rettv->vval.v_string);    break;
+     }
+ }
  
  /* Don't generate a prototype for the next function, it generates an error on
   * newer Python versions. */
***************
*** 1453,1458 ****
--- 1755,1766 ----
  }
  #endif /* Python 1.4 */
  
+     void
+ set_ref_in_python (int copyID)
+ {
+     set_ref_in_py(copyID);
+ }
+ 
      static void
  init_structs(void)
  {
*** ../vim-7.3.568/src/if_python3.c	2012-02-04 20:17:21.000000000 +0100
--- src/if_python3.c	2012-06-29 11:54:10.000000000 +0200
***************
*** 77,83 ****
  
  #define PyInt Py_ssize_t
  #define PyString_Check(obj) PyUnicode_Check(obj)
! #define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER);
  #define PyString_FreeBytes(obj) Py_XDECREF(bytes)
  #define PyString_AsString(obj) PyBytes_AsString(obj)
  #define PyString_Size(obj) PyBytes_GET_SIZE(bytes)
--- 77,83 ----
  
  #define PyInt Py_ssize_t
  #define PyString_Check(obj) PyUnicode_Check(obj)
! #define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER)
  #define PyString_FreeBytes(obj) Py_XDECREF(bytes)
  #define PyString_AsString(obj) PyBytes_AsString(obj)
  #define PyString_Size(obj) PyBytes_GET_SIZE(bytes)
***************
*** 109,114 ****
--- 109,115 ----
  # undef PyArg_ParseTuple
  # define PyArg_ParseTuple py3_PyArg_ParseTuple
  # define PyMem_Free py3_PyMem_Free
+ # define PyMem_Malloc py3_PyMem_Malloc
  # define PyDict_SetItemString py3_PyDict_SetItemString
  # define PyErr_BadArgument py3_PyErr_BadArgument
  # define PyErr_Clear py3_PyErr_Clear
***************
*** 128,141 ****
--- 129,155 ----
  # define PyList_New py3_PyList_New
  # define PyList_SetItem py3_PyList_SetItem
  # define PyList_Size py3_PyList_Size
+ # define PySequence_Check py3_PySequence_Check
+ # define PySequence_Size py3_PySequence_Size
+ # define PySequence_GetItem py3_PySequence_GetItem
+ # define PyTuple_Size py3_PyTuple_Size
+ # define PyTuple_GetItem py3_PyTuple_GetItem
  # define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
  # define PyImport_ImportModule py3_PyImport_ImportModule
+ # define PyImport_AddModule py3_PyImport_AddModule
  # define PyObject_Init py3__PyObject_Init
  # define PyDict_New py3_PyDict_New
  # define PyDict_GetItemString py3_PyDict_GetItemString
+ # define PyDict_Next py3_PyDict_Next
+ # define PyMapping_Check py3_PyMapping_Check
+ # define PyMapping_Items py3_PyMapping_Items
+ # define PyIter_Next py3_PyIter_Next
+ # define PyObject_GetIter py3_PyObject_GetIter
  # define PyModule_GetDict py3_PyModule_GetDict
  #undef PyRun_SimpleString
  # define PyRun_SimpleString py3_PyRun_SimpleString
+ #undef PyRun_String
+ # define PyRun_String py3_PyRun_String
  # define PySys_SetObject py3_PySys_SetObject
  # define PySys_SetArgv py3_PySys_SetArgv
  # define PyType_Type (*py3_PyType_Type)
***************
*** 147,152 ****
--- 161,167 ----
  # define Py_Finalize py3_Py_Finalize
  # define Py_IsInitialized py3_Py_IsInitialized
  # define _Py_NoneStruct (*py3__Py_NoneStruct)
+ # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented)
  # define PyModule_AddObject py3_PyModule_AddObject
  # define PyImport_AppendInittab py3_PyImport_AppendInittab
  # define _PyUnicode_AsString py3__PyUnicode_AsString
***************
*** 154,161 ****
--- 169,181 ----
  # define PyUnicode_AsEncodedString py3_PyUnicode_AsEncodedString
  # undef PyBytes_AsString
  # define PyBytes_AsString py3_PyBytes_AsString
+ # undef PyBytes_FromString
+ # define PyBytes_FromString py3_PyBytes_FromString
+ # define PyFloat_FromDouble py3_PyFloat_FromDouble
+ # define PyFloat_AsDouble py3_PyFloat_AsDouble
  # define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
  # define PySlice_Type (*py3_PySlice_Type)
+ # define PyFloat_Type (*py3_PyFloat_Type)
  # define PyErr_NewException py3_PyErr_NewException
  # ifdef Py_DEBUG
  #  define _Py_NegativeRefcount py3__Py_NegativeRefcount
***************
*** 174,179 ****
--- 194,202 ----
  # define PyUnicode_FromString py3_PyUnicode_FromString
  # undef PyUnicode_Decode
  # define PyUnicode_Decode py3_PyUnicode_Decode
+ # define PyType_IsSubtype py3_PyType_IsSubtype
+ # define PyCapsule_New py3_PyCapsule_New
+ # define PyCapsule_GetPointer py3_PyCapsule_GetPointer
  
  # ifdef Py_DEBUG
  #  undef PyObject_NEW
***************
*** 194,215 ****
--- 217,250 ----
  static int (*py3_PySys_SetObject)(char *, PyObject *);
  static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
  static Py_ssize_t (*py3_PyList_Size)(PyObject *);
+ static int (*py3_PySequence_Check)(PyObject *);
+ static Py_ssize_t (*py3_PySequence_Size)(PyObject *);
+ static PyObject* (*py3_PySequence_GetItem)(PyObject *, Py_ssize_t);
+ static Py_ssize_t (*py3_PyTuple_Size)(PyObject *);
+ static PyObject* (*py3_PyTuple_GetItem)(PyObject *, Py_ssize_t);
+ static int (*py3_PyMapping_Check)(PyObject *);
+ static PyObject* (*py3_PyMapping_Items)(PyObject *);
  static int (*py3_PySlice_GetIndicesEx)(PyObject *r, Py_ssize_t length,
  		     Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
  static PyObject* (*py3_PyErr_NoMemory)(void);
  static void (*py3_Py_Finalize)(void);
  static void (*py3_PyErr_SetString)(PyObject *, const char *);
  static int (*py3_PyRun_SimpleString)(char *);
+ static PyObject* (*py3_PyRun_String)(char *, int, PyObject *, PyObject *);
  static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
  static PyObject* (*py3_PyImport_ImportModule)(const char *);
+ static PyObject* (*py3_PyImport_AddModule)(const char *);
  static int (*py3_PyErr_BadArgument)(void);
  static PyTypeObject* py3_PyType_Type;
  static PyObject* (*py3_PyErr_Occurred)(void);
  static PyObject* (*py3_PyModule_GetDict)(PyObject *);
  static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
  static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
+ static int (*py3_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **);
  static PyObject* (*py3_PyLong_FromLong)(long);
  static PyObject* (*py3_PyDict_New)(void);
+ static PyObject* (*py3_PyIter_Next)(PyObject *);
+ static PyObject* (*py3_PyObject_GetIter)(PyObject *);
  static PyObject* (*py3_Py_BuildValue)(char *, ...);
  static int (*py3_PyType_Ready)(PyTypeObject *type);
  static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
***************
*** 224,244 ****
--- 259,287 ----
  static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
  static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
  static int (*py3_PyMem_Free)(void *);
+ static void* (*py3_PyMem_Malloc)(size_t);
  static int (*py3_Py_IsInitialized)(void);
  static void (*py3_PyErr_Clear)(void);
  static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
+ static iternextfunc py3__PyObject_NextNotImplemented;
  static PyObject* py3__Py_NoneStruct;
  static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
  static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
  static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
  static PyObject* (*py3_PyUnicode_AsEncodedString)(PyObject *unicode, const char* encoding, const char* errors);
  static char* (*py3_PyBytes_AsString)(PyObject *bytes);
+ static PyObject* (*py3_PyBytes_FromString)(char *str);
+ static PyObject* (*py3_PyFloat_FromDouble)(double num);
+ static double (*py3_PyFloat_AsDouble)(PyObject *);
  static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
  static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
  static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
  static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
  static PyTypeObject* py3_PySlice_Type;
+ static PyTypeObject* py3_PyFloat_Type;
  static PyObject* (*py3_PyErr_NewException)(char *name, PyObject *base, PyObject *dict);
+ static PyObject* (*py3_PyCapsule_New)(void *, char *, PyCapsule_Destructor);
+ static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *);
  # ifdef Py_DEBUG
      static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
      static Py_ssize_t* py3__Py_RefTotal;
***************
*** 249,254 ****
--- 292,298 ----
      static void (*py3_PyObject_Free)(void*);
      static void* (*py3_PyObject_Malloc)(size_t);
  # endif
+ static int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
  
  static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
  
***************
*** 280,304 ****
--- 324,361 ----
      {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
      {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
      {"PyMem_Free", (PYTHON_PROC*)&py3_PyMem_Free},
+     {"PyMem_Malloc", (PYTHON_PROC*)&py3_PyMem_Malloc},
      {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
      {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
      {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
      {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
      {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
      {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
+     {"PySequence_Check", (PYTHON_PROC*)&py3_PySequence_Check},
+     {"PySequence_Size", (PYTHON_PROC*)&py3_PySequence_Size},
+     {"PySequence_GetItem", (PYTHON_PROC*)&py3_PySequence_GetItem},
+     {"PyTuple_Size", (PYTHON_PROC*)&py3_PyTuple_Size},
+     {"PyTuple_GetItem", (PYTHON_PROC*)&py3_PyTuple_GetItem},
      {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
      {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
      {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
      {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
      {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
+     {"PyRun_String", (PYTHON_PROC*)&py3_PyRun_String},
      {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
      {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
+     {"PyImport_AddModule", (PYTHON_PROC*)&py3_PyImport_AddModule},
      {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
      {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
      {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
      {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
      {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
      {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
+     {"PyDict_Next", (PYTHON_PROC*)&py3_PyDict_Next},
+     {"PyMapping_Check", (PYTHON_PROC*)&py3_PyMapping_Check},
+     {"PyMapping_Items", (PYTHON_PROC*)&py3_PyMapping_Items},
+     {"PyIter_Next", (PYTHON_PROC*)&py3_PyIter_Next},
+     {"PyObject_GetIter", (PYTHON_PROC*)&py3_PyObject_GetIter},
      {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
      {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
      {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
***************
*** 311,316 ****
--- 368,374 ----
      {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
      {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
      {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
+     {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented},
      {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
      {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
      {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
***************
*** 318,328 ****
--- 376,390 ----
      {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
      {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
      {"PyBytes_AsString", (PYTHON_PROC*)&py3_PyBytes_AsString},
+     {"PyBytes_FromString", (PYTHON_PROC*)&py3_PyBytes_FromString},
+     {"PyFloat_FromDouble", (PYTHON_PROC*)&py3_PyFloat_FromDouble},
+     {"PyFloat_AsDouble", (PYTHON_PROC*)&py3_PyFloat_AsDouble},
      {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
      {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
      {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
      {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
      {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
+     {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type},
      {"PyErr_NewException", (PYTHON_PROC*)&py3_PyErr_NewException},
  # ifdef Py_DEBUG
      {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
***************
*** 334,339 ****
--- 396,404 ----
      {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
      {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
  # endif
+     {"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype},
+     {"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New},
+     {"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer},
      {"", NULL},
  };
  
***************
*** 472,482 ****
--- 537,577 ----
  
  static PyTypeObject RangeType;
  
+ static int py3initialised = 0;
+ 
+ #define PYINITIALISED py3initialised
+ 
+ /* Add conversion from PyInt? */
+ #define DICTKEY_GET(err) \
+     if (PyBytes_Check(keyObject)) \
+ 	key = (char_u *) PyBytes_AsString(keyObject); \
+     else if (PyUnicode_Check(keyObject)) \
+     { \
+ 	bytes = PyString_AsBytes(keyObject); \
+ 	if (bytes == NULL) \
+ 	    return err; \
+ 	key = (char_u *) PyBytes_AsString(bytes); \
+ 	if (key == NULL) \
+ 	    return err; \
+     } \
+     else \
+     { \
+ 	PyErr_SetString(PyExc_TypeError, _("only string keys are allowed")); \
+ 	return err; \
+     }
+ #define DICTKEY_UNREF \
+     if (bytes != NULL) \
+ 	Py_XDECREF(bytes);
+ 
+ #define DICTKEY_DECL PyObject *bytes = NULL;
+ 
  /*
   * Include the code shared with if_python.c
   */
  #include "if_py_both.h"
  
+ #define PY3OBJ_DELETED(obj) (obj->ob_base.ob_refcnt<=0)
+ 
      static void
  call_PyObject_Free(void *p)
  {
***************
*** 506,511 ****
--- 601,608 ----
  static Py_ssize_t RangeStart;
  static Py_ssize_t RangeEnd;
  
+ static PyObject *globals;
+ 
  static int PythonIO_Init(void);
  static void PythonIO_Fini(void);
  PyMODINIT_FUNC Py3Init_vim(void);
***************
*** 514,521 ****
   * 1. Python interpreter main program.
   */
  
- static int py3initialised = 0;
- 
  static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
  
      void
--- 611,616 ----
***************
*** 593,598 ****
--- 688,695 ----
  
  	PyImport_AppendInittab("vim", Py3Init_vim);
  
+ 	globals = PyModule_GetDict(PyImport_AddModule("__main__"));
+ 
  	/* Remove the element from sys.path that was added because of our
  	 * argv[0] value in Py3Init_vim().  Previously we used an empty
  	 * string, but dependinding on the OS we then get an empty entry or
***************
*** 629,635 ****
   * External interface
   */
      static void
! DoPy3Command(exarg_T *eap, const char *cmd)
  {
  #if defined(MACOS) && !defined(MACOS_X_UNIX)
      GrafPtr		oldPort;
--- 726,732 ----
   * External interface
   */
      static void
! DoPy3Command(exarg_T *eap, const char *cmd, typval_T *rettv)
  {
  #if defined(MACOS) && !defined(MACOS_X_UNIX)
      GrafPtr		oldPort;
***************
*** 649,656 ****
      if (Python3_Init())
  	goto theend;
  
!     RangeStart = eap->line1;
!     RangeEnd = eap->line2;
      Python_Release_Vim();	    /* leave vim */
  
  #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
--- 746,761 ----
      if (Python3_Init())
  	goto theend;
  
!     if (rettv == NULL)
!     {
! 	RangeStart = eap->line1;
! 	RangeEnd = eap->line2;
!     }
!     else
!     {
! 	RangeStart = (PyInt) curwin->w_cursor.lnum;
! 	RangeEnd = RangeStart;
!     }
      Python_Release_Vim();	    /* leave vim */
  
  #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
***************
*** 674,680 ****
  					(char *)ENC_OPT, CODEC_ERROR_HANDLER);
      cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER);
      Py_XDECREF(cmdstr);
!     PyRun_SimpleString(PyBytes_AsString(cmdbytes));
      Py_XDECREF(cmdbytes);
  
      PyGILState_Release(pygilstate);
--- 779,802 ----
  					(char *)ENC_OPT, CODEC_ERROR_HANDLER);
      cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER);
      Py_XDECREF(cmdstr);
!     if (rettv == NULL)
! 	PyRun_SimpleString(PyBytes_AsString(cmdbytes));
!     else
!     {
! 	PyObject	*r;
! 
! 	r = PyRun_String(PyBytes_AsString(cmdbytes), Py_eval_input,
! 			 globals, globals);
! 	if (r == NULL)
! 	    EMSG(_("E860: Eval did not return a valid python 3 object"));
! 	else
! 	{
! 	    if (ConvertFromPyObject(r, rettv) == -1)
! 		EMSG(_("E861: Failed to convert returned python 3 object to vim value"));
! 	    Py_DECREF(r);
! 	}
! 	PyErr_Clear();
!     }
      Py_XDECREF(cmdbytes);
  
      PyGILState_Release(pygilstate);
***************
*** 709,717 ****
      if (!eap->skip)
      {
  	if (script == NULL)
! 	    DoPy3Command(eap, (char *)eap->arg);
  	else
! 	    DoPy3Command(eap, (char *)script);
      }
      vim_free(script);
  }
--- 831,839 ----
      if (!eap->skip)
      {
  	if (script == NULL)
! 	    DoPy3Command(eap, (char *)eap->arg, NULL);
  	else
! 	    DoPy3Command(eap, (char *)script, NULL);
      }
      vim_free(script);
  }
***************
*** 772,778 ****
  
  
      /* Execute the file */
!     DoPy3Command(eap, buffer);
  }
  
  /******************************************************
--- 894,900 ----
  
  
      /* Execute the file */
!     DoPy3Command(eap, buffer, NULL);
  }
  
  /******************************************************
***************
*** 802,815 ****
      if (PyUnicode_Check(nameobj))
  	name = _PyUnicode_AsString(nameobj);
  
!     if (val == NULL) {
  	PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
  	return -1;
      }
  
      if (strcmp(name, "softspace") == 0)
      {
! 	if (!PyLong_Check(val)) {
  	    PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
  	    return -1;
  	}
--- 924,939 ----
      if (PyUnicode_Check(nameobj))
  	name = _PyUnicode_AsString(nameobj);
  
!     if (val == NULL)
!     {
  	PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
  	return -1;
      }
  
      if (strcmp(name, "softspace") == 0)
      {
! 	if (!PyLong_Check(val))
! 	{
  	    PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
  	    return -1;
  	}
***************
*** 1030,1049 ****
      static PyObject *
  BufferSubscript(PyObject *self, PyObject* idx)
  {
!     if (PyLong_Check(idx)) {
  	long _idx = PyLong_AsLong(idx);
  	return BufferItem(self,_idx);
!     } else if (PySlice_Check(idx)) {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  	      (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
  	      &start, &stop,
! 	      &step, &slicelen) < 0) {
  	    return NULL;
  	}
  	return BufferSlice(self, start, stop);
!     } else {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return NULL;
      }
--- 1154,1178 ----
      static PyObject *
  BufferSubscript(PyObject *self, PyObject* idx)
  {
!     if (PyLong_Check(idx))
!     {
  	long _idx = PyLong_AsLong(idx);
  	return BufferItem(self,_idx);
!     } else if (PySlice_Check(idx))
!     {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  	      (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
  	      &start, &stop,
! 	      &step, &slicelen) < 0)
! 	{
  	    return NULL;
  	}
  	return BufferSlice(self, start, stop);
!     }
!     else
!     {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return NULL;
      }
***************
*** 1052,1075 ****
      static Py_ssize_t
  BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val)
  {
!     if (PyLong_Check(idx)) {
  	long n = PyLong_AsLong(idx);
  	return RBAsItem((BufferObject *)(self), n, val, 1,
  		    (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
  		    NULL);
!     } else if (PySlice_Check(idx)) {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  	      (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
  	      &start, &stop,
! 	      &step, &slicelen) < 0) {
  	    return -1;
  	}
  	return RBAsSlice((BufferObject *)(self), start, stop, val, 1,
  			  (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
  			  NULL);
!     } else {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return -1;
      }
--- 1181,1209 ----
      static Py_ssize_t
  BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val)
  {
!     if (PyLong_Check(idx))
!     {
  	long n = PyLong_AsLong(idx);
  	return RBAsItem((BufferObject *)(self), n, val, 1,
  		    (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
  		    NULL);
!     } else if (PySlice_Check(idx))
!     {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  	      (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
  	      &start, &stop,
! 	      &step, &slicelen) < 0)
! 	{
  	    return -1;
  	}
  	return RBAsSlice((BufferObject *)(self), start, stop, val, 1,
  			  (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
  			  NULL);
!     }
!     else
!     {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return -1;
      }
***************
*** 1142,1161 ****
      static PyObject *
  RangeSubscript(PyObject *self, PyObject* idx)
  {
!     if (PyLong_Check(idx)) {
  	long _idx = PyLong_AsLong(idx);
  	return RangeItem(self,_idx);
!     } else if (PySlice_Check(idx)) {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  		((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
  		&start, &stop,
! 		&step, &slicelen) < 0) {
  	    return NULL;
  	}
  	return RangeSlice(self, start, stop);
!     } else {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return NULL;
      }
--- 1276,1300 ----
      static PyObject *
  RangeSubscript(PyObject *self, PyObject* idx)
  {
!     if (PyLong_Check(idx))
!     {
  	long _idx = PyLong_AsLong(idx);
  	return RangeItem(self,_idx);
!     } else if (PySlice_Check(idx))
!     {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  		((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
  		&start, &stop,
! 		&step, &slicelen) < 0)
! 	{
  	    return NULL;
  	}
  	return RangeSlice(self, start, stop);
!     }
!     else
!     {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return NULL;
      }
***************
*** 1164,1183 ****
      static Py_ssize_t
  RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val)
  {
!     if (PyLong_Check(idx)) {
  	long n = PyLong_AsLong(idx);
  	return RangeAsItem(self, n, val);
!     } else if (PySlice_Check(idx)) {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  		((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
  		&start, &stop,
! 		&step, &slicelen) < 0) {
  	    return -1;
  	}
  	return RangeAsSlice(self, start, stop, val);
!     } else {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return -1;
      }
--- 1303,1327 ----
      static Py_ssize_t
  RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val)
  {
!     if (PyLong_Check(idx))
!     {
  	long n = PyLong_AsLong(idx);
  	return RangeAsItem(self, n, val);
!     } else if (PySlice_Check(idx))
!     {
  	Py_ssize_t start, stop, step, slicelen;
  
  	if (PySlice_GetIndicesEx((PyObject *)idx,
  		((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
  		&start, &stop,
! 		&step, &slicelen) < 0)
! 	{
  	    return -1;
  	}
  	return RangeAsSlice(self, start, stop, val);
!     }
!     else
!     {
  	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
  	return -1;
      }
***************
*** 1390,1395 ****
--- 1534,1680 ----
      }
  }
  
+ /* Dictionary object - Definitions
+  */
+ 
+ static PyInt DictionaryLength(PyObject *);
+ 
+ static PyMappingMethods DictionaryAsMapping = {
+     /* mp_length	*/ (lenfunc) DictionaryLength,
+     /* mp_subscript     */ (binaryfunc) DictionaryItem,
+     /* mp_ass_subscript */ (objobjargproc) DictionaryAssItem,
+ };
+ 
+ static PyTypeObject DictionaryType;
+ 
+     static void
+ DictionaryDestructor(PyObject *self)
+ {
+     DictionaryObject *this = (DictionaryObject *)(self);
+ 
+     pyll_remove(&this->ref, &lastdict);
+     dict_unref(this->dict);
+ 
+     Py_TYPE(self)->tp_free((PyObject*)self);
+ }
+ 
+ /* List object - Definitions
+  */
+ 
+ static PyInt ListLength(PyObject *);
+ static PyObject *ListItem(PyObject *, Py_ssize_t);
+ 
+ static PySequenceMethods ListAsSeq = {
+     (lenfunc)		ListLength,	 /* sq_length,	  len(x)   */
+     (binaryfunc)	0,		 /* RangeConcat, sq_concat,  x+y   */
+     (ssizeargfunc)	0,		 /* RangeRepeat, sq_repeat,  x*n   */
+     (ssizeargfunc)	ListItem,	 /* sq_item,	  x[i]	   */
+     (void *)		0,		 /* was_sq_slice,     x[i:j]   */
+     (ssizeobjargproc)	ListAssItem,	 /* sq_as_item,  x[i]=v   */
+     (void *)		0,		 /* was_sq_ass_slice, x[i:j]=v */
+     0,					 /* sq_contains */
+     (binaryfunc)	ListConcatInPlace,/* sq_inplace_concat */
+     0,					 /* sq_inplace_repeat */
+ };
+ 
+ static PyObject *ListSubscript(PyObject *, PyObject *);
+ static Py_ssize_t ListAsSubscript(PyObject *, PyObject *, PyObject *);
+ 
+ static PyMappingMethods ListAsMapping = {
+     /* mp_length	*/ (lenfunc) ListLength,
+     /* mp_subscript     */ (binaryfunc) ListSubscript,
+     /* mp_ass_subscript */ (objobjargproc) ListAsSubscript,
+ };
+ 
+ static PyTypeObject ListType;
+ 
+     static PyObject *
+ ListSubscript(PyObject *self, PyObject* idxObject)
+ {
+     if (PyLong_Check(idxObject))
+     {
+ 	long idx = PyLong_AsLong(idxObject);
+ 	return ListItem(self, idx);
+     }
+     else if (PySlice_Check(idxObject))
+     {
+ 	Py_ssize_t start, stop, step, slicelen;
+ 
+ 	if (PySlice_GetIndicesEx(idxObject, ListLength(self), &start, &stop,
+ 				 &step, &slicelen) < 0)
+ 	    return NULL;
+ 	return ListSlice(self, start, stop);
+     }
+     else
+     {
+ 	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
+ 	return NULL;
+     }
+ }
+ 
+     static Py_ssize_t
+ ListAsSubscript(PyObject *self, PyObject *idxObject, PyObject *obj)
+ {
+     if (PyLong_Check(idxObject))
+     {
+ 	long idx = PyLong_AsLong(idxObject);
+ 	return ListAssItem(self, idx, obj);
+     }
+     else if (PySlice_Check(idxObject))
+     {
+ 	Py_ssize_t start, stop, step, slicelen;
+ 
+ 	if (PySlice_GetIndicesEx(idxObject, ListLength(self), &start, &stop,
+ 				 &step, &slicelen) < 0)
+ 	    return -1;
+ 	return ListAssSlice(self, start, stop, obj);
+     }
+     else
+     {
+ 	PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
+ 	return -1;
+     }
+ }
+ 
+     static void
+ ListDestructor(PyObject *self)
+ {
+     ListObject *this = (ListObject *)(self);
+ 
+     pyll_remove(&this->ref, &lastlist);
+     list_unref(this->list);
+ 
+     Py_TYPE(self)->tp_free((PyObject*)self);
+ }
+ 
+ /* Function object - Definitions
+  */
+ 
+     static void
+ FunctionDestructor(PyObject *self)
+ {
+     FunctionObject	*this = (FunctionObject *) (self);
+ 
+     func_unref(this->name);
+     PyMem_Del(this->name);
+ 
+     Py_TYPE(self)->tp_free((PyObject*)self);
+ }
+ 
+     static PyObject *
+ FunctionGetattro(PyObject *self, PyObject *nameobj)
+ {
+     FunctionObject	*this = (FunctionObject *)(self);
+     char	*name = "";
+     if (PyUnicode_Check(nameobj))
+ 	name = _PyUnicode_AsString(nameobj);
+ 
+     if (strcmp(name, "name") == 0)
+ 	return PyUnicode_FromString((char *)(this->name));
+ 
+     return PyObject_GenericGetAttr(self, nameobj);
+ }
+ 
  /* External interface
   */
  
***************
*** 1449,1454 ****
--- 1734,1742 ----
      PyType_Ready(&BufListType);
      PyType_Ready(&WinListType);
      PyType_Ready(&CurrentType);
+     PyType_Ready(&DictionaryType);
+     PyType_Ready(&ListType);
+     PyType_Ready(&FunctionType);
  
      /* Set sys.argv[] to avoid a crash in warn(). */
      PySys_SetArgv(1, argv);
***************
*** 1517,1522 ****
--- 1805,1828 ----
      return result;
  }
  
+     void
+ do_py3eval (char_u *str, typval_T *rettv)
+ {
+     DoPy3Command(NULL, (char *) str, rettv);
+     switch(rettv->v_type)
+     {
+ 	case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
+ 	case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;
+ 	case VAR_FUNC: func_ref(rettv->vval.v_string);    break;
+     }
+ }
+ 
+     void
+ set_ref_in_python3 (int copyID)
+ {
+     set_ref_in_py(copyID);
+ }
+ 
      static void
  init_structs(void)
  {
***************
*** 1598,1603 ****
--- 1904,1938 ----
      CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
      CurrentType.tp_doc = "vim current object";
  
+     vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
+     DictionaryType.tp_name = "vim.dictionary";
+     DictionaryType.tp_basicsize = sizeof(DictionaryObject);
+     DictionaryType.tp_dealloc = DictionaryDestructor;
+     DictionaryType.tp_as_mapping = &DictionaryAsMapping;
+     DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
+     DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
+     DictionaryType.tp_methods = DictionaryMethods;
+ 
+     vim_memset(&ListType, 0, sizeof(ListType));
+     ListType.tp_name = "vim.list";
+     ListType.tp_dealloc = ListDestructor;
+     ListType.tp_basicsize = sizeof(ListObject);
+     ListType.tp_as_sequence = &ListAsSeq;
+     ListType.tp_as_mapping = &ListAsMapping;
+     ListType.tp_flags = Py_TPFLAGS_DEFAULT;
+     ListType.tp_doc = "list pushing modifications to vim structure";
+     ListType.tp_methods = ListMethods;
+ 
+     vim_memset(&FunctionType, 0, sizeof(FunctionType));
+     FunctionType.tp_name = "vim.list";
+     FunctionType.tp_basicsize = sizeof(FunctionObject);
+     FunctionType.tp_getattro = FunctionGetattro;
+     FunctionType.tp_dealloc = FunctionDestructor;
+     FunctionType.tp_call = FunctionCall;
+     FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
+     FunctionType.tp_doc = "object that calls vim function";
+     FunctionType.tp_methods = FunctionMethods;
+ 
      vim_memset(&vimmodule, 0, sizeof(vimmodule));
      vimmodule.m_name = "vim";
      vimmodule.m_doc = vim_module_doc;
*** ../vim-7.3.568/src/proto/eval.pro	2011-09-14 16:52:02.000000000 +0200
--- src/proto/eval.pro	2012-06-20 18:20:28.000000000 +0200
***************
*** 46,57 ****
--- 46,66 ----
  list_T *list_alloc __ARGS((void));
  void list_unref __ARGS((list_T *l));
  void list_free __ARGS((list_T *l, int recurse));
+ listitem_T *listitem_alloc __ARGS((void));
+ void listitem_remove __ARGS((list_T *l, listitem_T *item));
  dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
+ listitem_T *list_find __ARGS((list_T *l, long n));
  char_u *list_find_str __ARGS((list_T *l, long idx));
+ void list_append __ARGS((list_T *l, listitem_T *item));
  int list_append_tv __ARGS((list_T *l, typval_T *tv));
  int list_append_dict __ARGS((list_T *list, dict_T *dict));
  int list_append_string __ARGS((list_T *l, char_u *str, int len));
+ int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
+ void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
  int garbage_collect __ARGS((void));
+ void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
+ void set_ref_in_list __ARGS((list_T *l, int copyID));
+ void set_ref_in_item __ARGS((typval_T *tv, int copyID));
  dict_T *dict_alloc __ARGS((void));
  void dict_unref __ARGS((dict_T *d));
  dictitem_T *dictitem_alloc __ARGS((char_u *key));
***************
*** 64,69 ****
--- 73,79 ----
  long get_dict_number __ARGS((dict_T *d, char_u *key));
  char_u *get_function_name __ARGS((expand_T *xp, int idx));
  char_u *get_expr_name __ARGS((expand_T *xp, int idx));
+ int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv));
  long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit));
  void set_vim_var_nr __ARGS((int idx, long val));
  long get_vim_var_nr __ARGS((int idx));
***************
*** 94,99 ****
--- 104,111 ----
  void func_dump_profile __ARGS((FILE *fd));
  char_u *get_user_func_name __ARGS((expand_T *xp, int idx));
  void ex_delfunction __ARGS((exarg_T *eap));
+ void func_unref __ARGS((char_u *name));
+ void func_ref __ARGS((char_u *name));
  void ex_return __ARGS((exarg_T *eap));
  int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *rettv));
  void discard_pending_return __ARGS((void *rettv));
*** ../vim-7.3.568/src/proto/if_python.pro	2010-08-15 21:57:28.000000000 +0200
--- src/proto/if_python.pro	2012-06-20 18:23:06.000000000 +0200
***************
*** 6,9 ****
--- 6,11 ----
  void ex_pyfile __ARGS((exarg_T *eap));
  void python_buffer_free __ARGS((buf_T *buf));
  void python_window_free __ARGS((win_T *win));
+ void do_pyeval __ARGS((char_u *str, typval_T *rettv));
+ void set_ref_in_python __ARGS((int copyID));
  /* vim: set ft=c : */
*** ../vim-7.3.568/src/proto/if_python3.pro	2010-08-15 21:57:28.000000000 +0200
--- src/proto/if_python3.pro	2012-06-20 18:34:26.000000000 +0200
***************
*** 6,9 ****
--- 6,11 ----
  void ex_py3file __ARGS((exarg_T *eap));
  void python3_buffer_free __ARGS((buf_T *buf));
  void python3_window_free __ARGS((win_T *win));
+ void do_py3eval __ARGS((char_u *str, typval_T *rettv));
+ void set_ref_in_python3 __ARGS((int copyID));
  /* vim: set ft=c : */
*** ../vim-7.3.568/src/testdir/Make_amiga.mak	2012-04-05 16:56:38.000000000 +0200
--- src/testdir/Make_amiga.mak	2012-06-20 18:43:05.000000000 +0200
***************
*** 14,19 ****
--- 14,20 ----
  # test27	can't edit file with "*"
  # test52	only for Win32
  # test85	no Lua interface
+ # test86, 87	no Python interface
  
  SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
  		test7.out test8.out test9.out \
*** ../vim-7.3.568/src/testdir/Make_dos.mak	2012-04-13 19:11:16.000000000 +0200
--- src/testdir/Make_dos.mak	2012-06-20 18:43:45.000000000 +0200
***************
*** 30,36 ****
  		test68.out test69.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out
  
  SCRIPTS32 =	test50.out test70.out
  
--- 30,36 ----
  		test68.out test69.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out test86.out test87.out
  
  SCRIPTS32 =	test50.out test70.out
  
*** ../vim-7.3.568/src/testdir/Make_ming.mak	2012-04-13 19:11:16.000000000 +0200
--- src/testdir/Make_ming.mak	2012-06-20 18:44:12.000000000 +0200
***************
*** 50,56 ****
  		test68.out test69.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out
  
  SCRIPTS32 =	test50.out test70.out
  
--- 50,56 ----
  		test68.out test69.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out test86.out test87.out
  
  SCRIPTS32 =	test50.out test70.out
  
*** ../vim-7.3.568/src/testdir/Make_os2.mak	2012-04-05 16:56:38.000000000 +0200
--- src/testdir/Make_os2.mak	2012-06-20 18:44:32.000000000 +0200
***************
*** 14,19 ****
--- 14,20 ----
  # test27	can't edit file with "*" in file name
  # test52	only for Win32
  # test85	no Lua interface
+ # test86, 87	no Python interface
  
  SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
  		test7.out test8.out test9.out \
*** ../vim-7.3.568/src/testdir/Makefile	2012-04-05 16:56:38.000000000 +0200
--- src/testdir/Makefile	2012-06-29 11:56:00.000000000 +0200
***************
*** 27,33 ****
  		test69.out test70.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out
  
  SCRIPTS_GUI = test16.out
  
--- 27,33 ----
  		test69.out test70.out test71.out test72.out test73.out \
  		test74.out test75.out test76.out test77.out test78.out \
  		test79.out test80.out test81.out test82.out test83.out \
! 		test84.out test85.out test86.out test87.out
  
  SCRIPTS_GUI = test16.out
  
*** ../vim-7.3.568/src/testdir/test86.in	2012-06-20 20:19:31.000000000 +0200
--- src/testdir/test86.in	2012-06-20 18:01:02.000000000 +0200
***************
*** 0 ****
--- 1,211 ----
+ Tests for various python features.     vim: set ft=vim :
+ 
+ STARTTEST
+ :so small.vim
+ :if !has('python') | e! test.ok | wq! test.out | endif
+ :py import vim
+ :fun Test()
+ :let l = []
+ :py l=vim.bindeval('l')
+ :py f=vim.bindeval('function("strlen")')
+ :" Extending List directly with different types
+ :py l.extend([1, "as'd", [1, 2, f, {'a': 1}]])
+ :$put =string(l)
+ :$put =string(l[-1])
+ :try
+ :  $put =string(l[-4])
+ :catch
+ :  $put =v:exception[:13]
+ :endtry
+ :" List assignment
+ :py l[0]=0
+ :$put =string(l)
+ :py l[-2]=f
+ :$put =string(l)
+ :"
+ :" Extending Dictionary directly with different types
+ :let d = {}
+ :py d=vim.bindeval('d')
+ :py d['1']='asd'
+ :py d['b']=[1, 2, f]
+ :py d['-1']={'a': 1}
+ :let dkeys = []
+ :py dk=vim.bindeval('dkeys')
+ :py dkeys=d.keys()
+ :py dkeys.sort()
+ :py dk.extend(dkeys)
+ :$put =string(dkeys)
+ :for [key, val] in sort(items(d))
+ :  $put =string(key) . ' : ' . string(val)
+ :  unlet key val
+ :endfor
+ :"
+ :" removing items with del
+ :py del l[2]
+ :$put =string(l)
+ :let l = range(8)
+ :py l=vim.bindeval('l')
+ :try
+ :   py del l[:3]
+ :   py del l[1:]
+ :catch
+ :   $put =v:exception
+ :endtry
+ :$put =string(l)
+ :"
+ :py del d['-1']
+ :$put =string(d)
+ :"
+ :" removing items out of range: silently skip items that don't exist
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :" The following two ranges delete nothing as they match empty list:
+ :py del l[2:1]
+ :$put =string(l)
+ :py del l[2:2]
+ :$put =string(l)
+ :py del l[2:3]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[2:4]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[2:5]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[2:6]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :" The following two ranges delete nothing as they match empty list:
+ :py del l[-1:2]
+ :$put =string(l)
+ :py del l[-2:2]
+ :$put =string(l)
+ :py del l[-3:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[-4:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[-5:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py del l[-6:2]
+ :$put =string(l)
+ :"
+ :" Slice assignment to a list
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[0:0]=['a']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[1:2]=['b']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[2:4]=['c']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[4:4]=['d']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[-1:2]=['e']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[-10:2]=['f']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :py l[2:-10]=['g']
+ :$put =string(l)
+ :let l = []
+ :py l=vim.bindeval('l')
+ :py l[0:0]=['h']
+ :$put =string(l)
+ :"
+ :" Locked variables
+ :let l = [0, 1, 2, 3]
+ :py l=vim.bindeval('l')
+ :lockvar! l
+ :py l[2]='i'
+ :$put =string(l)
+ :unlockvar! l
+ :"
+ :" Function calls
+ :function New(...)
+ :return ['NewStart']+a:000+['NewEnd']
+ :endfunction
+ :function DictNew(...) dict
+ :return ['DictNewStart']+a:000+['DictNewEnd', self]
+ :endfunction
+ :let l=[function('New'), function('DictNew')]
+ :py l=vim.bindeval('l')
+ :py l.extend(list(l[0](1, 2, 3)))
+ :$put =string(l)
+ :py l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
+ :$put =string(l)
+ :py l.extend([l[0].name])
+ :$put =string(l)
+ :try
+ :   py l[1](1, 2, 3)
+ :catch
+ :   $put =v:exception[:16]
+ :endtry
+ :delfunction New
+ :try
+ :   py l[0](1, 2, 3)
+ :catch
+ :   $put =v:exception[:16]
+ :endtry
+ :if has('float')
+ :   let l=[0.0]
+ :   py l=vim.bindeval('l')
+ :   py l.extend([0.0])
+ :   $put =string(l)
+ :else
+ :   $put ='[0.0, 0.0]'
+ :endif
+ :"
+ :" pyeval()
+ :let l=pyeval('range(3)')
+ :$put =string(l)
+ :let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}')
+ :$put =sort(items(d))
+ :try
+ :   let undef=pyeval('undefined_name')
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :try
+ :   let vim=pyeval('vim')
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :if has('float')
+ :   let f=pyeval('0.0')
+ :   $put =string(f)
+ :else
+ :   $put ='0.0'
+ :endif
+ :endfun
+ :"
+ :call Test()
+ :"
+ :delfunc Test
+ :call garbagecollect(1)
+ :"
+ :/^start:/,$wq! test.out
+ ENDTEST
+ 
+ start:
*** ../vim-7.3.568/src/testdir/test86.ok	2012-06-20 20:19:31.000000000 +0200
--- src/testdir/test86.ok	2012-06-20 18:01:02.000000000 +0200
***************
*** 0 ****
--- 1,47 ----
+ start:
+ [1, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+ [1, 2, function('strlen'), {'a': 1}]
+ Vim(put):E684:
+ [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+ [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
+ ['-1', '1', 'b']
+ '-1' : {'a': 1}
+ '1' : 'asd'
+ 'b' : [1, 2, function('strlen')]
+ [0, function('strlen')]
+ [3]
+ {'1': 'asd', 'b': [1, 2, function('strlen')]}
+ [0, 1, 2, 3]
+ [0, 1, 2, 3]
+ [0, 1, 3]
+ [0, 1]
+ [0, 1]
+ [0, 1]
+ [0, 1, 2, 3]
+ [0, 1, 2, 3]
+ [0, 2, 3]
+ [2, 3]
+ [2, 3]
+ [2, 3]
+ ['a', 0, 1, 2, 3]
+ [0, 'b', 2, 3]
+ [0, 1, 'c']
+ [0, 1, 2, 3, 'd']
+ [0, 1, 2, 'e', 3]
+ ['f', 2, 3]
+ [0, 1, 'g', 2, 3]
+ ['h']
+ [0, 1, 2, 3]
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New']
+ Vim(python):E725:
+ Vim(python):E117:
+ [0.0, 0.0]
+ [0, 1, 2]
+ ['a', 'b']
+ ['c', 1]
+ ['d', ['e']]
+ Vim(let):E858:
+ Vim(let):E859:
+ 0.0
*** ../vim-7.3.568/src/testdir/test87.in	2012-06-20 20:19:31.000000000 +0200
--- src/testdir/test87.in	2012-06-20 18:01:02.000000000 +0200
***************
*** 0 ****
--- 1,211 ----
+ Tests for various python features.     vim: set ft=vim :
+ 
+ STARTTEST
+ :so small.vim
+ :if !has('python3') | e! test.ok | wq! test.out | endif
+ :py3 import vim
+ :fun Test()
+ :let l = []
+ :py3 l=vim.bindeval('l')
+ :py3 f=vim.bindeval('function("strlen")')
+ :" Extending List directly with different types
+ :py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]]
+ :$put =string(l)
+ :$put =string(l[-1])
+ :try
+ :  $put =string(l[-4])
+ :catch
+ :  $put =v:exception[:13]
+ :endtry
+ :" List assignment
+ :py3 l[0]=0
+ :$put =string(l)
+ :py3 l[-2]=f
+ :$put =string(l)
+ :"
+ :" Extending Dictionary directly with different types
+ :let d = {}
+ :py3 d=vim.bindeval('d')
+ :py3 d['1']='asd'
+ :py3 d['b']=[1, 2, f]
+ :py3 d['-1']={'a': 1}
+ :let dkeys = []
+ :py3 dk=vim.bindeval('dkeys')
+ :py3 dkeys=d.keys()
+ :py3 dkeys.sort()
+ :py3 dk+=dkeys
+ :$put =string(dkeys)
+ :for [key, val] in sort(items(d))
+ :  $put =string(key) . ' : ' . string(val)
+ :  unlet key val
+ :endfor
+ :"
+ :" removing items with del
+ :py3 del l[2]
+ :$put =string(l)
+ :let l = range(8)
+ :py3 l=vim.bindeval('l')
+ :try
+ :   py3 del l[:3]
+ :   py3 del l[1:]
+ :catch
+ :   $put =v:exception
+ :endtry
+ :$put =string(l)
+ :"
+ :py3 del d['-1']
+ :$put =string(d)
+ :"
+ :" removing items out of range: silently skip items that don't exist
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :" The following two ranges delete nothing as they match empty list:
+ :py3 del l[2:1]
+ :$put =string(l)
+ :py3 del l[2:2]
+ :$put =string(l)
+ :py3 del l[2:3]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[2:4]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[2:5]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[2:6]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :" The following two ranges delete nothing as they match empty list:
+ :py3 del l[-1:2]
+ :$put =string(l)
+ :py3 del l[-2:2]
+ :$put =string(l)
+ :py3 del l[-3:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[-4:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[-5:2]
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 del l[-6:2]
+ :$put =string(l)
+ :"
+ :" Slice assignment to a list
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[0:0]=['a']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[1:2]=['b']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[2:4]=['c']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[4:4]=['d']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[-1:2]=['e']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[-10:2]=['f']
+ :$put =string(l)
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :py3 l[2:-10]=['g']
+ :$put =string(l)
+ :let l = []
+ :py3 l=vim.bindeval('l')
+ :py3 l[0:0]=['h']
+ :$put =string(l)
+ :"
+ :" Locked variables
+ :let l = [0, 1, 2, 3]
+ :py3 l=vim.bindeval('l')
+ :lockvar! l
+ :py3 l[2]='i'
+ :$put =string(l)
+ :unlockvar! l
+ :"
+ :" Function calls
+ :function New(...)
+ :return ['NewStart']+a:000+['NewEnd']
+ :endfunction
+ :function DictNew(...) dict
+ :return ['DictNewStart']+a:000+['DictNewEnd', self]
+ :endfunction
+ :let l=[function('New'), function('DictNew')]
+ :py3 l=vim.bindeval('l')
+ :py3 l.extend(list(l[0](1, 2, 3)))
+ :$put =string(l)
+ :py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
+ :$put =string(l)
+ :py3 l+=[l[0].name]
+ :$put =string(l)
+ :try
+ :   py3 l[1](1, 2, 3)
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :delfunction New
+ :try
+ :   py3 l[0](1, 2, 3)
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :if has('float')
+ :   let l=[0.0]
+ :   py3 l=vim.bindeval('l')
+ :   py3 l.extend([0.0])
+ :   $put =string(l)
+ :else
+ :   $put ='[0.0, 0.0]'
+ :endif
+ :"
+ :" py3eval()
+ :let l=py3eval('[0, 1, 2]')
+ :$put =string(l)
+ :let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}')
+ :$put =sort(items(d))
+ :try
+ :   let undef=py3eval('undefined_name')
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :try
+ :   let vim=py3eval('vim')
+ :catch
+ :   $put =v:exception[:13]
+ :endtry
+ :if has('float')
+ :   let f=py3eval('0.0')
+ :   $put =string(f)
+ :else
+ :   $put ='0.0'
+ :endif
+ :endfun
+ :"
+ :call Test()
+ :"
+ :delfunc Test
+ :call garbagecollect(1)
+ :"
+ :/^start:/,$wq! test.out
+ ENDTEST
+ 
+ start:
*** ../vim-7.3.568/src/testdir/test87.ok	2012-06-20 20:19:31.000000000 +0200
--- src/testdir/test87.ok	2012-06-20 18:01:02.000000000 +0200
***************
*** 0 ****
--- 1,47 ----
+ start:
+ [1, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+ [1, 2, function('strlen'), {'a': 1}]
+ Vim(put):E684:
+ [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+ [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
+ ['-1', '1', 'b']
+ '-1' : {'a': 1}
+ '1' : 'asd'
+ 'b' : [1, 2, function('strlen')]
+ [0, function('strlen')]
+ [3]
+ {'1': 'asd', 'b': [1, 2, function('strlen')]}
+ [0, 1, 2, 3]
+ [0, 1, 2, 3]
+ [0, 1, 3]
+ [0, 1]
+ [0, 1]
+ [0, 1]
+ [0, 1, 2, 3]
+ [0, 1, 2, 3]
+ [0, 2, 3]
+ [2, 3]
+ [2, 3]
+ [2, 3]
+ ['a', 0, 1, 2, 3]
+ [0, 'b', 2, 3]
+ [0, 1, 'c']
+ [0, 1, 2, 3, 'd']
+ [0, 1, 2, 'e', 3]
+ ['f', 2, 3]
+ [0, 1, 'g', 2, 3]
+ ['h']
+ [0, 1, 2, 3]
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
+ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New']
+ Vim(py3):E725:
+ Vim(py3):E117:
+ [0.0, 0.0]
+ [0, 1, 2]
+ ['a', 'b']
+ ['c', 1]
+ ['d', ['e']]
+ Vim(let):E860:
+ Vim(let):E861:
+ 0.0
*** ../vim-7.3.568/src/version.c	2012-06-29 12:35:40.000000000 +0200
--- src/version.c	2012-06-29 12:47:03.000000000 +0200
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     569,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
69. Yahoo welcomes you with your own start page

 /// Bram Moolenaar -- Bram@Moolenaar.net -- 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    ///