1" Test for python 3 commands.
2
3source check.vim
4CheckFeature python3
5source shared.vim
6
7func Create_vim_list()
8  return [1]
9endfunction
10
11func Create_vim_dict()
12  return {'a': 1}
13endfunction
14
15let s:system_error_pat = 'Vim(py3):SystemError: \(<built-in function eval> returned NULL without setting an \(error\|exception\)\|error return without exception set\)'
16
17" This function should be called first. This sets up python functions used by
18" the other tests.
19func Test_AAA_python3_setup()
20  py3 << trim EOF
21    import vim
22    import sys
23    import re
24
25    py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
26    py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
27    py39_type_error_pattern = re.compile('\w+\.([^(]+\(\) takes)')
28    py310_type_error_pattern = re.compile('takes (\d+) positional argument but (\d+) were given')
29
30    def emsg(ei):
31      return ei[0].__name__ + ':' + repr(ei[1].args)
32
33    def ee(expr, g=globals(), l=locals()):
34        cb = vim.current.buffer
35        try:
36            try:
37                exec(expr, g, l)
38            except Exception as e:
39                if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."):
40                    msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
41                elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
42                    msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
43                elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
44                    # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
45                    msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
46                elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
47                    m = py33_type_error_pattern.search(str(e))
48                    if m:
49                        msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
50                        msg = repr((e.__class__, TypeError(msg)))
51                    else:
52                        msg = repr((e.__class__, e))
53                        # Messages changed with Python 3.6, change new to old.
54                        newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
55                        oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
56                        if msg.find(newmsg1) > -1:
57                            msg = msg.replace(newmsg1, oldmsg1)
58                        newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
59                        oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
60                        if msg.find(newmsg2) > -1:
61                            msg = msg.replace(newmsg2, oldmsg2)
62                        # Python 3.9 reports errors like "vim.command() takes ..." instead of "command() takes ..."
63                        msg = py39_type_error_pattern.sub(r'\1', msg)
64                        msg = py310_type_error_pattern.sub(r'takes exactly \1 positional argument (\2 given)', msg)
65                elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
66                    msg = repr((TypeError, TypeError('expected bytes with no null')))
67                else:
68                    msg = repr((e.__class__, e))
69                    # Some Python versions say can't, others cannot.
70                    if msg.find('can\'t') > -1:
71                        msg = msg.replace('can\'t', 'cannot')
72                    # Some Python versions use single quote, some double quote
73                    if msg.find('"cannot ') > -1:
74                        msg = msg.replace('"cannot ', '\'cannot ')
75                    if msg.find(' attributes"') > -1:
76                        msg = msg.replace(' attributes"', ' attributes\'')
77                if sys.version_info >= (3, 7):
78                    msg = py37_exception_repr.sub(r'\1,\2', msg)
79                cb.append(expr + ':' + msg)
80            else:
81                cb.append(expr + ':NOT FAILED')
82        except Exception as e:
83            msg = repr((e.__class__, e))
84            if sys.version_info >= (3, 7):
85                msg = py37_exception_repr.sub(r'\1,\2', msg)
86            cb.append(expr + '::' + msg)
87  EOF
88endfunc
89
90func Test_py3do()
91  " Check deleting lines does not trigger an ml_get error.
92  new
93  call setline(1, ['one', 'two', 'three'])
94  py3do vim.command("%d_")
95  bwipe!
96
97  " Check switching to another buffer does not trigger an ml_get error.
98  new
99  let wincount = winnr('$')
100  call setline(1, ['one', 'two', 'three'])
101  py3do vim.command("new")
102  call assert_equal(wincount + 1, winnr('$'))
103  bwipe!
104  bwipe!
105
106  " Try modifying a buffer with 'nomodifiable' set
107  set nomodifiable
108  call assert_fails('py3do toupper(line)', 'E21:')
109  set modifiable
110
111  " Invalid command
112  call AssertException(['py3do non_existing_cmd'],
113        \ "Vim(py3do):NameError: name 'non_existing_cmd' is not defined")
114  call AssertException(["py3do raise Exception('test')"],
115        \ 'Vim(py3do):Exception: test')
116  call AssertException(["py3do {lambda}"],
117        \ 'Vim(py3do):SyntaxError: invalid syntax')
118endfunc
119
120func Test_set_cursor()
121  " Check that setting the cursor position works.
122  new
123  call setline(1, ['first line', 'second line'])
124  normal gg
125  py3do vim.current.window.cursor = (1, 5)
126  call assert_equal([1, 6], [line('.'), col('.')])
127
128  " Check that movement after setting cursor position keeps current column.
129  normal j
130  call assert_equal([2, 6], [line('.'), col('.')])
131endfunc
132
133func Test_vim_function()
134  " Check creating vim.Function object
135
136  func s:foo()
137    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
138  endfunc
139  let name = '<SNR>' . s:foo()
140
141  try
142    py3 f = vim.bindeval('function("s:foo")')
143    call assert_equal(name, py3eval('f.name'))
144  catch
145    call assert_false(v:exception)
146  endtry
147
148  try
149    py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
150    call assert_equal(name, 'f.name'->py3eval())
151  catch
152    call assert_false(v:exception)
153  endtry
154
155  " Non-existing function attribute
156  call AssertException(["let x = py3eval('f.abc')"],
157        \ "Vim(let):AttributeError: 'vim.function' object has no attribute 'abc'")
158
159  py3 del f
160  delfunc s:foo
161endfunc
162
163func Test_skipped_python3_command_does_not_affect_pyxversion()
164  set pyxversion=0
165  if 0
166    python3 import vim
167  endif
168  call assert_equal(0, &pyxversion)  " This assertion would have failed with Vim 8.0.0251. (pyxversion was introduced in 8.0.0251.)
169endfunc
170
171func _SetUpHiddenBuffer()
172  new
173  edit hidden
174  setlocal bufhidden=hide
175
176  enew
177  let lnum = 0
178  while lnum < 10
179    call append( 1, string( lnum ) )
180    let lnum = lnum + 1
181  endwhile
182  normal G
183
184  call assert_equal( line( '.' ), 11 )
185endfunc
186
187func _CleanUpHiddenBuffer()
188  bwipe! hidden
189  bwipe!
190endfunc
191
192func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Clear()
193  call _SetUpHiddenBuffer()
194  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = None
195  call assert_equal( line( '.' ), 11 )
196  call _CleanUpHiddenBuffer()
197endfunc
198
199func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_List()
200  call _SetUpHiddenBuffer()
201  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = [ 'test' ]
202  call assert_equal( line( '.' ), 11 )
203  call _CleanUpHiddenBuffer()
204endfunc
205
206func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Str()
207  call _SetUpHiddenBuffer()
208  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = 'test'
209  call assert_equal( line( '.' ), 11 )
210  call _CleanUpHiddenBuffer()
211endfunc
212
213func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_ClearLine()
214  call _SetUpHiddenBuffer()
215  py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = None
216  call assert_equal( line( '.' ), 11 )
217  call _CleanUpHiddenBuffer()
218endfunc
219
220func _SetUpVisibleBuffer()
221  new
222  let lnum = 0
223  while lnum < 10
224    call append( 1, string( lnum ) )
225    let lnum = lnum + 1
226  endwhile
227  normal G
228  call assert_equal( line( '.' ), 11 )
229endfunc
230
231func Test_Write_To_Current_Buffer_Fixes_Cursor_Clear()
232  call _SetUpVisibleBuffer()
233
234  py3 vim.current.buffer[:] = None
235  call assert_equal( line( '.' ), 1 )
236
237  bwipe!
238endfunc
239
240func Test_Write_To_Current_Buffer_Fixes_Cursor_List()
241  call _SetUpVisibleBuffer()
242
243  py3 vim.current.buffer[:] = [ 'test' ]
244  call assert_equal( line( '.' ), 1 )
245
246  bwipe!
247endfunc
248
249func Test_Write_To_Current_Buffer_Fixes_Cursor_Str()
250  call _SetUpVisibleBuffer()
251
252  py3 vim.current.buffer[-1] = None
253  call assert_equal( line( '.' ), 10 )
254
255  bwipe!
256endfunc
257
258func Test_Catch_Exception_Message()
259  try
260    py3 raise RuntimeError( 'TEST' )
261  catch /.*/
262    call assert_match( '^Vim(.*):RuntimeError: TEST$', v:exception )
263  endtry
264endfunc
265
266func Test_unicode()
267  " this crashed Vim once
268  if &tenc != ''
269    throw "Skipped: 'termencoding' is not empty"
270  endif
271
272  set encoding=utf32
273  py3 print('hello')
274
275  if !has('win32')
276    set encoding=debug
277    py3 print('hello')
278
279    set encoding=euc-tw
280    py3 print('hello')
281  endif
282
283  set encoding=utf8
284endfunc
285
286" Test vim.eval() with various types.
287func Test_python3_vim_val()
288  call assert_equal("\n8",             execute('py3 print(vim.eval("3+5"))'))
289  if has('float')
290    call assert_equal("\n3.140000",    execute('py3 print(vim.eval("1.01+2.13"))'))
291    call assert_equal("\n0.000000",    execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
292    call assert_equal("\n0.000000",    execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
293    call assert_equal("\n-0.000000",   execute('py3 print(vim.eval("0.0/(-1.0/0.0)"))'))
294    " Commented out: output of infinity and nan depend on platforms.
295    " call assert_equal("\ninf",         execute('py3 print(vim.eval("1.0/0.0"))'))
296    " call assert_equal("\n-inf",        execute('py3 print(vim.eval("-1.0/0.0"))'))
297    " call assert_equal("\n-nan",        execute('py3 print(vim.eval("0.0/0.0"))'))
298  endif
299  call assert_equal("\nabc",           execute('py3 print(vim.eval("\"abc\""))'))
300  call assert_equal("\n['1', '2']",    execute('py3 print(vim.eval("[1, 2]"))'))
301  call assert_equal("\n{'1': '2'}",    execute('py3 print(vim.eval("{1:2}"))'))
302  call assert_equal("\nTrue",          execute('py3 print(vim.eval("v:true"))'))
303  call assert_equal("\nFalse",         execute('py3 print(vim.eval("v:false"))'))
304  call assert_equal("\nNone",          execute('py3 print(vim.eval("v:null"))'))
305  call assert_equal("\nNone",          execute('py3 print(vim.eval("v:none"))'))
306  call assert_equal("\nb'\\xab\\x12'", execute('py3 print(vim.eval("0zab12"))'))
307
308  call assert_fails('py3 vim.eval("1+")', 'E15: Invalid expression')
309endfunc
310
311" Test range objects, see :help python-range
312func Test_python3_range()
313  new
314  py3 b = vim.current.buffer
315
316  call setline(1, range(1, 6))
317  py3 r = b.range(2, 4)
318  call assert_equal(6, py3eval('len(b)'))
319  call assert_equal(3, py3eval('len(r)'))
320  call assert_equal('3', py3eval('b[2]'))
321  call assert_equal('4', py3eval('r[2]'))
322
323  call assert_fails('py3 r[3] = "x"', ['Traceback', 'IndexError: line number out of range'])
324  call assert_fails('py3 x = r[3]', ['Traceback', 'IndexError: line number out of range'])
325  call assert_fails('py3 r["a"] = "x"', ['Traceback', 'TypeError: index must be int or slice, not str'])
326  call assert_fails('py3 x = r["a"]', ['Traceback', 'TypeError: index must be int or slice, not str'])
327
328  py3 del r[:]
329  call assert_equal(['1', '5', '6'], getline(1, '$'))
330
331  %d | call setline(1, range(1, 6))
332  py3 r = b.range(2, 5)
333  py3 del r[2]
334  call assert_equal(['1', '2', '3', '5', '6'], getline(1, '$'))
335
336  %d | call setline(1, range(1, 6))
337  py3 r = b.range(2, 4)
338  py3 vim.command("%d,%dnorm Ax" % (r.start + 1, r.end + 1))
339  call assert_equal(['1', '2x', '3x', '4x', '5', '6'], getline(1, '$'))
340
341  %d | call setline(1, range(1, 4))
342  py3 r = b.range(2, 3)
343  py3 r.append(['a', 'b'])
344  call assert_equal(['1', '2', '3', 'a', 'b', '4'], getline(1, '$'))
345  py3 r.append(['c', 'd'], 0)
346  call assert_equal(['1', 'c', 'd', '2', '3', 'a', 'b', '4'], getline(1, '$'))
347
348  %d | call setline(1, range(1, 5))
349  py3 r = b.range(2, 4)
350  py3 r.append('a')
351  call assert_equal(['1', '2', '3', '4', 'a', '5'], getline(1, '$'))
352  py3 r.append('b', 1)
353  call assert_equal(['1', '2', 'b', '3', '4', 'a', '5'], getline(1, '$'))
354
355  bwipe!
356endfunc
357
358" Test for resetting options with local values to global values
359func Test_python3_opt_reset_local_to_global()
360  new
361
362  py3 curbuf = vim.current.buffer
363  py3 curwin = vim.current.window
364
365  " List of buffer-local options. Each list item has [option name, global
366  " value, buffer-local value, buffer-local value after reset] to use in the
367  " test.
368  let bopts = [
369        \ ['autoread', 1, 0, -1],
370        \ ['equalprg', 'geprg', 'leprg', ''],
371        \ ['keywordprg', 'gkprg', 'lkprg', ''],
372        \ ['path', 'gpath', 'lpath', ''],
373        \ ['backupcopy', 'yes', 'no', ''],
374        \ ['tags', 'gtags', 'ltags', ''],
375        \ ['tagcase', 'ignore', 'match', ''],
376        \ ['define', 'gdef', 'ldef', ''],
377        \ ['include', 'ginc', 'linc', ''],
378        \ ['dict', 'gdict', 'ldict', ''],
379        \ ['thesaurus', 'gtsr', 'ltsr', ''],
380        \ ['formatprg', 'gfprg', 'lfprg', ''],
381        \ ['errorformat', '%f:%l:%m', '%s-%l-%m', ''],
382        \ ['grepprg', 'ggprg', 'lgprg', ''],
383        \ ['makeprg', 'gmprg', 'lmprg', ''],
384        \ ['balloonexpr', 'gbexpr', 'lbexpr', ''],
385        \ ['cryptmethod', 'blowfish2', 'zip', ''],
386        \ ['lispwords', 'abc', 'xyz', ''],
387        \ ['makeencoding', 'utf-8', 'latin1', ''],
388        \ ['undolevels', 100, 200, -123456]]
389
390  " Set the global and buffer-local option values and then clear the
391  " buffer-local option value.
392  for opt in bopts
393    py3 << trim END
394      pyopt = vim.bindeval("opt")
395      vim.options[pyopt[0]] = pyopt[1]
396      curbuf.options[pyopt[0]] = pyopt[2]
397    END
398    exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
399    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
400    exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
401    py3 del curbuf.options[pyopt[0]]
402    exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
403    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
404    exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
405    exe "set " .. opt[0] .. "&"
406  endfor
407
408  " Set the global and window-local option values and then clear the
409  " window-local option value.
410  let wopts = [
411        \ ['scrolloff', 5, 10, -1],
412        \ ['sidescrolloff', 6, 12, -1],
413        \ ['statusline', '%<%f', '%<%F', '']]
414  for opt in wopts
415    py3 << trim
416      pyopt = vim.bindeval("opt")
417      vim.options[pyopt[0]] = pyopt[1]
418      curwin.options[pyopt[0]] = pyopt[2]
419    .
420    exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
421    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
422    exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
423    py3 del curwin.options[pyopt[0]]
424    exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
425    exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
426    exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
427    exe "set " .. opt[0] .. "&"
428  endfor
429
430  close!
431endfunc
432
433" Test for various heredoc syntax
434func Test_python3_heredoc()
435  python3 << END
436s='A'
437END
438  python3 <<
439s+='B'
440.
441  python3 << trim END
442    s+='C'
443  END
444  python3 << trim
445    s+='D'
446  .
447  python3 << trim eof
448    s+='E'
449  eof
450  call assert_equal('ABCDE', pyxeval('s'))
451endfunc
452
453" Test for the buffer range object
454func Test_python3_range2()
455  new
456  call setline(1, ['one', 'two', 'three'])
457  py3 b = vim.current.buffer
458  py3 r = b.range(1, 3)
459  call assert_equal(0, py3eval('r.start'))
460  call assert_equal(2, py3eval('r.end'))
461  call assert_equal('one', py3eval('r[0]'))
462  call assert_equal('one', py3eval('r[-3]'))
463  call AssertException(["let x = py3eval('r[-4]')"],
464        \ 'Vim(let):IndexError: line number out of range')
465  call assert_equal(['two', 'three'], py3eval('r[1:]'))
466  py3 r[0] = 'green'
467  call assert_equal(['green', 'two', 'three'], getline(1, '$'))
468  py3 r[0:2] = ['red', 'blue']
469  call assert_equal(['red', 'blue', 'three'], getline(1, '$'))
470
471  " try different invalid start/end index for the range slice
472  %d
473  call setline(1, ['one', 'two', 'three'])
474  py3 r[-10:1] = ["a"]
475  py3 r[10:12] = ["b"]
476  py3 r[-10:-9] = ["c"]
477  py3 r[1:0] = ["d"]
478  call assert_equal(['c', 'd', 'a', 'two', 'three', 'b'], getline(1, '$'))
479
480  " The following code used to trigger an ml_get error
481  %d
482  let x = py3eval('r[:]')
483
484  " Non-existing range attribute
485  call AssertException(["let x = py3eval('r.abc')"],
486        \ "Vim(let):AttributeError: 'vim.range' object has no attribute 'abc'")
487
488  close!
489endfunc
490
491" Test for the python tabpage object
492func Test_python3_tabpage()
493  tabnew
494  py3 t = vim.tabpages[1]
495  py3 wl = t.windows
496  tabclose
497  " Accessing a closed tabpage
498  call AssertException(["let n = py3eval('t.number')"],
499        \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
500  call AssertException(["let n = py3eval('len(wl)')"],
501        \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
502  call AssertException(["py3 w = wl[0]"],
503        \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
504  call AssertException(["py3 vim.current.tabpage = t"],
505        \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
506  call assert_match('<tabpage object (deleted)', py3eval('repr(t)'))
507  %bw!
508endfunc
509
510" Test for the python window object
511func Test_python3_window()
512  " Test for setting the window height
513  10new
514  py3 vim.current.window.height = 5
515  call assert_equal(5, winheight(0))
516  py3 vim.current.window.height = 3.2
517  call assert_equal(3, winheight(0))
518
519  " Test for setting the window width
520  10vnew
521  py3 vim.current.window.width = 6
522  call assert_equal(6, winwidth(0))
523
524  " Try accessing a closed window
525  py3 w = vim.current.window
526  py3 wopts = w.options
527  close
528  " Access the attributes of a closed window
529  call AssertException(["let n = py3eval('w.number')"],
530        \ 'Vim(let):vim.error: attempt to refer to deleted window')
531  call AssertException(["py3 w.height = 5"],
532        \ 'Vim(py3):vim.error: attempt to refer to deleted window')
533  call AssertException(["py3 vim.current.window = w"],
534        \ 'Vim(py3):vim.error: attempt to refer to deleted window')
535  " Try to set one of the options of the closed window
536  " The following caused ASAN failure
537  call AssertException(["py3 wopts['list'] = False"],
538        \ 'Vim(py3):vim.error: attempt to refer to deleted window')
539  call assert_match('<window object (deleted)', py3eval("repr(w)"))
540  %bw!
541endfunc
542
543" Test for the python List object
544func Test_python3_list()
545  " Try to convert a null List
546  call AssertException(["py3 t = vim.eval('test_null_list()')"],
547        \ s:system_error_pat)
548
549  " Try to convert a List with a null List item
550  call AssertException(["py3 t = vim.eval('[test_null_list()]')"],
551        \ s:system_error_pat)
552
553  " Try to bind a null List variable (works because an empty list is used)
554  let cmds =<< trim END
555    let l = test_null_list()
556    py3 ll = vim.bindeval('l')
557  END
558  call AssertException(cmds, '')
559
560  let l = []
561  py3 l = vim.bindeval('l')
562  py3 f = vim.bindeval('function("strlen")')
563  " Extending List directly with different types
564  py3 l += [1, "as'd", [1, 2, f, {'a': 1}]]
565  call assert_equal([1, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
566  call assert_equal([1, 2, function("strlen"), {'a': 1}], l[-1])
567  call assert_fails('echo l[-4]', 'E684:')
568
569  " List assignment
570  py3 l[0] = 0
571  call assert_equal([0, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
572  py3 l[-2] = f
573  call assert_equal([0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]], l)
574
575  " appending to a list
576  let l = [1, 2]
577  py3 ll = vim.bindeval('l')
578  py3 ll[2] = 8
579  call assert_equal([1, 2, 8], l)
580
581  " iterating over list from Python
582  py3 print([x for x in vim.Function("getline")(1, 2)])
583
584  " Using dict as an index
585  call AssertException(['py3 ll[{}] = 10'],
586        \ 'Vim(py3):TypeError: index must be int or slice, not dict')
587endfunc
588
589" Test for the python Dict object
590func Test_python3_dict()
591  " Try to convert a null Dict
592  call AssertException(["py3 t = vim.eval('test_null_dict()')"],
593        \ s:system_error_pat)
594
595  " Try to convert a Dict with a null List value
596  call AssertException(["py3 t = vim.eval(\"{'a' : test_null_list()}\")"],
597        \ s:system_error_pat)
598
599  " Try to convert a Dict with a null string key
600  py3 t = vim.eval("{test_null_string() : 10}")
601  call assert_fails("let d = py3eval('t')", 'E859:')
602
603  " Dict length
604  let d = {'a' : 10, 'b' : 20}
605  py3 d = vim.bindeval('d')
606  call assert_equal(2, py3eval('len(d)'))
607
608  " Deleting a non-existing key
609  call AssertException(["py3 del d['c']"], "Vim(py3):KeyError: 'c'")
610endfunc
611
612" Extending Dictionary directly with different types
613func Test_python3_dict_extend()
614  let d = {}
615  func d.f()
616    return 1
617  endfunc
618
619  py3 f = vim.bindeval('function("strlen")')
620  py3 << trim EOF
621    d = vim.bindeval('d')
622    d['1'] = 'asd'
623    d.update()  # Must not do anything, including throwing errors
624    d.update(b = [1, 2, f])
625    d.update((('-1', {'a': 1}),))
626    d.update({'0': -1})
627    dk = d.keys()
628    dv = d.values()
629    di = d.items()
630    dk.sort(key=repr)
631    dv.sort(key=repr)
632    di.sort(key=repr)
633  EOF
634
635  " Try extending a locked dictionary
636  lockvar d
637  call AssertException(["py3 d.update({'b' : 20})"],
638        \ 'Vim(py3):vim.error: dictionary is locked')
639  unlockvar d
640
641  call assert_equal(1, py3eval("d['f'](self={})"))
642  call assert_equal("[b'-1', b'0', b'1', b'b', b'f']", py3eval('repr(dk)'))
643  call assert_equal("[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd']", substitute(py3eval('repr(dv)'),'0x\x\+','','g'))
644  call assert_equal("[(b'-1', <vim.dictionary object at >), (b'0', -1), (b'1', b'asd'), (b'b', <vim.list object at >), (b'f', <vim.Function '1'>)]", substitute(py3eval('repr(di)'),'0x\x\+','','g'))
645  call assert_equal(['0', '1', 'b', 'f', '-1'], keys(d))
646  call assert_equal("[-1, 'asd', [1, 2, function('strlen')], function('1'), {'a': 1}]", string(values(d)))
647  py3 del dk
648  py3 del di
649  py3 del dv
650endfunc
651
652func Test_python3_list_del_items()
653  " removing items with del
654  let l = [0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]]
655  py3 l = vim.bindeval('l')
656  py3 del l[2]
657  call assert_equal("[0, function('strlen')]", string(l))
658
659  let l = range(8)
660  py3 l = vim.bindeval('l')
661  py3 del l[:3]
662  py3 del l[1:]
663  call assert_equal([3], l)
664
665  " removing items out of range: silently skip items that don't exist
666
667  " The following two ranges delete nothing as they match empty list:
668  let l = [0, 1, 2, 3]
669  py3 l = vim.bindeval('l')
670  py3 del l[2:1]
671  call assert_equal([0, 1, 2, 3], l)
672  py3 del l[2:2]
673  call assert_equal([0, 1, 2, 3], l)
674  py3 del l[2:3]
675  call assert_equal([0, 1, 3], l)
676
677  let l = [0, 1, 2, 3]
678  py3 l = vim.bindeval('l')
679  py3 del l[2:4]
680  call assert_equal([0, 1], l)
681
682  let l = [0, 1, 2, 3]
683  py3 l = vim.bindeval('l')
684  py3 del l[2:5]
685  call assert_equal([0, 1], l)
686
687  let l = [0, 1, 2, 3]
688  py3 l = vim.bindeval('l')
689  py3 del l[2:6]
690  call assert_equal([0, 1], l)
691
692  " The following two ranges delete nothing as they match empty list:
693  let l = [0, 1, 2, 3]
694  py3 l = vim.bindeval('l')
695  py3 del l[-1:2]
696  call assert_equal([0, 1, 2, 3], l)
697  py3 del l[-2:2]
698  call assert_equal([0, 1, 2, 3], l)
699  py3 del l[-3:2]
700  call assert_equal([0, 2, 3], l)
701
702  let l = [0, 1, 2, 3]
703  py3 l = vim.bindeval('l')
704  py3 del l[-4:2]
705  call assert_equal([2, 3], l)
706
707  let l = [0, 1, 2, 3]
708  py3 l = vim.bindeval('l')
709  py3 del l[-5:2]
710  call assert_equal([2, 3], l)
711
712  let l = [0, 1, 2, 3]
713  py3 l = vim.bindeval('l')
714  py3 del l[-6:2]
715  call assert_equal([2, 3], l)
716
717  let l = [0, 1, 2, 3]
718  py3 l = vim.bindeval('l')
719  py3 del l[::2]
720  call assert_equal([1, 3], l)
721
722  let l = [0, 1, 2, 3]
723  py3 l = vim.bindeval('l')
724  py3 del l[3:0:-2]
725  call assert_equal([0, 2], l)
726
727  let l = [0, 1, 2, 3]
728  py3 l = vim.bindeval('l')
729  py3 del l[2:4:-2]
730  let l = [0, 1, 2, 3]
731endfunc
732
733func Test_python3_dict_del_items()
734  let d = eval("{'0' : -1, '1' : 'asd', 'b' : [1, 2, function('strlen')], 'f' : function('min'), '-1' : {'a': 1}}")
735  py3 d = vim.bindeval('d')
736  py3 del d['-1']
737  py3 del d['f']
738  call assert_equal([1, 2, function('strlen')], py3eval('d.get(''b'', 1)'))
739  call assert_equal([1, 2, function('strlen')], py3eval('d.pop(''b'')'))
740  call assert_equal(1, py3eval('d.get(''b'', 1)'))
741  call assert_equal('asd', py3eval('d.pop(''1'', 2)'))
742  call assert_equal(2, py3eval('d.pop(''1'', 2)'))
743  call assert_equal('True', py3eval('repr(d.has_key(''0''))'))
744  call assert_equal('False', py3eval('repr(d.has_key(''1''))'))
745  call assert_equal('True', py3eval('repr(''0'' in d)'))
746  call assert_equal('False', py3eval('repr(''1'' in d)'))
747  call assert_equal("[b'0']", py3eval('repr(list(iter(d)))'))
748  call assert_equal({'0' : -1}, d)
749  call assert_equal("(b'0', -1)", py3eval('repr(d.popitem())'))
750  call assert_equal('None', py3eval('repr(d.get(''0''))'))
751  call assert_equal('[]', py3eval('repr(list(iter(d)))'))
752endfunc
753
754" Slice assignment to a list
755func Test_python3_slice_assignment()
756  let l = [0, 1, 2, 3]
757  py3 l = vim.bindeval('l')
758  py3 l[0:0] = ['a']
759  call assert_equal(['a', 0, 1, 2, 3], l)
760
761  let l = [0, 1, 2, 3]
762  py3 l = vim.bindeval('l')
763  py3 l[1:2] = ['b']
764  call assert_equal([0, 'b', 2, 3], l)
765
766  let l = [0, 1, 2, 3]
767  py3 l = vim.bindeval('l')
768  py3 l[2:4] = ['c']
769  call assert_equal([0, 1, 'c'], l)
770
771  let l = [0, 1, 2, 3]
772  py3 l = vim.bindeval('l')
773  py3 l[4:4] = ['d']
774  call assert_equal([0, 1, 2, 3, 'd'], l)
775
776  let l = [0, 1, 2, 3]
777  py3 l = vim.bindeval('l')
778  py3 l[-1:2] = ['e']
779  call assert_equal([0, 1, 2, 'e', 3], l)
780
781  let l = [0, 1, 2, 3]
782  py3 l = vim.bindeval('l')
783  py3 l[-10:2] = ['f']
784  call assert_equal(['f', 2, 3], l)
785
786  let l = [0, 1, 2, 3]
787  py3 l = vim.bindeval('l')
788  py3 l[2:-10] = ['g']
789  call assert_equal([0, 1, 'g', 2, 3], l)
790
791  let l = []
792  py3 l = vim.bindeval('l')
793  py3 l[0:0] = ['h']
794  call assert_equal(['h'], l)
795
796  let l = range(8)
797  py3 l = vim.bindeval('l')
798  py3 l[2:6:2] = [10, 20]
799  call assert_equal([0, 1, 10, 3, 20, 5, 6, 7], l)
800
801  let l = range(8)
802  py3 l = vim.bindeval('l')
803  py3 l[6:2:-2] = [10, 20]
804  call assert_equal([0, 1, 2, 3, 20, 5, 10, 7], l)
805
806  let l = range(8)
807  py3 l = vim.bindeval('l')
808  py3 l[6:2] = ()
809  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
810
811  let l = range(8)
812  py3 l = vim.bindeval('l')
813  py3 l[6:2:1] = ()
814  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
815
816  let l = range(8)
817  py3 l = vim.bindeval('l')
818  py3 l[2:2:1] = ()
819  call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
820
821  call AssertException(["py3 x = l[10:11:0]"],
822        \ "Vim(py3):ValueError: slice step cannot be zero")
823endfunc
824
825" Locked variables
826func Test_python3_lockedvar()
827  new
828  py3 cb = vim.current.buffer
829  let l = [0, 1, 2, 3]
830  py3 l = vim.bindeval('l')
831  lockvar! l
832  py3 << trim EOF
833    try:
834        l[2]='i'
835    except vim.error:
836        cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
837  EOF
838  call assert_equal(['', "l[2] threw vim.error: error:('list is locked',)"],
839        \ getline(1, '$'))
840
841  " Try to concatenate a locked list
842  call AssertException(['py3 l += [4, 5]'], 'Vim(py3):vim.error: list is locked')
843
844  call assert_equal([0, 1, 2, 3], l)
845  unlockvar! l
846  close!
847endfunc
848
849" Test for calling a function
850func Test_python3_function_call()
851  func New(...)
852    return ['NewStart'] + a:000 + ['NewEnd']
853  endfunc
854
855  func DictNew(...) dict
856    return ['DictNewStart'] + a:000 + ['DictNewEnd', self]
857  endfunc
858
859  new
860  let l = [function('New'), function('DictNew')]
861  py3 l = vim.bindeval('l')
862  py3 l.extend(list(l[0](1, 2, 3)))
863  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'], l)
864  py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
865  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}], l)
866  py3 l += [[l[0].name]]
867  call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, ['New']], l)
868  py3 ee('l[1](1, 2, 3)')
869  call assert_equal("l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',))", getline(2))
870  %d
871  py3 f = l[0]
872  delfunction New
873  py3 ee('f(1, 2, 3)')
874  call assert_equal("f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',))", getline(2))
875  close!
876  delfunction DictNew
877endfunc
878
879func Test_python3_float()
880  CheckFeature float
881  let l = [0.0]
882  py3 l = vim.bindeval('l')
883  py3 l.extend([0.0])
884  call assert_equal([0.0, 0.0], l)
885endfunc
886
887" Test for Dict key errors
888func Test_python3_dict_key_error()
889  let messages = []
890  py3 << trim EOF
891    import sys
892    d = vim.bindeval('{}')
893    m = vim.bindeval('messages')
894    def em(expr, g=globals(), l=locals()):
895      try:
896        exec(expr, g, l)
897      except Exception as e:
898        if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
899          m.extend([TypeError.__name__])
900        else:
901          m.extend([e.__class__.__name__])
902
903    em('d["abc1"]')
904    em('d["abc1"]="\\0"')
905    em('d["abc1"]=vim')
906    em('d[""]=1')
907    em('d["a\\0b"]=1')
908    em('d[b"a\\0b"]=1')
909    em('d.pop("abc1")')
910    em('d.popitem()')
911    del em
912    del m
913  EOF
914
915  call assert_equal(['KeyError', 'TypeError', 'TypeError', 'ValueError',
916        \ 'TypeError', 'TypeError', 'KeyError', 'KeyError'], messages)
917  unlet messages
918endfunc
919
920" Test for locked and scope attributes
921func Test_python3_lock_scope_attr()
922  let d = {} | let dl = {} | lockvar dl
923  let res = []
924  for s in split("d dl v: g:")
925    let name = tr(s, ':', 's')
926    execute 'py3 ' .. name .. ' = vim.bindeval("' .. s .. '")'
927    call add(res, s .. ' : ' .. join(map(['locked', 'scope'],
928          \ 'v:val .. ":" .. py3eval(name .. "." .. v:val)'), ';'))
929  endfor
930  call assert_equal(['d : locked:0;scope:0', 'dl : locked:1;scope:0',
931        \ 'v: : locked:2;scope:1', 'g: : locked:0;scope:2'], res)
932
933  silent! let d.abc2 = 1
934  silent! let dl.abc3 = 1
935  py3 d.locked = True
936  py3 dl.locked = False
937  silent! let d.def = 1
938  silent! let dl.def = 1
939  call assert_equal({'abc2': 1}, d)
940  call assert_equal({'def': 1}, dl)
941  unlet d dl
942
943  let l = [] | let ll = [] | lockvar ll
944  let res = []
945  for s in split("l ll")
946    let name = tr(s, ':', 's')
947    execute 'py3 ' .. name .. '=vim.bindeval("' .. s .. '")'
948    call add(res, s .. ' : locked:' .. py3eval(name .. '.locked'))
949  endfor
950  call assert_equal(['l : locked:0', 'll : locked:1'], res)
951
952  silent! call extend(l, [0])
953  silent! call extend(ll, [0])
954  py3 l.locked = True
955  py3 ll.locked = False
956  silent! call extend(l, [1])
957  silent! call extend(ll, [1])
958  call assert_equal([0], l)
959  call assert_equal([1], ll)
960  unlet l ll
961
962  " Try changing an attribute of a fixed list
963  py3 a = vim.bindeval('v:argv')
964  call AssertException(['py3 a.locked = 0'],
965        \ 'Vim(py3):TypeError: cannot modify fixed list')
966endfunc
967
968" Test for py3eval()
969func Test_python3_pyeval()
970  let l = py3eval('[0, 1, 2]')
971  call assert_equal([0, 1, 2], l)
972
973  let d = py3eval('{"a": "b", "c": 1, "d": ["e"]}')
974  call assert_equal([['a', 'b'], ['c', 1], ['d', ['e']]], sort(items(d)))
975
976  let v:errmsg = ''
977  call assert_equal(v:none, py3eval('None'))
978  call assert_equal('', v:errmsg)
979
980  py3 v = vim.eval('test_null_function()')
981  call assert_equal(v:none, py3eval('v'))
982
983  if has('float')
984    call assert_equal(0.0, py3eval('0.0'))
985  endif
986
987  " Evaluate an invalid values
988  call AssertException(['let v = py3eval(''"\0"'')'], 'E859:')
989  call AssertException(['let v = py3eval(''{"\0" : 1}'')'], 'E859:')
990  call AssertException(['let v = py3eval("undefined_name")'],
991        \ "Vim(let):NameError: name 'undefined_name' is not defined")
992  call AssertException(['let v = py3eval("vim")'], 'E859:')
993endfunc
994
995" Test for vim.bindeval()
996func Test_python3_vim_bindeval()
997  " Float
998  let f = 3.14
999  py3 f = vim.bindeval('f')
1000  call assert_equal(3.14, py3eval('f'))
1001
1002  " Blob
1003  let b = 0z12
1004  py3 b = vim.bindeval('b')
1005  call assert_equal("\x12", py3eval('b'))
1006
1007  " Bool
1008  call assert_equal(1, py3eval("vim.bindeval('v:true')"))
1009  call assert_equal(0, py3eval("vim.bindeval('v:false')"))
1010  call assert_equal(v:none, py3eval("vim.bindeval('v:null')"))
1011  call assert_equal(v:none, py3eval("vim.bindeval('v:none')"))
1012
1013  " channel/job
1014  if has('channel')
1015    call assert_equal(v:none, py3eval("vim.bindeval('test_null_channel()')"))
1016  endif
1017  if has('job')
1018    call assert_equal(v:none, py3eval("vim.bindeval('test_null_job()')"))
1019  endif
1020endfunc
1021
1022" threading
1023" Running py3do command (Test_pydo) before this test, stops the python thread
1024" from running. So this test should be run before the pydo test
1025func Test_aaa_python3_threading()
1026  let l = [0]
1027  py3 l = vim.bindeval('l')
1028  py3 << trim EOF
1029    import threading
1030    import time
1031
1032    class T(threading.Thread):
1033      def __init__(self):
1034        threading.Thread.__init__(self)
1035        self.t = 0
1036        self.running = True
1037
1038      def run(self):
1039        while self.running:
1040          self.t += 1
1041          time.sleep(0.1)
1042
1043    t = T()
1044    del T
1045    t.start()
1046  EOF
1047
1048  sleep 1
1049  py3 t.running = False
1050  py3 t.join()
1051
1052  " Check if the background thread is working.  Count should be 10, but on a
1053  " busy system (AppVeyor) it can be much lower.
1054  py3 l[0] = t.t > 4
1055  py3 del time
1056  py3 del threading
1057  py3 del t
1058  call assert_equal([1], l)
1059endfunc
1060
1061" settrace
1062func Test_python3_settrace()
1063  let l = []
1064  py3 l = vim.bindeval('l')
1065  py3 << trim EOF
1066    import sys
1067
1068    def traceit(frame, event, arg):
1069      global l
1070      if event == "line":
1071        l += [frame.f_lineno]
1072      return traceit
1073
1074    def trace_main():
1075      for i in range(5):
1076        pass
1077  EOF
1078  py3 sys.settrace(traceit)
1079  py3 trace_main()
1080  py3 sys.settrace(None)
1081  py3 del traceit
1082  py3 del trace_main
1083  call assert_equal([1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1], l)
1084endfunc
1085
1086" Slice
1087func Test_python3_list_slice()
1088  py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
1089  py3 l = ll[:4]
1090  call assert_equal([0, 1, 2, 3], py3eval('l'))
1091  py3 l = ll[2:]
1092  call assert_equal([2, 3, 4, 5], py3eval('l'))
1093  py3 l = ll[:-4]
1094  call assert_equal([0, 1], py3eval('l'))
1095  py3 l = ll[-2:]
1096  call assert_equal([4, 5], py3eval('l'))
1097  py3 l = ll[2:4]
1098  call assert_equal([2, 3], py3eval('l'))
1099  py3 l = ll[4:2]
1100  call assert_equal([], py3eval('l'))
1101  py3 l = ll[-4:-2]
1102  call assert_equal([2, 3], py3eval('l'))
1103  py3 l = ll[-2:-4]
1104  call assert_equal([], py3eval('l'))
1105  py3 l = ll[:]
1106  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1107  py3 l = ll[0:6]
1108  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1109  py3 l = ll[-10:10]
1110  call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1111  py3 l = ll[4:2:-1]
1112  call assert_equal([4, 3], py3eval('l'))
1113  py3 l = ll[::2]
1114  call assert_equal([0, 2, 4], py3eval('l'))
1115  py3 l = ll[4:2:1]
1116  call assert_equal([], py3eval('l'))
1117
1118  " Error case: Use an invalid index
1119  call AssertException(['py3 ll[-10] = 5'], 'Vim(py3):vim.error: internal error:')
1120
1121  " Use a step value of 0
1122  call AssertException(['py3 ll[0:3:0] = [1, 2, 3]'],
1123        \ 'Vim(py3):ValueError: slice step cannot be zero')
1124
1125  " Error case: Invalid slice type
1126  call AssertException(["py3 x = ll['abc']"],
1127        \ "Vim(py3):TypeError: index must be int or slice, not str")
1128  py3 del l
1129
1130  " Error case: List with a null list item
1131  let l = [test_null_list()]
1132  py3 ll = vim.bindeval('l')
1133  call AssertException(["py3 x = ll[:]"],
1134        \ s:system_error_pat)
1135endfunc
1136
1137" Vars
1138func Test_python3_vars()
1139  let g:foo = 'bac'
1140  let w:abc3 = 'def'
1141  let b:baz = 'bar'
1142  let t:bar = 'jkl'
1143  try
1144    throw "Abc"
1145  catch /Abc/
1146    call assert_equal('Abc', py3eval('vim.vvars[''exception'']'))
1147  endtry
1148  call assert_equal('bac', py3eval('vim.vars[''foo'']'))
1149  call assert_equal('def', py3eval('vim.current.window.vars[''abc3'']'))
1150  call assert_equal('bar', py3eval('vim.current.buffer.vars[''baz'']'))
1151  call assert_equal('jkl', py3eval('vim.current.tabpage.vars[''bar'']'))
1152endfunc
1153
1154" Options
1155" paste:          boolean, global
1156" previewheight   number,  global
1157" operatorfunc:   string,  global
1158" number:         boolean, window-local
1159" numberwidth:    number,  window-local
1160" colorcolumn:    string,  window-local
1161" statusline:     string,  window-local/global
1162" autoindent:     boolean, buffer-local
1163" shiftwidth:     number,  buffer-local
1164" omnifunc:       string,  buffer-local
1165" preserveindent: boolean, buffer-local/global
1166" path:           string,  buffer-local/global
1167func Test_python3_opts()
1168  let g:res = []
1169  let g:bufs = [bufnr('%')]
1170  new
1171  let g:bufs += [bufnr('%')]
1172  vnew
1173  let g:bufs += [bufnr('%')]
1174  wincmd j
1175  vnew
1176  let g:bufs += [bufnr('%')]
1177  wincmd l
1178
1179  func RecVars(opt)
1180    let gval = string(eval('&g:' .. a:opt))
1181    let wvals = join(map(range(1, 4),
1182          \ 'v:val .. ":" .. string(getwinvar(v:val, "&" .. a:opt))'))
1183    let bvals = join(map(copy(g:bufs),
1184          \ 'v:val .. ":" .. string(getbufvar(v:val, "&" .. a:opt))'))
1185    call add(g:res, '  G: ' .. gval)
1186    call add(g:res, '  W: ' .. wvals)
1187    call add(g:res, '  B: ' .. wvals)
1188  endfunc
1189
1190  py3 << trim EOF
1191    def e(s, g=globals(), l=locals()):
1192      try:
1193        exec(s, g, l)
1194      except Exception as e:
1195        vim.command('return ' + repr(e.__class__.__name__))
1196
1197    def ev(s, g=globals(), l=locals()):
1198      try:
1199        return eval(s, g, l)
1200      except Exception as e:
1201        vim.command('let exc=' + repr(e.__class__.__name__))
1202        return 0
1203  EOF
1204
1205  func E(s)
1206    python3 e(vim.eval('a:s'))
1207  endfunc
1208
1209  func Ev(s)
1210    let r = py3eval('ev(vim.eval("a:s"))')
1211    if exists('exc')
1212      throw exc
1213    endif
1214    return r
1215  endfunc
1216
1217  py3 gopts1 = vim.options
1218  py3 wopts1 = vim.windows[2].options
1219  py3 wopts2 = vim.windows[0].options
1220  py3 wopts3 = vim.windows[1].options
1221  py3 bopts1 = vim.buffers[vim.bindeval("g:bufs")[2]].options
1222  py3 bopts2 = vim.buffers[vim.bindeval("g:bufs")[1]].options
1223  py3 bopts3 = vim.buffers[vim.bindeval("g:bufs")[0]].options
1224  call add(g:res, 'wopts iters equal: ' ..
1225        \ py3eval('list(wopts1) == list(wopts2)'))
1226  call add(g:res, 'bopts iters equal: ' ..
1227        \ py3eval('list(bopts1) == list(bopts2)'))
1228  py3 gset = set(iter(gopts1))
1229  py3 wset = set(iter(wopts1))
1230  py3 bset = set(iter(bopts1))
1231
1232  set path=.,..,,
1233  let lst = []
1234  let lst += [['paste', 1, 0, 1, 2, 1, 1, 0]]
1235  let lst += [['previewheight', 5, 1, 6, 'a', 0, 1, 0]]
1236  let lst += [['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0]]
1237  let lst += [['number', 0, 1, 1, 0, 1, 0, 1]]
1238  let lst += [['numberwidth', 2, 3, 5, -100, 0, 0, 1]]
1239  let lst += [['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1]]
1240  let lst += [['statusline', '1', '2', '4', 0, 0, 1, 1]]
1241  let lst += [['autoindent', 0, 1, 1, 2, 1, 0, 2]]
1242  let lst += [['shiftwidth', 0, 2, 1, 3, 0, 0, 2]]
1243  let lst += [['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2]]
1244  let lst += [['preserveindent', 0, 1, 1, 2, 1, 1, 2]]
1245  let lst += [['path', '.,,', ',,', '.', 0, 0, 1, 2]]
1246  for  [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
1247    py3 oname = vim.eval('oname')
1248    py3 oval1 = vim.bindeval('oval1')
1249    py3 oval2 = vim.bindeval('oval2')
1250    py3 oval3 = vim.bindeval('oval3')
1251    if invval is 0 || invval is 1
1252      py3 invval = bool(vim.bindeval('invval'))
1253    else
1254      py3 invval = vim.bindeval('invval')
1255    endif
1256    if bool
1257      py3 oval1 = bool(oval1)
1258      py3 oval2 = bool(oval2)
1259      py3 oval3 = bool(oval3)
1260    endif
1261    call add(g:res, '>>> ' .. oname)
1262    call add(g:res, '  g/w/b:' .. py3eval('oname in gset') .. '/' ..
1263          \ py3eval('oname in wset') .. '/' .. py3eval('oname in bset'))
1264    call add(g:res, '  g/w/b (in):' .. py3eval('oname in gopts1') .. '/' ..
1265          \ py3eval('oname in wopts1') .. '/' .. py3eval('oname in bopts1'))
1266    for v in ['gopts1', 'wopts1', 'bopts1']
1267      try
1268        call add(g:res, '  p/' .. v .. ': ' .. Ev('repr(' .. v .. '[''' .. oname .. '''])'))
1269      catch
1270        call add(g:res, '  p/' .. v .. '! ' .. v:exception)
1271      endtry
1272      let r = E(v .. '[''' .. oname .. ''']=invval')
1273      if r isnot 0
1274        call add(g:res, '  inv: ' .. string(invval) .. '! ' .. r)
1275      endif
1276      for vv in (v is# 'gopts1' ? [v] : [v, v[:-2] .. '2', v[:-2] .. '3'])
1277        let val = substitute(vv, '^.opts', 'oval', '')
1278        let r = E(vv .. '[''' .. oname .. ''']=' .. val)
1279        if r isnot 0
1280            call add(g:res, '  ' .. vv .. '! ' .. r)
1281        endif
1282      endfor
1283    endfor
1284    call RecVars(oname)
1285    for v in ['wopts3', 'bopts3']
1286      let r = E('del ' .. v .. '["' .. oname .. '"]')
1287      if r isnot 0
1288        call add(g:res, '  del ' .. v .. '! ' .. r)
1289      endif
1290    endfor
1291    call RecVars(oname)
1292  endfor
1293  delfunction RecVars
1294  delfunction E
1295  delfunction Ev
1296  py3 del ev
1297  py3 del e
1298  only
1299  for buf in g:bufs[1:]
1300    execute 'bwipeout!' buf
1301  endfor
1302  py3 del gopts1
1303  py3 del wopts1
1304  py3 del wopts2
1305  py3 del wopts3
1306  py3 del bopts1
1307  py3 del bopts2
1308  py3 del bopts3
1309  py3 del oval1
1310  py3 del oval2
1311  py3 del oval3
1312  py3 del oname
1313  py3 del invval
1314
1315  let expected =<< trim END
1316    wopts iters equal: 1
1317    bopts iters equal: 1
1318    >>> paste
1319      g/w/b:1/0/0
1320      g/w/b (in):1/0/0
1321      p/gopts1: False
1322      p/wopts1! KeyError
1323      inv: 2! KeyError
1324      wopts1! KeyError
1325      wopts2! KeyError
1326      wopts3! KeyError
1327      p/bopts1! KeyError
1328      inv: 2! KeyError
1329      bopts1! KeyError
1330      bopts2! KeyError
1331      bopts3! KeyError
1332      G: 1
1333      W: 1:1 2:1 3:1 4:1
1334      B: 1:1 2:1 3:1 4:1
1335      del wopts3! KeyError
1336      del bopts3! KeyError
1337      G: 1
1338      W: 1:1 2:1 3:1 4:1
1339      B: 1:1 2:1 3:1 4:1
1340    >>> previewheight
1341      g/w/b:1/0/0
1342      g/w/b (in):1/0/0
1343      p/gopts1: 12
1344      inv: 'a'! TypeError
1345      p/wopts1! KeyError
1346      inv: 'a'! KeyError
1347      wopts1! KeyError
1348      wopts2! KeyError
1349      wopts3! KeyError
1350      p/bopts1! KeyError
1351      inv: 'a'! KeyError
1352      bopts1! KeyError
1353      bopts2! KeyError
1354      bopts3! KeyError
1355      G: 5
1356      W: 1:5 2:5 3:5 4:5
1357      B: 1:5 2:5 3:5 4:5
1358      del wopts3! KeyError
1359      del bopts3! KeyError
1360      G: 5
1361      W: 1:5 2:5 3:5 4:5
1362      B: 1:5 2:5 3:5 4:5
1363    >>> operatorfunc
1364      g/w/b:1/0/0
1365      g/w/b (in):1/0/0
1366      p/gopts1: b''
1367      inv: 2! TypeError
1368      p/wopts1! KeyError
1369      inv: 2! KeyError
1370      wopts1! KeyError
1371      wopts2! KeyError
1372      wopts3! KeyError
1373      p/bopts1! KeyError
1374      inv: 2! KeyError
1375      bopts1! KeyError
1376      bopts2! KeyError
1377      bopts3! KeyError
1378      G: 'A'
1379      W: 1:'A' 2:'A' 3:'A' 4:'A'
1380      B: 1:'A' 2:'A' 3:'A' 4:'A'
1381      del wopts3! KeyError
1382      del bopts3! KeyError
1383      G: 'A'
1384      W: 1:'A' 2:'A' 3:'A' 4:'A'
1385      B: 1:'A' 2:'A' 3:'A' 4:'A'
1386    >>> number
1387      g/w/b:0/1/0
1388      g/w/b (in):0/1/0
1389      p/gopts1! KeyError
1390      inv: 0! KeyError
1391      gopts1! KeyError
1392      p/wopts1: False
1393      p/bopts1! KeyError
1394      inv: 0! KeyError
1395      bopts1! KeyError
1396      bopts2! KeyError
1397      bopts3! KeyError
1398      G: 0
1399      W: 1:1 2:1 3:0 4:0
1400      B: 1:1 2:1 3:0 4:0
1401      del wopts3! ValueError
1402      del bopts3! KeyError
1403      G: 0
1404      W: 1:1 2:1 3:0 4:0
1405      B: 1:1 2:1 3:0 4:0
1406    >>> numberwidth
1407      g/w/b:0/1/0
1408      g/w/b (in):0/1/0
1409      p/gopts1! KeyError
1410      inv: -100! KeyError
1411      gopts1! KeyError
1412      p/wopts1: 4
1413      inv: -100! error
1414      p/bopts1! KeyError
1415      inv: -100! KeyError
1416      bopts1! KeyError
1417      bopts2! KeyError
1418      bopts3! KeyError
1419      G: 4
1420      W: 1:3 2:5 3:2 4:4
1421      B: 1:3 2:5 3:2 4:4
1422      del wopts3! ValueError
1423      del bopts3! KeyError
1424      G: 4
1425      W: 1:3 2:5 3:2 4:4
1426      B: 1:3 2:5 3:2 4:4
1427    >>> colorcolumn
1428      g/w/b:0/1/0
1429      g/w/b (in):0/1/0
1430      p/gopts1! KeyError
1431      inv: 'abc4'! KeyError
1432      gopts1! KeyError
1433      p/wopts1: b''
1434      inv: 'abc4'! error
1435      p/bopts1! KeyError
1436      inv: 'abc4'! KeyError
1437      bopts1! KeyError
1438      bopts2! KeyError
1439      bopts3! KeyError
1440      G: ''
1441      W: 1:'+2' 2:'+3' 3:'+1' 4:''
1442      B: 1:'+2' 2:'+3' 3:'+1' 4:''
1443      del wopts3! ValueError
1444      del bopts3! KeyError
1445      G: ''
1446      W: 1:'+2' 2:'+3' 3:'+1' 4:''
1447      B: 1:'+2' 2:'+3' 3:'+1' 4:''
1448    >>> statusline
1449      g/w/b:1/1/0
1450      g/w/b (in):1/1/0
1451      p/gopts1: b''
1452      inv: 0! TypeError
1453      p/wopts1: None
1454      inv: 0! TypeError
1455      p/bopts1! KeyError
1456      inv: 0! KeyError
1457      bopts1! KeyError
1458      bopts2! KeyError
1459      bopts3! KeyError
1460      G: '1'
1461      W: 1:'2' 2:'4' 3:'1' 4:'1'
1462      B: 1:'2' 2:'4' 3:'1' 4:'1'
1463      del bopts3! KeyError
1464      G: '1'
1465      W: 1:'2' 2:'1' 3:'1' 4:'1'
1466      B: 1:'2' 2:'1' 3:'1' 4:'1'
1467    >>> autoindent
1468      g/w/b:0/0/1
1469      g/w/b (in):0/0/1
1470      p/gopts1! KeyError
1471      inv: 2! KeyError
1472      gopts1! KeyError
1473      p/wopts1! KeyError
1474      inv: 2! KeyError
1475      wopts1! KeyError
1476      wopts2! KeyError
1477      wopts3! KeyError
1478      p/bopts1: False
1479      G: 0
1480      W: 1:0 2:1 3:0 4:1
1481      B: 1:0 2:1 3:0 4:1
1482      del wopts3! KeyError
1483      del bopts3! ValueError
1484      G: 0
1485      W: 1:0 2:1 3:0 4:1
1486      B: 1:0 2:1 3:0 4:1
1487    >>> shiftwidth
1488      g/w/b:0/0/1
1489      g/w/b (in):0/0/1
1490      p/gopts1! KeyError
1491      inv: 3! KeyError
1492      gopts1! KeyError
1493      p/wopts1! KeyError
1494      inv: 3! KeyError
1495      wopts1! KeyError
1496      wopts2! KeyError
1497      wopts3! KeyError
1498      p/bopts1: 8
1499      G: 8
1500      W: 1:0 2:2 3:8 4:1
1501      B: 1:0 2:2 3:8 4:1
1502      del wopts3! KeyError
1503      del bopts3! ValueError
1504      G: 8
1505      W: 1:0 2:2 3:8 4:1
1506      B: 1:0 2:2 3:8 4:1
1507    >>> omnifunc
1508      g/w/b:0/0/1
1509      g/w/b (in):0/0/1
1510      p/gopts1! KeyError
1511      inv: 1! KeyError
1512      gopts1! KeyError
1513      p/wopts1! KeyError
1514      inv: 1! KeyError
1515      wopts1! KeyError
1516      wopts2! KeyError
1517      wopts3! KeyError
1518      p/bopts1: b''
1519      inv: 1! TypeError
1520      G: ''
1521      W: 1:'A' 2:'B' 3:'' 4:'C'
1522      B: 1:'A' 2:'B' 3:'' 4:'C'
1523      del wopts3! KeyError
1524      del bopts3! ValueError
1525      G: ''
1526      W: 1:'A' 2:'B' 3:'' 4:'C'
1527      B: 1:'A' 2:'B' 3:'' 4:'C'
1528    >>> preserveindent
1529      g/w/b:0/0/1
1530      g/w/b (in):0/0/1
1531      p/gopts1! KeyError
1532      inv: 2! KeyError
1533      gopts1! KeyError
1534      p/wopts1! KeyError
1535      inv: 2! KeyError
1536      wopts1! KeyError
1537      wopts2! KeyError
1538      wopts3! KeyError
1539      p/bopts1: False
1540      G: 0
1541      W: 1:0 2:1 3:0 4:1
1542      B: 1:0 2:1 3:0 4:1
1543      del wopts3! KeyError
1544      del bopts3! ValueError
1545      G: 0
1546      W: 1:0 2:1 3:0 4:1
1547      B: 1:0 2:1 3:0 4:1
1548    >>> path
1549      g/w/b:1/0/1
1550      g/w/b (in):1/0/1
1551      p/gopts1: b'.,..,,'
1552      inv: 0! TypeError
1553      p/wopts1! KeyError
1554      inv: 0! KeyError
1555      wopts1! KeyError
1556      wopts2! KeyError
1557      wopts3! KeyError
1558      p/bopts1: None
1559      inv: 0! TypeError
1560      G: '.,,'
1561      W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1562      B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1563      del wopts3! KeyError
1564      G: '.,,'
1565      W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1566      B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1567  END
1568
1569  call assert_equal(expected, g:res)
1570  unlet g:res
1571
1572  call assert_equal(0, py3eval("'' in vim.options"))
1573
1574  " use an empty key to index vim.options
1575  call AssertException(["let v = py3eval(\"vim.options['']\")"],
1576        \ 'Vim(let):ValueError: empty keys are not allowed')
1577  call AssertException(["py3 vim.current.window.options[''] = 0"],
1578        \ 'Vim(py3):ValueError: empty keys are not allowed')
1579  call AssertException(["py3 vim.current.window.options[{}] = 0"],
1580        \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got dict')
1581
1582  " set one of the number options to a very large number
1583  let cmd = ["py3 vim.options['previewheight'] = 9999999999999999"]
1584  call AssertException(cmd, "Vim(py3):OverflowError:")
1585
1586  " unset a global-local string option
1587  call AssertException(["py3 del vim.options['errorformat']"],
1588        \ 'Vim(py3):ValueError: unable to unset global option errorformat')
1589endfunc
1590
1591" Test for vim.buffer object
1592func Test_python3_buffer()
1593  new
1594  call setline(1, "Hello\nWorld")
1595  call assert_fails("let x = py3eval('vim.current.buffer[0]')", 'E859:')
1596  %bw!
1597
1598  edit Xfile1
1599  let bnr1 = bufnr()
1600  py3 cb = vim.current.buffer
1601  vnew Xfile2
1602  let bnr2 = bufnr()
1603  call setline(1, ['First line', 'Second line', 'Third line'])
1604  py3 b = vim.current.buffer
1605  wincmd w
1606
1607  " Test for getting lines from the buffer using a slice
1608  call assert_equal(['First line'], py3eval('b[-10:1]'))
1609  call assert_equal(['Third line'], py3eval('b[2:10]'))
1610  call assert_equal([], py3eval('b[2:0]'))
1611  call assert_equal([], py3eval('b[10:12]'))
1612  call assert_equal([], py3eval('b[-10:-8]'))
1613  call AssertException(["py3 x = b[0:3:0]"],
1614        \ 'Vim(py3):ValueError: slice step cannot be zero')
1615  call AssertException(["py3 b[0:3:0] = 'abc'"],
1616        \ 'Vim(py3):ValueError: slice step cannot be zero')
1617  call AssertException(["py3 x = b[{}]"],
1618        \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1619  call AssertException(["py3 b[{}] = 'abc'"],
1620        \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1621
1622  " Test for getting lines using a range
1623  call AssertException(["py3 x = b.range(0,3)[0:2:0]"],
1624        \ "Vim(py3):ValueError: slice step cannot be zero")
1625  call AssertException(["py3 b.range(0,3)[0:2:0] = 'abc'"],
1626        \ "Vim(py3):ValueError: slice step cannot be zero")
1627
1628  " Tests BufferAppend and BufferItem
1629  py3 cb.append(b[0])
1630  call assert_equal(['First line'], getbufline(bnr1, 2))
1631  %d
1632
1633  " Try to append using out-of-range line number
1634  call AssertException(["py3 b.append('abc', 10)"],
1635        \ 'Vim(py3):IndexError: line number out of range')
1636
1637  " Append a non-string item
1638  call AssertException(["py3 b.append([22])"],
1639        \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got int')
1640
1641  " Tests BufferSlice and BufferAssSlice
1642  py3 cb.append('abc5') # Will be overwritten
1643  py3 cb[-1:] = b[:-2]
1644  call assert_equal(['First line'], getbufline(bnr1, 2))
1645  %d
1646
1647  " Test BufferLength and BufferAssSlice
1648  py3 cb.append('def') # Will not be overwritten
1649  py3 cb[len(cb):] = b[:]
1650  call assert_equal(['def', 'First line', 'Second line', 'Third line'],
1651        \ getbufline(bnr1, 2, '$'))
1652  %d
1653
1654  " Test BufferAssItem and BufferMark
1655  call setbufline(bnr1, 1, ['one', 'two', 'three'])
1656  call cursor(1, 3)
1657  normal ma
1658  py3 cb.append('ghi') # Will be overwritten
1659  py3 cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
1660  call assert_equal(['(3, 2)'], getbufline(bnr1, 4))
1661  %d
1662
1663  " Test BufferRepr
1664  py3 cb.append(repr(cb) + repr(b))
1665  call assert_equal(['<buffer Xfile1><buffer Xfile2>'], getbufline(bnr1, 2))
1666  %d
1667
1668  " Modify foreign buffer
1669  py3 << trim EOF
1670    b.append('foo')
1671    b[0]='bar'
1672    b[0:0]=['baz']
1673    vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
1674  EOF
1675  call assert_equal(['baz', 'bar', 'Second line', 'Third line', 'foo'],
1676        \ getbufline(bnr2, 1, '$'))
1677  %d
1678
1679  " Test assigning to name property
1680  augroup BUFS
1681    autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
1682    autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
1683  augroup END
1684  py3 << trim EOF
1685    import os
1686    old_name = cb.name
1687    cb.name = 'foo'
1688    cb.append(cb.name[-11:].replace(os.path.sep, '/'))
1689    b.name = 'bar'
1690    cb.append(b.name[-11:].replace(os.path.sep, '/'))
1691    cb.name = old_name
1692    cb.append(cb.name[-14:].replace(os.path.sep, '/'))
1693    del old_name
1694  EOF
1695  call assert_equal([bnr1 .. ':BufFilePre:' .. bnr1,
1696        \ bnr1 .. ':BufFilePost:' .. bnr1,
1697        \ 'testdir/foo',
1698        \ bnr2 .. ':BufFilePre:' .. bnr2,
1699        \ bnr2 .. ':BufFilePost:' .. bnr2,
1700        \ 'testdir/bar',
1701        \ bnr1 .. ':BufFilePre:' .. bnr1,
1702        \ bnr1 .. ':BufFilePost:' .. bnr1,
1703        \ 'testdir/Xfile1'], getbufline(bnr1, 2, '$'))
1704  %d
1705
1706  " Test CheckBuffer
1707  py3 << trim EOF
1708    for _b in vim.buffers:
1709      if _b is not cb:
1710        vim.command('bwipeout! ' + str(_b.number))
1711    del _b
1712    cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
1713  EOF
1714  call assert_equal('valid: b:False, cb:True', getline(2))
1715  %d
1716
1717  py3 << trim EOF
1718    for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
1719      try:
1720        exec(expr)
1721      except vim.error:
1722        pass
1723      else:
1724        # Usually a SEGV here
1725        # Should not happen in any case
1726        cb.append('No exception for ' + expr)
1727    vim.command('cd .')
1728    del b
1729  EOF
1730  call assert_equal([''], getline(1, '$'))
1731
1732  " Delete all the lines in a buffer
1733  call setline(1, ['a', 'b', 'c'])
1734  py3 vim.current.buffer[:] = []
1735  call assert_equal([''], getline(1, '$'))
1736
1737  " Test for buffer marks
1738  call assert_equal(v:none, py3eval("vim.current.buffer.mark('r')"))
1739
1740  " Test for modifying a 'nomodifiable' buffer
1741  setlocal nomodifiable
1742  call AssertException(["py3 vim.current.buffer[0] = 'abc'"],
1743        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1744  call AssertException(["py3 vim.current.buffer[0] = None"],
1745        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1746  call AssertException(["py3 vim.current.buffer[:] = None"],
1747        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1748  call AssertException(["py3 vim.current.buffer[:] = []"],
1749        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1750  call AssertException(["py3 vim.current.buffer.append('abc')"],
1751        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1752  call AssertException(["py3 vim.current.buffer.append([])"],
1753        \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1754  setlocal modifiable
1755
1756  augroup BUFS
1757    autocmd!
1758  augroup END
1759  augroup! BUFS
1760  %bw!
1761
1762  " Range object for a deleted buffer
1763  new Xfile
1764  call setline(1, ['one', 'two', 'three'])
1765  py3 b = vim.current.buffer
1766  py3 r = vim.current.buffer.range(0, 2)
1767  call assert_equal('<range Xfile (0:2)>', py3eval('repr(r)'))
1768  %bw!
1769  call AssertException(['py3 r[:] = []'],
1770        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1771  call assert_match('<buffer object (deleted)', py3eval('repr(b)'))
1772  call assert_match('<range object (for deleted buffer)', py3eval('repr(r)'))
1773  call AssertException(["let n = py3eval('len(r)')"],
1774        \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
1775  call AssertException(["py3 r.append('abc')"],
1776        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1777
1778  " object for a deleted buffer
1779  call AssertException(["py3 b[0] = 'one'"],
1780        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1781  call AssertException(["py3 b.append('one')"],
1782        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1783  call AssertException(["let n = py3eval('len(b)')"],
1784        \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
1785  call AssertException(["py3 pos = b.mark('a')"],
1786        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1787  call AssertException(["py3 vim.current.buffer = b"],
1788        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1789  call AssertException(["py3 rn = b.range(0, 2)"],
1790        \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1791endfunc
1792
1793" Test vim.buffers object
1794func Test_python3_buffers()
1795  %bw!
1796  edit Xfile
1797  py3 cb = vim.current.buffer
1798  set hidden
1799  edit a
1800  buffer #
1801  edit b
1802  buffer #
1803  edit c
1804  buffer #
1805  py3 << trim EOF
1806    # Check GCing iterator that was not fully exhausted
1807    i = iter(vim.buffers)
1808    cb.append('i:' + str(next(i)))
1809    # and also check creating more than one iterator at a time
1810    i2 = iter(vim.buffers)
1811    cb.append('i2:' + str(next(i2)))
1812    cb.append('i:' + str(next(i)))
1813    # The following should trigger GC and not cause any problems
1814    del i
1815    del i2
1816    i3 = iter(vim.buffers)
1817    cb.append('i3:' + str(next(i3)))
1818    del i3
1819  EOF
1820  call assert_equal(['i:<buffer Xfile>',
1821        \ 'i2:<buffer Xfile>', 'i:<buffer a>', 'i3:<buffer Xfile>'],
1822        \ getline(2, '$'))
1823  %d
1824
1825  py3 << trim EOF
1826    prevnum = 0
1827    for b in vim.buffers:
1828      # Check buffer order
1829      if prevnum >= b.number:
1830        cb.append('!!! Buffer numbers not in strictly ascending order')
1831      # Check indexing: vim.buffers[number].number == number
1832      cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + \
1833                                                            '=' + repr(b))
1834      prevnum = b.number
1835    del prevnum
1836
1837    cb.append(str(len(vim.buffers)))
1838  EOF
1839  call assert_equal([bufnr('Xfile') .. ':<buffer Xfile>=<buffer Xfile>',
1840        \ bufnr('a') .. ':<buffer a>=<buffer a>',
1841        \ bufnr('b') .. ':<buffer b>=<buffer b>',
1842        \ bufnr('c') .. ':<buffer c>=<buffer c>', '4'], getline(2, '$'))
1843  %d
1844
1845  py3 << trim EOF
1846    bnums = list(map(lambda b: b.number, vim.buffers))[1:]
1847
1848    # Test wiping out buffer with existing iterator
1849    i4 = iter(vim.buffers)
1850    cb.append('i4:' + str(next(i4)))
1851    vim.command('bwipeout! ' + str(bnums.pop(0)))
1852    try:
1853      next(i4)
1854    except vim.error:
1855      pass
1856    else:
1857      cb.append('!!!! No vim.error')
1858    i4 = iter(vim.buffers)
1859    vim.command('bwipeout! ' + str(bnums.pop(-1)))
1860    vim.command('bwipeout! ' + str(bnums.pop(-1)))
1861    cb.append('i4:' + str(next(i4)))
1862    try:
1863      next(i4)
1864    except StopIteration:
1865      cb.append('StopIteration')
1866    del i4
1867    del bnums
1868  EOF
1869  call assert_equal(['i4:<buffer Xfile>',
1870        \ 'i4:<buffer Xfile>', 'StopIteration'], getline(2, '$'))
1871  %bw!
1872endfunc
1873
1874" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
1875func Test_python3_tabpage_window()
1876  %bw
1877  edit Xfile
1878  py3 cb = vim.current.buffer
1879  tabnew 0
1880  tabnew 1
1881  vnew a.1
1882  tabnew 2
1883  vnew a.2
1884  vnew b.2
1885  vnew c.2
1886
1887  py3 << trim EOF
1888    cb.append('Number of tabs: ' + str(len(vim.tabpages)))
1889    cb.append('Current tab pages:')
1890    def W(w):
1891      if '(unknown)' in repr(w):
1892        return '<window object (unknown)>'
1893      else:
1894        return repr(w)
1895
1896    def Cursor(w, start=len(cb)):
1897      if w.buffer is cb:
1898        return repr((start - w.cursor[0], w.cursor[1]))
1899      else:
1900        return repr(w.cursor)
1901
1902    for t in vim.tabpages:
1903      cb.append('  ' + repr(t) + '(' + str(t.number) + ')' + ': ' + \
1904                str(len(t.windows)) + ' windows, current is ' + W(t.window))
1905      cb.append('  Windows:')
1906      for w in t.windows:
1907        cb.append('    ' + W(w) + '(' + str(w.number) + ')' + \
1908                                  ': displays buffer ' + repr(w.buffer) + \
1909                                  '; cursor is at ' + Cursor(w))
1910        # Other values depend on the size of the terminal, so they are checked
1911        # partly:
1912        for attr in ('height', 'row', 'width', 'col'):
1913          try:
1914            aval = getattr(w, attr)
1915            if type(aval) is not int:
1916              raise TypeError
1917            if aval < 0:
1918              raise ValueError
1919          except Exception as e:
1920            cb.append('!!!!!! Error while getting attribute ' + attr + \
1921                                            ': ' + e.__class__.__name__)
1922        del aval
1923        del attr
1924        w.cursor = (len(w.buffer), 0)
1925    del W
1926    del Cursor
1927    cb.append('Number of windows in current tab page: ' + \
1928                                                    str(len(vim.windows)))
1929    if list(vim.windows) != list(vim.current.tabpage.windows):
1930      cb.append('!!!!!! Windows differ')
1931  EOF
1932
1933  let expected =<< trim END
1934    Number of tabs: 4
1935    Current tab pages:
1936      <tabpage 0>(1): 1 windows, current is <window object (unknown)>
1937      Windows:
1938        <window object (unknown)>(1): displays buffer <buffer Xfile>; cursor is at (2, 0)
1939      <tabpage 1>(2): 1 windows, current is <window object (unknown)>
1940      Windows:
1941        <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
1942      <tabpage 2>(3): 2 windows, current is <window object (unknown)>
1943      Windows:
1944        <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
1945        <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
1946      <tabpage 3>(4): 4 windows, current is <window 0>
1947      Windows:
1948        <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
1949        <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
1950        <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
1951        <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
1952    Number of windows in current tab page: 4
1953  END
1954  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
1955  %bw!
1956endfunc
1957
1958" Test vim.current
1959func Test_python3_vim_current()
1960  %bw
1961  edit Xfile
1962  py3 cb = vim.current.buffer
1963  tabnew 0
1964  tabnew 1
1965  vnew a.1
1966  tabnew 2
1967  vnew a.2
1968  vnew b.2
1969  vnew c.2
1970
1971  py3 << trim EOF
1972    def H(o):
1973      return repr(o)
1974    cb.append('Current tab page: ' + repr(vim.current.tabpage))
1975    cb.append('Current window: ' + repr(vim.current.window) + ': ' + \
1976               H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
1977    cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + \
1978               H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ \
1979               ' is ' + H(vim.current.tabpage.window.buffer))
1980    del H
1981  EOF
1982  let expected =<< trim END
1983    Current tab page: <tabpage 3>
1984    Current window: <window 0>: <window 0> is <window 0>
1985    Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
1986  END
1987  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
1988  call deletebufline(bufnr('Xfile'), 1, '$')
1989
1990  " Assigning: fails
1991  py3 << trim EOF
1992    try:
1993      vim.current.window = vim.tabpages[0].window
1994    except ValueError:
1995      cb.append('ValueError at assigning foreign tab window')
1996
1997    for attr in ('window', 'tabpage', 'buffer'):
1998      try:
1999        setattr(vim.current, attr, None)
2000      except TypeError:
2001        cb.append('Type error at assigning None to vim.current.' + attr)
2002    del attr
2003  EOF
2004
2005  let expected =<< trim END
2006    ValueError at assigning foreign tab window
2007    Type error at assigning None to vim.current.window
2008    Type error at assigning None to vim.current.tabpage
2009    Type error at assigning None to vim.current.buffer
2010  END
2011  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
2012  call deletebufline(bufnr('Xfile'), 1, '$')
2013
2014  call setbufline(bufnr('Xfile'), 1, 'python interface')
2015  py3 << trim EOF
2016    # Assigning: success
2017    vim.current.tabpage = vim.tabpages[-2]
2018    vim.current.buffer = cb
2019    vim.current.window = vim.windows[0]
2020    vim.current.window.cursor = (len(vim.current.buffer), 0)
2021    cb.append('Current tab page: ' + repr(vim.current.tabpage))
2022    cb.append('Current window: ' + repr(vim.current.window))
2023    cb.append('Current buffer: ' + repr(vim.current.buffer))
2024    cb.append('Current line: ' + repr(vim.current.line))
2025  EOF
2026
2027  let expected =<< trim END
2028    Current tab page: <tabpage 2>
2029    Current window: <window 0>
2030    Current buffer: <buffer Xfile>
2031    Current line: 'python interface'
2032  END
2033  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
2034  py3 vim.current.line = 'one line'
2035  call assert_equal('one line', getline('.'))
2036  call deletebufline(bufnr('Xfile'), 1, '$')
2037
2038  py3 << trim EOF
2039    ws = list(vim.windows)
2040    ts = list(vim.tabpages)
2041    for b in vim.buffers:
2042      if b is not cb:
2043        vim.command('bwipeout! ' + str(b.number))
2044    del b
2045    cb.append('w.valid: ' + repr([w.valid for w in ws]))
2046    cb.append('t.valid: ' + repr([t.valid for t in ts]))
2047    del w
2048    del t
2049    del ts
2050    del ws
2051  EOF
2052  let expected =<< trim END
2053    w.valid: [True, False]
2054    t.valid: [True, False, True, False]
2055  END
2056  call assert_equal(expected, getbufline(bufnr('Xfile'), 2, '$'))
2057  %bw!
2058endfunc
2059
2060" Test types
2061func Test_python3_types()
2062  %d
2063  py3 cb = vim.current.buffer
2064  py3 << trim EOF
2065    for expr, attr in (
2066      ('vim.vars',                         'Dictionary'),
2067      ('vim.options',                      'Options'),
2068      ('vim.bindeval("{}")',               'Dictionary'),
2069      ('vim.bindeval("[]")',               'List'),
2070      ('vim.bindeval("function(\'tr\')")', 'Function'),
2071      ('vim.current.buffer',               'Buffer'),
2072      ('vim.current.range',                'Range'),
2073      ('vim.current.window',               'Window'),
2074      ('vim.current.tabpage',              'TabPage'),
2075    ):
2076      cb.append(expr + ':' + attr + ':' + \
2077                                repr(type(eval(expr)) is getattr(vim, attr)))
2078    del expr
2079    del attr
2080  EOF
2081  let expected =<< trim END
2082    vim.vars:Dictionary:True
2083    vim.options:Options:True
2084    vim.bindeval("{}"):Dictionary:True
2085    vim.bindeval("[]"):List:True
2086    vim.bindeval("function('tr')"):Function:True
2087    vim.current.buffer:Buffer:True
2088    vim.current.range:Range:True
2089    vim.current.window:Window:True
2090    vim.current.tabpage:TabPage:True
2091  END
2092  call assert_equal(expected, getline(2, '$'))
2093endfunc
2094
2095" Test __dir__() method
2096func Test_python3_dir_method()
2097  %d
2098  py3 cb = vim.current.buffer
2099  py3 << trim EOF
2100    for name, o in (
2101            ('current',    vim.current),
2102            ('buffer',     vim.current.buffer),
2103            ('window',     vim.current.window),
2104            ('tabpage',    vim.current.tabpage),
2105            ('range',      vim.current.range),
2106            ('dictionary', vim.bindeval('{}')),
2107            ('list',       vim.bindeval('[]')),
2108            ('function',   vim.bindeval('function("tr")')),
2109            ('output',     sys.stdout),
2110        ):
2111        cb.append(name + ':' + ','.join(dir(o)))
2112    del name
2113    del o
2114  EOF
2115  let expected =<< trim END
2116    current:__dir__,buffer,line,range,tabpage,window
2117    buffer:__dir__,append,mark,name,number,options,range,valid,vars
2118    window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
2119    tabpage:__dir__,number,valid,vars,window,windows
2120    range:__dir__,append,end,start
2121    dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
2122    list:__dir__,extend,locked
2123    function:__dir__,args,auto_rebind,self,softspace
2124    output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
2125  END
2126  call assert_equal(expected, getline(2, '$'))
2127endfunc
2128
2129" Test vim.*.__new__
2130func Test_python3_new()
2131  call assert_equal({}, py3eval('vim.Dictionary({})'))
2132  call assert_equal({'a': 1}, py3eval('vim.Dictionary(a=1)'))
2133  call assert_equal({'a': 1}, py3eval('vim.Dictionary(((''a'', 1),))'))
2134  call assert_equal([], py3eval('vim.List()'))
2135  call assert_equal(['a', 'b', 'c', '7'], py3eval('vim.List(iter(''abc7''))'))
2136  call assert_equal(function('tr'), py3eval('vim.Function(''tr'')'))
2137  call assert_equal(function('tr', [123, 3, 4]),
2138        \ py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
2139  call assert_equal(function('tr'), py3eval('vim.Function(''tr'', args=[])'))
2140  call assert_equal(function('tr', {}),
2141        \ py3eval('vim.Function(''tr'', self={})'))
2142  call assert_equal(function('tr', [123, 3, 4], {}),
2143        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
2144  call assert_equal(function('tr'),
2145        \ py3eval('vim.Function(''tr'', auto_rebind=False)'))
2146  call assert_equal(function('tr', [123, 3, 4]),
2147        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
2148  call assert_equal(function('tr'),
2149        \ py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
2150  call assert_equal(function('tr', {}),
2151        \ py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
2152  call assert_equal(function('tr', [123, 3, 4], {}),
2153        \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
2154endfunc
2155
2156" Test vim.Function
2157func Test_python3_vim_func()
2158  func Args(...)
2159    return a:000
2160  endfunc
2161
2162  func SelfArgs(...) dict
2163    return [a:000, self]
2164  endfunc
2165
2166  " The following four lines should not crash
2167  let Pt = function('tr', [[]], {'l': []})
2168  py3 Pt = vim.bindeval('Pt')
2169  unlet Pt
2170  py3 del Pt
2171
2172  call assert_equal(3, py3eval('vim.strwidth("a\tb")'))
2173
2174  %bw!
2175  py3 cb = vim.current.buffer
2176  py3 << trim EOF
2177    def ecall(out_prefix, func, *args, **kwargs):
2178        line = out_prefix + ': '
2179        try:
2180            ret = func(*args, **kwargs)
2181        except Exception:
2182            line += '!exception: ' + emsg(sys.exc_info())
2183        else:
2184            line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
2185        cb.append(line)
2186    a = vim.Function('Args')
2187    pa1 = vim.Function('Args', args=['abcArgsPA1'])
2188    pa2 = vim.Function('Args', args=[])
2189    pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
2190    pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
2191    cb.append('a: ' + repr(a))
2192    cb.append('pa1: ' + repr(pa1))
2193    cb.append('pa2: ' + repr(pa2))
2194    cb.append('pa3: ' + repr(pa3))
2195    cb.append('pa4: ' + repr(pa4))
2196    sa = vim.Function('SelfArgs')
2197    psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
2198    psa2 = vim.Function('SelfArgs', args=[])
2199    psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
2200    psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
2201    psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
2202    psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
2203    psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
2204    psa8 = vim.Function('SelfArgs', auto_rebind=False)
2205    psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
2206    psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
2207    psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
2208    psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
2209    cb.append('sa: ' + repr(sa))
2210    cb.append('psa1: ' + repr(psa1))
2211    cb.append('psa2: ' + repr(psa2))
2212    cb.append('psa3: ' + repr(psa3))
2213    cb.append('psa4: ' + repr(psa4))
2214    cb.append('psa5: ' + repr(psa5))
2215    cb.append('psa6: ' + repr(psa6))
2216    cb.append('psa7: ' + repr(psa7))
2217    cb.append('psa8: ' + repr(psa8))
2218    cb.append('psa9: ' + repr(psa9))
2219    cb.append('psaA: ' + repr(psaA))
2220    cb.append('psaB: ' + repr(psaB))
2221    cb.append('psaC: ' + repr(psaC))
2222
2223    psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
2224    psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
2225    psar.self['rec'] = psar
2226    psar.self['self'] = psar.self
2227    psar.self['args'] = psar.args
2228
2229    try:
2230      cb.append('psar: ' + repr(psar))
2231    except Exception:
2232      cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
2233  EOF
2234
2235  let expected =<< trim END
2236    a: <vim.Function 'Args'>
2237    pa1: <vim.Function 'Args', args=['abcArgsPA1']>
2238    pa2: <vim.Function 'Args'>
2239    pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
2240    pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
2241    sa: <vim.Function 'SelfArgs'>
2242    psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
2243    psa2: <vim.Function 'SelfArgs'>
2244    psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
2245    psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
2246    psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
2247    psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
2248    psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
2249    psa8: <vim.Function 'SelfArgs'>
2250    psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
2251    psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
2252    psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
2253    psaC: <vim.Function 'SelfArgs'>
2254    psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
2255  END
2256  call assert_equal(expected, getline(2, '$'))
2257  %d
2258
2259  call assert_equal(function('Args'), py3eval('a'))
2260  call assert_equal(function('Args', ['abcArgsPA1']), py3eval('pa1'))
2261  call assert_equal(function('Args'), py3eval('pa2'))
2262  call assert_equal(function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}), py3eval('pa3'))
2263  call assert_equal(function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}), py3eval('pa4'))
2264  call assert_equal(function('SelfArgs'), py3eval('sa'))
2265  call assert_equal(function('SelfArgs', ['abcArgsPSA1']), py3eval('psa1'))
2266  call assert_equal(function('SelfArgs'), py3eval('psa2'))
2267  call assert_equal(function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}), py3eval('psa3'))
2268  call assert_equal(function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}), py3eval('psa4'))
2269  call assert_equal(function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}), py3eval('psa5'))
2270  call assert_equal(function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}), py3eval('psa6'))
2271  call assert_equal(function('SelfArgs', ['abcArgsPSA7']), py3eval('psa7'))
2272  call assert_equal(function('SelfArgs'), py3eval('psa8'))
2273  call assert_equal(function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}), py3eval('psa9'))
2274  call assert_equal(function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}), py3eval('psaA'))
2275  call assert_equal(function('SelfArgs', ['abcArgsPSAB']), py3eval('psaB'))
2276  call assert_equal(function('SelfArgs'), py3eval('psaC'))
2277
2278  let res = []
2279  for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7',
2280        \ 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
2281    let d = {'f': py3eval(v)}
2282    call add(res, 'd.' .. v .. '(): ' .. string(d.f()))
2283  endfor
2284
2285  let expected =<< trim END
2286    d.sa(): [[], {'f': function('SelfArgs')}]
2287    d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
2288    d.psa2(): [[], {'f': function('SelfArgs')}]
2289    d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2290    d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2291    d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
2292    d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
2293    d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
2294    d.psa8(): [[], {'f': function('SelfArgs')}]
2295    d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
2296    d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
2297    d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
2298    d.psaC(): [[], {'f': function('SelfArgs')}]
2299  END
2300  call assert_equal(expected, res)
2301
2302  py3 ecall('a()', a, )
2303  py3 ecall('pa1()', pa1, )
2304  py3 ecall('pa2()', pa2, )
2305  py3 ecall('pa3()', pa3, )
2306  py3 ecall('pa4()', pa4, )
2307  py3 ecall('sa()', sa, )
2308  py3 ecall('psa1()', psa1, )
2309  py3 ecall('psa2()', psa2, )
2310  py3 ecall('psa3()', psa3, )
2311  py3 ecall('psa4()', psa4, )
2312
2313  py3 ecall('a(42, 43)', a, 42, 43)
2314  py3 ecall('pa1(42, 43)', pa1, 42, 43)
2315  py3 ecall('pa2(42, 43)', pa2, 42, 43)
2316  py3 ecall('pa3(42, 43)', pa3, 42, 43)
2317  py3 ecall('pa4(42, 43)', pa4, 42, 43)
2318  py3 ecall('sa(42, 43)', sa, 42, 43)
2319  py3 ecall('psa1(42, 43)', psa1, 42, 43)
2320  py3 ecall('psa2(42, 43)', psa2, 42, 43)
2321  py3 ecall('psa3(42, 43)', psa3, 42, 43)
2322  py3 ecall('psa4(42, 43)', psa4, 42, 43)
2323
2324  py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
2325  py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
2326  py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
2327  py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
2328  py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
2329  py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
2330  py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
2331  py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
2332  py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
2333  py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
2334
2335  py3 ecall('a(self={"20": 1})', a, self={'20': 1})
2336  py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
2337  py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
2338  py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
2339  py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
2340  py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
2341  py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
2342  py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
2343  py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
2344  py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
2345
2346  py3 << trim EOF
2347    def s(v):
2348        if v is None:
2349            return repr(v)
2350        else:
2351            return str(vim.Function('string')(v), 'utf-8')
2352
2353    cb.append('a.args: ' + s(a.args))
2354    cb.append('pa1.args: ' + s(pa1.args))
2355    cb.append('pa2.args: ' + s(pa2.args))
2356    cb.append('pa3.args: ' + s(pa3.args))
2357    cb.append('pa4.args: ' + s(pa4.args))
2358    cb.append('sa.args: ' + s(sa.args))
2359    cb.append('psa1.args: ' + s(psa1.args))
2360    cb.append('psa2.args: ' + s(psa2.args))
2361    cb.append('psa3.args: ' + s(psa3.args))
2362    cb.append('psa4.args: ' + s(psa4.args))
2363
2364    cb.append('a.self: ' + s(a.self))
2365    cb.append('pa1.self: ' + s(pa1.self))
2366    cb.append('pa2.self: ' + s(pa2.self))
2367    cb.append('pa3.self: ' + s(pa3.self))
2368    cb.append('pa4.self: ' + s(pa4.self))
2369    cb.append('sa.self: ' + s(sa.self))
2370    cb.append('psa1.self: ' + s(psa1.self))
2371    cb.append('psa2.self: ' + s(psa2.self))
2372    cb.append('psa3.self: ' + s(psa3.self))
2373    cb.append('psa4.self: ' + s(psa4.self))
2374
2375    cb.append('a.name: ' + s(a.name))
2376    cb.append('pa1.name: ' + s(pa1.name))
2377    cb.append('pa2.name: ' + s(pa2.name))
2378    cb.append('pa3.name: ' + s(pa3.name))
2379    cb.append('pa4.name: ' + s(pa4.name))
2380    cb.append('sa.name: ' + s(sa.name))
2381    cb.append('psa1.name: ' + s(psa1.name))
2382    cb.append('psa2.name: ' + s(psa2.name))
2383    cb.append('psa3.name: ' + s(psa3.name))
2384    cb.append('psa4.name: ' + s(psa4.name))
2385
2386    cb.append('a.auto_rebind: ' + s(a.auto_rebind))
2387    cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
2388    cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
2389    cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
2390    cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
2391    cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
2392    cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
2393    cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
2394    cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
2395    cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
2396    cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
2397    cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
2398    cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
2399    cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
2400    cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
2401    cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
2402    cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
2403    cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
2404
2405    del s
2406
2407    del a
2408    del pa1
2409    del pa2
2410    del pa3
2411    del pa4
2412    del sa
2413    del psa1
2414    del psa2
2415    del psa3
2416    del psa4
2417    del psa5
2418    del psa6
2419    del psa7
2420    del psa8
2421    del psa9
2422    del psaA
2423    del psaB
2424    del psaC
2425    del psar
2426
2427    del ecall
2428  EOF
2429
2430  let expected =<< trim END
2431    a(): !result: []
2432    pa1(): !result: ['abcArgsPA1']
2433    pa2(): !result: []
2434    pa3(): !result: ['abcArgsPA3']
2435    pa4(): !result: []
2436    sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2437    psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2438    psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2439    psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2440    psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2441    a(42, 43): !result: [42, 43]
2442    pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
2443    pa2(42, 43): !result: [42, 43]
2444    pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
2445    pa4(42, 43): !result: [42, 43]
2446    sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2447    psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2448    psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2449    psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2450    psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2451    a(42, self={"20": 1}): !result: [42]
2452    pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
2453    pa2(42, self={"20": 1}): !result: [42]
2454    pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
2455    pa4(42, self={"20": 1}): !result: [42]
2456    sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
2457    psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
2458    psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
2459    psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
2460    psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
2461    a(self={"20": 1}): !result: []
2462    pa1(self={"20": 1}): !result: ['abcArgsPA1']
2463    pa2(self={"20": 1}): !result: []
2464    pa3(self={"20": 1}): !result: ['abcArgsPA3']
2465    pa4(self={"20": 1}): !result: []
2466    sa(self={"20": 1}): !result: [[], {'20': 1}]
2467    psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
2468    psa2(self={"20": 1}): !result: [[], {'20': 1}]
2469    psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
2470    psa4(self={"20": 1}): !result: [[], {'20': 1}]
2471    a.args: None
2472    pa1.args: ['abcArgsPA1']
2473    pa2.args: None
2474    pa3.args: ['abcArgsPA3']
2475    pa4.args: None
2476    sa.args: None
2477    psa1.args: ['abcArgsPSA1']
2478    psa2.args: None
2479    psa3.args: ['abcArgsPSA3']
2480    psa4.args: None
2481    a.self: None
2482    pa1.self: None
2483    pa2.self: None
2484    pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
2485    pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
2486    sa.self: None
2487    psa1.self: None
2488    psa2.self: None
2489    psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
2490    psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
2491    a.name: 'Args'
2492    pa1.name: 'Args'
2493    pa2.name: 'Args'
2494    pa3.name: 'Args'
2495    pa4.name: 'Args'
2496    sa.name: 'SelfArgs'
2497    psa1.name: 'SelfArgs'
2498    psa2.name: 'SelfArgs'
2499    psa3.name: 'SelfArgs'
2500    psa4.name: 'SelfArgs'
2501    a.auto_rebind: 1
2502    pa1.auto_rebind: 1
2503    pa2.auto_rebind: 1
2504    pa3.auto_rebind: 0
2505    pa4.auto_rebind: 0
2506    sa.auto_rebind: 1
2507    psa1.auto_rebind: 1
2508    psa2.auto_rebind: 1
2509    psa3.auto_rebind: 0
2510    psa4.auto_rebind: 0
2511    psa5.auto_rebind: 0
2512    psa6.auto_rebind: 0
2513    psa7.auto_rebind: 1
2514    psa8.auto_rebind: 1
2515    psa9.auto_rebind: 1
2516    psaA.auto_rebind: 1
2517    psaB.auto_rebind: 1
2518    psaC.auto_rebind: 1
2519  END
2520  call assert_equal(expected, getline(2, '$'))
2521  %bw!
2522endfunc
2523
2524" Test stdout/stderr
2525func Test_python3_stdin_stderr()
2526  let caught_writeerr = 0
2527  let caught_writelineerr = 0
2528  redir => messages
2529  py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
2530  try
2531    py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
2532  catch /abc9def/
2533    let caught_writeerr = 1
2534  endtry
2535  py3 sys.stdout.writelines(iter('abcA'))
2536  try
2537    py3 sys.stderr.writelines(iter('abcB'))
2538  catch /abcB/
2539    let caught_writelineerr = 1
2540  endtry
2541  redir END
2542  call assert_equal("\nabc8def\nabcA", messages)
2543  call assert_equal(1, caught_writeerr)
2544  call assert_equal(1, caught_writelineerr)
2545endfunc
2546
2547" Test subclassing
2548func Test_python3_subclass()
2549  new
2550  func Put(...)
2551    return a:000
2552  endfunc
2553
2554  py3 << trim EOF
2555    class DupDict(vim.Dictionary):
2556      def __setitem__(self, key, value):
2557        super(DupDict, self).__setitem__(key, value)
2558        super(DupDict, self).__setitem__('dup_' + key, value)
2559    dd = DupDict()
2560    dd['a'] = 'b'
2561
2562    class DupList(vim.List):
2563      def __getitem__(self, idx):
2564        return [super(DupList, self).__getitem__(idx)] * 2
2565
2566    dl = DupList()
2567    dl2 = DupList(iter('abcC'))
2568    dl.extend(dl2[0])
2569
2570    class DupFun(vim.Function):
2571      def __call__(self, arg):
2572        return super(DupFun, self).__call__(arg, arg)
2573
2574    df = DupFun('Put')
2575  EOF
2576
2577  call assert_equal(['a', 'dup_a'], sort(keys(py3eval('dd'))))
2578  call assert_equal(['a', 'a'], py3eval('dl'))
2579  call assert_equal(['a', 'b', 'c', 'C'], py3eval('dl2'))
2580  call assert_equal([2, 2], py3eval('df(2)'))
2581  call assert_equal(1, py3eval('dl') is# py3eval('dl'))
2582  call assert_equal(1, py3eval('dd') is# py3eval('dd'))
2583  call assert_equal(function('Put'), py3eval('df'))
2584  delfunction Put
2585  py3 << trim EOF
2586    del DupDict
2587    del DupList
2588    del DupFun
2589    del dd
2590    del dl
2591    del dl2
2592    del df
2593  EOF
2594  close!
2595endfunc
2596
2597" Test chdir
2598func Test_python3_chdir()
2599  new Xfile
2600  py3 cb = vim.current.buffer
2601  py3 << trim EOF
2602    import os
2603    fnamemodify = vim.Function('fnamemodify')
2604    cb.append(str(fnamemodify('.', ':p:h:t')))
2605    cb.append(vim.eval('@%'))
2606    os.chdir('..')
2607    path = fnamemodify('.', ':p:h:t')
2608    if path != b'src' and path != b'src2':
2609      # Running tests from a shadow directory, so move up another level
2610      # This will result in @% looking like shadow/testdir/Xfile, hence the
2611      # slicing to remove the leading path and path separator
2612      os.chdir('..')
2613      cb.append(str(fnamemodify('.', ':p:h:t')))
2614      cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
2615      os.chdir(path)
2616    else:
2617      # Also accept running from src2/testdir/ for MS-Windows CI.
2618      cb.append(str(fnamemodify('.', ':p:h:t').replace(b'src2', b'src')))
2619      cb.append(vim.eval('@%').replace(os.path.sep, '/'))
2620    del path
2621    os.chdir('testdir')
2622    cb.append(str(fnamemodify('.', ':p:h:t')))
2623    cb.append(vim.eval('@%'))
2624    del fnamemodify
2625  EOF
2626  call assert_equal(["b'testdir'", 'Xfile', "b'src'", 'testdir/Xfile',
2627        \"b'testdir'", 'Xfile'], getline(2, '$'))
2628  close!
2629  call AssertException(["py3 vim.chdir(None)"], "Vim(py3):TypeError:")
2630endfunc
2631
2632" Test errors
2633func Test_python3_errors()
2634  func F() dict
2635  endfunc
2636
2637  func D()
2638  endfunc
2639
2640  new
2641  py3 cb = vim.current.buffer
2642
2643  py3 << trim EOF
2644    import os
2645    d = vim.Dictionary()
2646    ned = vim.Dictionary(foo='bar', baz='abcD')
2647    dl = vim.Dictionary(a=1)
2648    dl.locked = True
2649    l = vim.List()
2650    ll = vim.List('abcE')
2651    ll.locked = True
2652    nel = vim.List('abcO')
2653    f = vim.Function('string')
2654    fd = vim.Function('F')
2655    fdel = vim.Function('D')
2656    vim.command('delfunction D')
2657
2658    def subexpr_test(expr, name, subexprs):
2659        cb.append('>>> Testing %s using %s' % (name, expr))
2660        for subexpr in subexprs:
2661            ee(expr % subexpr)
2662        cb.append('<<< Finished')
2663
2664    def stringtochars_test(expr):
2665        return subexpr_test(expr, 'StringToChars', (
2666            '1',       # Fail type checks
2667            'b"\\0"',  # Fail PyString_AsStringAndSize(object, , NULL) check
2668            '"\\0"',   # Fail PyString_AsStringAndSize(bytes, , NULL) check
2669        ))
2670
2671    class Mapping(object):
2672        def __init__(self, d):
2673            self.d = d
2674
2675        def __getitem__(self, key):
2676            return self.d[key]
2677
2678        def keys(self):
2679            return self.d.keys()
2680
2681        def items(self):
2682            return self.d.items()
2683
2684    def convertfrompyobject_test(expr, recurse=True):
2685        # pydict_to_tv
2686        stringtochars_test(expr % '{%s : 1}')
2687        if recurse:
2688            convertfrompyobject_test(expr % '{"abcF" : %s}', False)
2689        # pymap_to_tv
2690        stringtochars_test(expr % 'Mapping({%s : 1})')
2691        if recurse:
2692            convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
2693        # pyseq_to_tv
2694        iter_test(expr)
2695        return subexpr_test(expr, 'ConvertFromPyObject', (
2696            'None',                 # Not conversible
2697            '{b"": 1}',             # Empty key not allowed
2698            '{"": 1}',              # Same, but with unicode object
2699            'FailingMapping()',     #
2700            'FailingMappingKey()',  #
2701            'FailingNumber()',      #
2702        ))
2703
2704    def convertfrompymapping_test(expr):
2705        convertfrompyobject_test(expr)
2706        return subexpr_test(expr, 'ConvertFromPyMapping', (
2707            '[]',
2708        ))
2709
2710    def iter_test(expr):
2711        return subexpr_test(expr, '*Iter*', (
2712            'FailingIter()',
2713            'FailingIterNext()',
2714        ))
2715
2716    def number_test(expr, natural=False, unsigned=False):
2717        if natural:
2718            unsigned = True
2719        return subexpr_test(expr, 'NumberToLong', (
2720            '[]',
2721            'None',
2722        ) + (('-1',) if unsigned else ())
2723        + (('0',) if natural else ()))
2724
2725    class FailingTrue(object):
2726        def __bool__(self):
2727            raise NotImplementedError('bool')
2728
2729    class FailingIter(object):
2730        def __iter__(self):
2731            raise NotImplementedError('iter')
2732
2733    class FailingIterNext(object):
2734        def __iter__(self):
2735            return self
2736
2737        def __next__(self):
2738          raise NotImplementedError('next')
2739
2740    class FailingIterNextN(object):
2741        def __init__(self, n):
2742            self.n = n
2743
2744        def __iter__(self):
2745            return self
2746
2747        def __next__(self):
2748            if self.n:
2749                self.n -= 1
2750                return 1
2751            else:
2752                raise NotImplementedError('next N')
2753
2754    class FailingMappingKey(object):
2755        def __getitem__(self, item):
2756            raise NotImplementedError('getitem:mappingkey')
2757
2758        def keys(self):
2759            return list("abcH")
2760
2761    class FailingMapping(object):
2762        def __getitem__(self):
2763            raise NotImplementedError('getitem:mapping')
2764
2765        def keys(self):
2766            raise NotImplementedError('keys')
2767
2768    class FailingList(list):
2769        def __getitem__(self, idx):
2770            if i == 2:
2771                raise NotImplementedError('getitem:list')
2772            else:
2773                return super(FailingList, self).__getitem__(idx)
2774
2775    class NoArgsCall(object):
2776        def __call__(self):
2777            pass
2778
2779    class FailingCall(object):
2780        def __call__(self, path):
2781            raise NotImplementedError('call')
2782
2783    class FailingNumber(object):
2784        def __int__(self):
2785            raise NotImplementedError('int')
2786
2787    cb.append("> Output")
2788    cb.append(">> OutputSetattr")
2789    ee('del sys.stdout.softspace')
2790    number_test('sys.stdout.softspace = %s', unsigned=True)
2791    number_test('sys.stderr.softspace = %s', unsigned=True)
2792    ee('assert sys.stdout.isatty()==False')
2793    ee('assert sys.stdout.seekable()==False')
2794    ee('sys.stdout.close()')
2795    ee('sys.stdout.flush()')
2796    ee('assert sys.stderr.isatty()==False')
2797    ee('assert sys.stderr.seekable()==False')
2798    ee('sys.stderr.close()')
2799    ee('sys.stderr.flush()')
2800    ee('sys.stdout.attr = None')
2801    cb.append(">> OutputWrite")
2802    ee('assert sys.stdout.writable()==True')
2803    ee('assert sys.stdout.readable()==False')
2804    ee('assert sys.stderr.writable()==True')
2805    ee('assert sys.stderr.readable()==False')
2806    ee('assert sys.stdout.closed()==False')
2807    ee('assert sys.stderr.closed()==False')
2808    ee('assert sys.stdout.errors=="strict"')
2809    ee('assert sys.stderr.errors=="strict"')
2810    ee('assert sys.stdout.encoding==sys.stderr.encoding')
2811    ee('sys.stdout.write(None)')
2812    cb.append(">> OutputWriteLines")
2813    ee('sys.stdout.writelines(None)')
2814    ee('sys.stdout.writelines([1])')
2815    iter_test('sys.stdout.writelines(%s)')
2816    cb.append("> VimCommand")
2817    stringtochars_test('vim.command(%s)')
2818    ee('vim.command("", 2)')
2819    #! Not checked: vim->python exceptions translating: checked later
2820    cb.append("> VimToPython")
2821    #! Not checked: everything: needs errors in internal python functions
2822    cb.append("> VimEval")
2823    stringtochars_test('vim.eval(%s)')
2824    ee('vim.eval("", FailingTrue())')
2825    #! Not checked: everything: needs errors in internal python functions
2826    cb.append("> VimEvalPy")
2827    stringtochars_test('vim.bindeval(%s)')
2828    ee('vim.eval("", 2)')
2829    #! Not checked: vim->python exceptions translating: checked later
2830    cb.append("> VimStrwidth")
2831    stringtochars_test('vim.strwidth(%s)')
2832    cb.append("> VimForeachRTP")
2833    ee('vim.foreach_rtp(None)')
2834    ee('vim.foreach_rtp(NoArgsCall())')
2835    ee('vim.foreach_rtp(FailingCall())')
2836    ee('vim.foreach_rtp(int, 2)')
2837    cb.append('> import')
2838    old_rtp = vim.options['rtp']
2839    vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
2840    ee('import xxx_no_such_module_xxx')
2841    ee('import failing_import')
2842    ee('import failing')
2843    vim.options['rtp'] = old_rtp
2844    del old_rtp
2845    cb.append("> Options")
2846    cb.append(">> OptionsItem")
2847    ee('vim.options["abcQ"]')
2848    ee('vim.options[""]')
2849    stringtochars_test('vim.options[%s]')
2850    cb.append(">> OptionsContains")
2851    stringtochars_test('%s in vim.options')
2852    cb.append("> Dictionary")
2853    cb.append(">> DictionaryConstructor")
2854    ee('vim.Dictionary("abcI")')
2855    ##! Not checked: py_dict_alloc failure
2856    cb.append(">> DictionarySetattr")
2857    ee('del d.locked')
2858    ee('d.locked = FailingTrue()')
2859    ee('vim.vvars.locked = False')
2860    ee('d.scope = True')
2861    ee('d.xxx = True')
2862    cb.append(">> _DictionaryItem")
2863    ee('d.get("a", 2, 3)')
2864    stringtochars_test('d.get(%s)')
2865    ee('d.pop("a")')
2866    ee('dl.pop("a")')
2867    cb.append(">> DictionaryContains")
2868    ee('"" in d')
2869    ee('0 in d')
2870    cb.append(">> DictionaryIterNext")
2871    ee('for i in ned: ned["a"] = 1')
2872    del i
2873    cb.append(">> DictionaryAssItem")
2874    ee('dl["b"] = 1')
2875    stringtochars_test('d[%s] = 1')
2876    convertfrompyobject_test('d["a"] = %s')
2877    cb.append(">> DictionaryUpdate")
2878    cb.append(">>> kwargs")
2879    cb.append(">>> iter")
2880    ee('d.update(FailingMapping())')
2881    ee('d.update([FailingIterNext()])')
2882    ee('d.update([FailingIterNextN(1)])')
2883    iter_test('d.update(%s)')
2884    convertfrompyobject_test('d.update(%s)')
2885    stringtochars_test('d.update(((%s, 0),))')
2886    convertfrompyobject_test('d.update((("a", %s),))')
2887    cb.append(">> DictionaryPopItem")
2888    ee('d.popitem(1, 2)')
2889    cb.append(">> DictionaryHasKey")
2890    ee('d.has_key()')
2891    cb.append("> List")
2892    cb.append(">> ListConstructor")
2893    ee('vim.List(1, 2)')
2894    ee('vim.List(a=1)')
2895    iter_test('vim.List(%s)')
2896    convertfrompyobject_test('vim.List([%s])')
2897    cb.append(">> ListItem")
2898    ee('l[1000]')
2899    cb.append(">> ListAssItem")
2900    ee('ll[1] = 2')
2901    ee('l[1000] = 3')
2902    cb.append(">> ListAssSlice")
2903    ee('ll[1:100] = "abcJ"')
2904    iter_test('l[:] = %s')
2905    ee('nel[1:10:2]  = "abcK"')
2906    cb.append(repr(tuple(nel)))
2907    ee('nel[1:10:2]  = "a"')
2908    cb.append(repr(tuple(nel)))
2909    ee('nel[1:1:-1]  = "a"')
2910    cb.append(repr(tuple(nel)))
2911    ee('nel[:] = FailingIterNextN(2)')
2912    cb.append(repr(tuple(nel)))
2913    convertfrompyobject_test('l[:] = [%s]')
2914    cb.append(">> ListConcatInPlace")
2915    iter_test('l.extend(%s)')
2916    convertfrompyobject_test('l.extend([%s])')
2917    cb.append(">> ListSetattr")
2918    ee('del l.locked')
2919    ee('l.locked = FailingTrue()')
2920    ee('l.xxx = True')
2921    cb.append("> Function")
2922    cb.append(">> FunctionConstructor")
2923    cb.append(">>> FunctionConstructor")
2924    ee('vim.Function("123")')
2925    ee('vim.Function("xxx_non_existent_function_xxx")')
2926    ee('vim.Function("xxx#non#existent#function#xxx")')
2927    ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
2928    ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
2929    ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
2930    cb.append(">>> FunctionNew")
2931    ee('vim.Function("tr", self="abcFuncSelf")')
2932    ee('vim.Function("tr", args=427423)')
2933    ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
2934    ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
2935    ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
2936    ee('vim.Function("tr", "")')
2937    cb.append(">> FunctionCall")
2938    convertfrompyobject_test('f(%s)')
2939    convertfrompymapping_test('fd(self=%s)')
2940    cb.append("> TabPage")
2941    cb.append(">> TabPageAttr")
2942    ee('vim.current.tabpage.xxx')
2943    cb.append("> TabList")
2944    cb.append(">> TabListItem")
2945    ee('vim.tabpages[1000]')
2946    cb.append("> Window")
2947    cb.append(">> WindowAttr")
2948    ee('vim.current.window.xxx')
2949    cb.append(">> WindowSetattr")
2950    ee('vim.current.window.buffer = 0')
2951    ee('vim.current.window.cursor = (100000000, 100000000)')
2952    ee('vim.current.window.cursor = True')
2953    number_test('vim.current.window.height = %s', unsigned=True)
2954    number_test('vim.current.window.width = %s', unsigned=True)
2955    ee('vim.current.window.xxxxxx = True')
2956    cb.append("> WinList")
2957    cb.append(">> WinListItem")
2958    ee('vim.windows[1000]')
2959    cb.append("> Buffer")
2960    cb.append(">> StringToLine (indirect)")
2961    ee('vim.current.buffer[0] = "\\na"')
2962    ee('vim.current.buffer[0] = b"\\na"')
2963    cb.append(">> SetBufferLine (indirect)")
2964    ee('vim.current.buffer[0] = True')
2965    cb.append(">> SetBufferLineList (indirect)")
2966    ee('vim.current.buffer[:] = True')
2967    ee('vim.current.buffer[:] = ["\\na", "bc"]')
2968    cb.append(">> InsertBufferLines (indirect)")
2969    ee('vim.current.buffer.append(None)')
2970    ee('vim.current.buffer.append(["\\na", "bc"])')
2971    ee('vim.current.buffer.append("\\nbc")')
2972    cb.append(">> RBItem")
2973    ee('vim.current.buffer[100000000]')
2974    cb.append(">> RBAsItem")
2975    ee('vim.current.buffer[100000000] = ""')
2976    cb.append(">> BufferAttr")
2977    ee('vim.current.buffer.xxx')
2978    cb.append(">> BufferSetattr")
2979    ee('vim.current.buffer.name = True')
2980    ee('vim.current.buffer.xxx = True')
2981    cb.append(">> BufferMark")
2982    ee('vim.current.buffer.mark(0)')
2983    ee('vim.current.buffer.mark("abcM")')
2984    ee('vim.current.buffer.mark("!")')
2985    cb.append(">> BufferRange")
2986    ee('vim.current.buffer.range(1, 2, 3)')
2987    cb.append("> BufMap")
2988    cb.append(">> BufMapItem")
2989    ee('vim.buffers[100000000]')
2990    number_test('vim.buffers[%s]', natural=True)
2991    cb.append("> Current")
2992    cb.append(">> CurrentGetattr")
2993    ee('vim.current.xxx')
2994    cb.append(">> CurrentSetattr")
2995    ee('vim.current.line = True')
2996    ee('vim.current.buffer = True')
2997    ee('vim.current.window = True')
2998    ee('vim.current.tabpage = True')
2999    ee('vim.current.xxx = True')
3000    del d
3001    del ned
3002    del dl
3003    del l
3004    del ll
3005    del nel
3006    del f
3007    del fd
3008    del fdel
3009    del subexpr_test
3010    del stringtochars_test
3011    del Mapping
3012    del convertfrompyobject_test
3013    del convertfrompymapping_test
3014    del iter_test
3015    del number_test
3016    del FailingTrue
3017    del FailingIter
3018    del FailingIterNext
3019    del FailingIterNextN
3020    del FailingMapping
3021    del FailingMappingKey
3022    del FailingList
3023    del NoArgsCall
3024    del FailingCall
3025    del FailingNumber
3026  EOF
3027  delfunction F
3028
3029  let expected =<< trim END
3030    > Output
3031    >> OutputSetattr
3032    del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError('cannot delete OutputObject attributes',))
3033    >>> Testing NumberToLong using sys.stdout.softspace = %s
3034    sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3035    sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3036    sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3037    <<< Finished
3038    >>> Testing NumberToLong using sys.stderr.softspace = %s
3039    sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3040    sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3041    sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3042    <<< Finished
3043    assert sys.stdout.isatty()==False:NOT FAILED
3044    assert sys.stdout.seekable()==False:NOT FAILED
3045    sys.stdout.close():NOT FAILED
3046    sys.stdout.flush():NOT FAILED
3047    assert sys.stderr.isatty()==False:NOT FAILED
3048    assert sys.stderr.seekable()==False:NOT FAILED
3049    sys.stderr.close():NOT FAILED
3050    sys.stderr.flush():NOT FAILED
3051    sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
3052    >> OutputWrite
3053    assert sys.stdout.writable()==True:NOT FAILED
3054    assert sys.stdout.readable()==False:NOT FAILED
3055    assert sys.stderr.writable()==True:NOT FAILED
3056    assert sys.stderr.readable()==False:NOT FAILED
3057    assert sys.stdout.closed()==False:NOT FAILED
3058    assert sys.stderr.closed()==False:NOT FAILED
3059    assert sys.stdout.errors=="strict":NOT FAILED
3060    assert sys.stderr.errors=="strict":NOT FAILED
3061    assert sys.stdout.encoding==sys.stderr.encoding:NOT FAILED
3062    sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
3063    >> OutputWriteLines
3064    sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3065    sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
3066    >>> Testing *Iter* using sys.stdout.writelines(%s)
3067    sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3068    sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3069    <<< Finished
3070    > VimCommand
3071    >>> Testing StringToChars using vim.command(%s)
3072    vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3073    vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3074    vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3075    <<< Finished
3076    vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
3077    > VimToPython
3078    > VimEval
3079    >>> Testing StringToChars using vim.eval(%s)
3080    vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3081    vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3082    vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3083    <<< Finished
3084    vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3085    > VimEvalPy
3086    >>> Testing StringToChars using vim.bindeval(%s)
3087    vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3088    vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3089    vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3090    <<< Finished
3091    vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3092    > VimStrwidth
3093    >>> Testing StringToChars using vim.strwidth(%s)
3094    vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3095    vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3096    vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3097    <<< Finished
3098    > VimForeachRTP
3099    vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
3100    vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
3101    vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
3102    vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
3103    > import
3104    import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
3105    import failing_import:(<class 'ImportError'>, ImportError())
3106    import failing:(<class 'NotImplementedError'>, NotImplementedError())
3107    > Options
3108    >> OptionsItem
3109    vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
3110    vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3111    >>> Testing StringToChars using vim.options[%s]
3112    vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3113    vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3114    vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3115    <<< Finished
3116    >> OptionsContains
3117    >>> Testing StringToChars using %s in vim.options
3118    1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3119    b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3120    "\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3121    <<< Finished
3122    > Dictionary
3123    >> DictionaryConstructor
3124    vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
3125    >> DictionarySetattr
3126    del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
3127    d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3128    vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
3129    d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
3130    d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3131    >> _DictionaryItem
3132    d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
3133    >>> Testing StringToChars using d.get(%s)
3134    d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3135    d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3136    d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3137    <<< Finished
3138    d.pop("a"):(<class 'KeyError'>, KeyError('a',))
3139    dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
3140    >> DictionaryContains
3141    "" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3142    0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3143    >> DictionaryIterNext
3144    for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
3145    >> DictionaryAssItem
3146    dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
3147    >>> Testing StringToChars using d[%s] = 1
3148    d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3149    d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3150    d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3151    <<< Finished
3152    >>> Testing StringToChars using d["a"] = {%s : 1}
3153    d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3154    d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3155    d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3156    <<< Finished
3157    >>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
3158    d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3159    d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3160    d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3161    <<< Finished
3162    >>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
3163    d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3164    d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3165    d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3166    <<< Finished
3167    >>> Testing *Iter* using d["a"] = {"abcF" : %s}
3168    d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3169    d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
3170    <<< Finished
3171    >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
3172    d["a"] = {"abcF" : None}:NOT FAILED
3173    d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3174    d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3175    d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3176    d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3177    d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
3178    <<< Finished
3179    >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
3180    d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3181    d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3182    d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3183    <<< Finished
3184    >>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
3185    d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3186    d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3187    d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3188    <<< Finished
3189    >>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
3190    d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3191    d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3192    d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3193    <<< Finished
3194    >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
3195    d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3196    d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3197    <<< Finished
3198    >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
3199    d["a"] = Mapping({"abcG" : None}):NOT FAILED
3200    d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3201    d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3202    d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3203    d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3204    d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3205    <<< Finished
3206    >>> Testing *Iter* using d["a"] = %s
3207    d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3208    d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3209    <<< Finished
3210    >>> Testing ConvertFromPyObject using d["a"] = %s
3211    d["a"] = None:NOT FAILED
3212    d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3213    d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3214    d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
3215    d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3216    d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
3217    <<< Finished
3218    >> DictionaryUpdate
3219    >>> kwargs
3220    >>> iter
3221    d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3222    d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3223    d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3224    >>> Testing *Iter* using d.update(%s)
3225    d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3226    d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3227    <<< Finished
3228    >>> Testing StringToChars using d.update({%s : 1})
3229    d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3230    d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3231    d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3232    <<< Finished
3233    >>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
3234    d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3235    d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3236    d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3237    <<< Finished
3238    >>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
3239    d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3240    d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3241    d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3242    <<< Finished
3243    >>> Testing *Iter* using d.update({"abcF" : %s})
3244    d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3245    d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3246    <<< Finished
3247    >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
3248    d.update({"abcF" : None}):NOT FAILED
3249    d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3250    d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3251    d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3252    d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3253    d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3254    <<< Finished
3255    >>> Testing StringToChars using d.update(Mapping({%s : 1}))
3256    d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3257    d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3258    d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3259    <<< Finished
3260    >>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
3261    d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3262    d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3263    d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3264    <<< Finished
3265    >>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
3266    d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3267    d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3268    d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3269    <<< Finished
3270    >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
3271    d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3272    d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3273    <<< Finished
3274    >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
3275    d.update(Mapping({"abcG" : None})):NOT FAILED
3276    d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3277    d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3278    d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3279    d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3280    d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3281    <<< Finished
3282    >>> Testing *Iter* using d.update(%s)
3283    d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3284    d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3285    <<< Finished
3286    >>> Testing ConvertFromPyObject using d.update(%s)
3287    d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3288    d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3289    d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3290    d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3291    d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3292    d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
3293    <<< Finished
3294    >>> Testing StringToChars using d.update(((%s, 0),))
3295    d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3296    d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3297    d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3298    <<< Finished
3299    >>> Testing StringToChars using d.update((("a", {%s : 1}),))
3300    d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3301    d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3302    d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3303    <<< Finished
3304    >>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
3305    d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3306    d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3307    d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3308    <<< Finished
3309    >>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
3310    d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3311    d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3312    d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3313    <<< Finished
3314    >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
3315    d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3316    d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3317    <<< Finished
3318    >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
3319    d.update((("a", {"abcF" : None}),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3320    d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3321    d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3322    d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3323    d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3324    d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3325    <<< Finished
3326    >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
3327    d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3328    d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3329    d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3330    <<< Finished
3331    >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
3332    d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3333    d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3334    d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3335    <<< Finished
3336    >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
3337    d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3338    d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3339    d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3340    <<< Finished
3341    >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
3342    d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3343    d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3344    <<< Finished
3345    >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
3346    d.update((("a", Mapping({"abcG" : None})),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3347    d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3348    d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3349    d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3350    d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3351    d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3352    <<< Finished
3353    >>> Testing *Iter* using d.update((("a", %s),))
3354    d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3355    d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3356    <<< Finished
3357    >>> Testing ConvertFromPyObject using d.update((("a", %s),))
3358    d.update((("a", None),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3359    d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3360    d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3361    d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3362    d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3363    d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3364    <<< Finished
3365    >> DictionaryPopItem
3366    d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
3367    >> DictionaryHasKey
3368    d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
3369    > List
3370    >> ListConstructor
3371    vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
3372    vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
3373    >>> Testing *Iter* using vim.List(%s)
3374    vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3375    vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3376    <<< Finished
3377    >>> Testing StringToChars using vim.List([{%s : 1}])
3378    vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3379    vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3380    vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3381    <<< Finished
3382    >>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
3383    vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3384    vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3385    vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3386    <<< Finished
3387    >>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
3388    vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3389    vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3390    vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3391    <<< Finished
3392    >>> Testing *Iter* using vim.List([{"abcF" : %s}])
3393    vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3394    vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3395    <<< Finished
3396    >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
3397    vim.List([{"abcF" : None}]):NOT FAILED
3398    vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3399    vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3400    vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3401    vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3402    vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3403    <<< Finished
3404    >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
3405    vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3406    vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3407    vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3408    <<< Finished
3409    >>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
3410    vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3411    vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3412    vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3413    <<< Finished
3414    >>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
3415    vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3416    vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3417    vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3418    <<< Finished
3419    >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
3420    vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3421    vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3422    <<< Finished
3423    >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
3424    vim.List([Mapping({"abcG" : None})]):NOT FAILED
3425    vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3426    vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3427    vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3428    vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3429    vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3430    <<< Finished
3431    >>> Testing *Iter* using vim.List([%s])
3432    vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3433    vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3434    <<< Finished
3435    >>> Testing ConvertFromPyObject using vim.List([%s])
3436    vim.List([None]):NOT FAILED
3437    vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3438    vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3439    vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3440    vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3441    vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3442    <<< Finished
3443    >> ListItem
3444    l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
3445    >> ListAssItem
3446    ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
3447    l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
3448    >> ListAssSlice
3449    ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
3450    >>> Testing *Iter* using l[:] = %s
3451    l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
3452    l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3453    <<< Finished
3454    nel[1:10:2]  = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 2 to extended slice',))
3455    (b'a', b'b', b'c', b'O')
3456    nel[1:10:2]  = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
3457    (b'a', b'b', b'c', b'O')
3458    nel[1:1:-1]  = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 0 to extended slice',))
3459    (b'a', b'b', b'c', b'O')
3460    nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3461    (b'a', b'b', b'c', b'O')
3462    >>> Testing StringToChars using l[:] = [{%s : 1}]
3463    l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3464    l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3465    l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3466    <<< Finished
3467    >>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
3468    l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3469    l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3470    l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3471    <<< Finished
3472    >>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
3473    l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3474    l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3475    l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3476    <<< Finished
3477    >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
3478    l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3479    l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3480    <<< Finished
3481    >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
3482    l[:] = [{"abcF" : None}]:NOT FAILED
3483    l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3484    l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3485    l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3486    l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3487    l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3488    <<< Finished
3489    >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
3490    l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3491    l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3492    l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3493    <<< Finished
3494    >>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
3495    l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3496    l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3497    l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3498    <<< Finished
3499    >>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
3500    l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3501    l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3502    l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3503    <<< Finished
3504    >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
3505    l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3506    l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3507    <<< Finished
3508    >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
3509    l[:] = [Mapping({"abcG" : None})]:NOT FAILED
3510    l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3511    l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3512    l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3513    l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3514    l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3515    <<< Finished
3516    >>> Testing *Iter* using l[:] = [%s]
3517    l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3518    l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3519    <<< Finished
3520    >>> Testing ConvertFromPyObject using l[:] = [%s]
3521    l[:] = [None]:NOT FAILED
3522    l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3523    l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3524    l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3525    l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3526    l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3527    <<< Finished
3528    >> ListConcatInPlace
3529    >>> Testing *Iter* using l.extend(%s)
3530    l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3531    l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3532    <<< Finished
3533    >>> Testing StringToChars using l.extend([{%s : 1}])
3534    l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3535    l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3536    l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3537    <<< Finished
3538    >>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
3539    l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3540    l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3541    l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3542    <<< Finished
3543    >>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
3544    l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3545    l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3546    l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3547    <<< Finished
3548    >>> Testing *Iter* using l.extend([{"abcF" : %s}])
3549    l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3550    l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3551    <<< Finished
3552    >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
3553    l.extend([{"abcF" : None}]):NOT FAILED
3554    l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3555    l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3556    l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3557    l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3558    l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3559    <<< Finished
3560    >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
3561    l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3562    l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3563    l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3564    <<< Finished
3565    >>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
3566    l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3567    l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3568    l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3569    <<< Finished
3570    >>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
3571    l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3572    l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3573    l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3574    <<< Finished
3575    >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
3576    l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3577    l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3578    <<< Finished
3579    >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
3580    l.extend([Mapping({"abcG" : None})]):NOT FAILED
3581    l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3582    l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3583    l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3584    l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3585    l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3586    <<< Finished
3587    >>> Testing *Iter* using l.extend([%s])
3588    l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3589    l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3590    <<< Finished
3591    >>> Testing ConvertFromPyObject using l.extend([%s])
3592    l.extend([None]):NOT FAILED
3593    l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3594    l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3595    l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3596    l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3597    l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3598    <<< Finished
3599    >> ListSetattr
3600    del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
3601    l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3602    l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3603    > Function
3604    >> FunctionConstructor
3605    >>> FunctionConstructor
3606    vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
3607    vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
3608    vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
3609    vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
3610    vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
3611    vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
3612    >>> FunctionNew
3613    vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
3614    vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to a Vim list',))
3615    vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3616    vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3617    vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3618    vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3619    >> FunctionCall
3620    >>> Testing StringToChars using f({%s : 1})
3621    f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3622    f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3623    f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3624    <<< Finished
3625    >>> Testing StringToChars using f({"abcF" : {%s : 1}})
3626    f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3627    f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3628    f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3629    <<< Finished
3630    >>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
3631    f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3632    f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3633    f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3634    <<< Finished
3635    >>> Testing *Iter* using f({"abcF" : %s})
3636    f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3637    f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3638    <<< Finished
3639    >>> Testing ConvertFromPyObject using f({"abcF" : %s})
3640    f({"abcF" : None}):NOT FAILED
3641    f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3642    f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3643    f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3644    f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3645    f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3646    <<< Finished
3647    >>> Testing StringToChars using f(Mapping({%s : 1}))
3648    f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3649    f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3650    f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3651    <<< Finished
3652    >>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
3653    f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3654    f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3655    f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3656    <<< Finished
3657    >>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
3658    f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3659    f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3660    f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3661    <<< Finished
3662    >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
3663    f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3664    f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3665    <<< Finished
3666    >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
3667    f(Mapping({"abcG" : None})):NOT FAILED
3668    f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3669    f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3670    f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3671    f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3672    f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3673    <<< Finished
3674    >>> Testing *Iter* using f(%s)
3675    f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3676    f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3677    <<< Finished
3678    >>> Testing ConvertFromPyObject using f(%s)
3679    f(None):NOT FAILED
3680    f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3681    f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3682    f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3683    f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3684    f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
3685    <<< Finished
3686    >>> Testing StringToChars using fd(self={%s : 1})
3687    fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3688    fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3689    fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3690    <<< Finished
3691    >>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
3692    fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3693    fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3694    fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3695    <<< Finished
3696    >>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
3697    fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3698    fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3699    fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3700    <<< Finished
3701    >>> Testing *Iter* using fd(self={"abcF" : %s})
3702    fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3703    fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3704    <<< Finished
3705    >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
3706    fd(self={"abcF" : None}):NOT FAILED
3707    fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3708    fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3709    fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3710    fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3711    fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3712    <<< Finished
3713    >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
3714    fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3715    fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3716    fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3717    <<< Finished
3718    >>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
3719    fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3720    fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3721    fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3722    <<< Finished
3723    >>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
3724    fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3725    fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3726    fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3727    <<< Finished
3728    >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
3729    fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3730    fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3731    <<< Finished
3732    >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
3733    fd(self=Mapping({"abcG" : None})):NOT FAILED
3734    fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3735    fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3736    fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3737    fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3738    fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3739    <<< Finished
3740    >>> Testing *Iter* using fd(self=%s)
3741    fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim dictionary',))
3742    fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to a Vim dictionary',))
3743    <<< Finished
3744    >>> Testing ConvertFromPyObject using fd(self=%s)
3745    fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to a Vim dictionary',))
3746    fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3747    fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3748    fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3749    fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3750    fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to a Vim dictionary',))
3751    <<< Finished
3752    >>> Testing ConvertFromPyMapping using fd(self=%s)
3753    fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
3754    <<< Finished
3755    > TabPage
3756    >> TabPageAttr
3757    vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
3758    > TabList
3759    >> TabListItem
3760    vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
3761    > Window
3762    >> WindowAttr
3763    vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
3764    >> WindowSetattr
3765    vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
3766    vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
3767    vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
3768    >>> Testing NumberToLong using vim.current.window.height = %s
3769    vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3770    vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3771    vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3772    <<< Finished
3773    >>> Testing NumberToLong using vim.current.window.width = %s
3774    vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3775    vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3776    vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3777    <<< Finished
3778    vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
3779    > WinList
3780    >> WinListItem
3781    vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
3782    > Buffer
3783    >> StringToLine (indirect)
3784    vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3785    vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3786    >> SetBufferLine (indirect)
3787    vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3788    >> SetBufferLineList (indirect)
3789    vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3790    vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
3791    >> InsertBufferLines (indirect)
3792    vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3793    vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
3794    vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
3795    >> RBItem
3796    vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
3797    >> RBAsItem
3798    vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
3799    >> BufferAttr
3800    vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
3801    >> BufferSetattr
3802    vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
3803    vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3804    >> BufferMark
3805    vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3806    vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
3807    vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
3808    >> BufferRange
3809    vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
3810    > BufMap
3811    >> BufMapItem
3812    vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
3813    >>> Testing NumberToLong using vim.buffers[%s]
3814    vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3815    vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3816    vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3817    vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3818    <<< Finished
3819    > Current
3820    >> CurrentGetattr
3821    vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
3822    >> CurrentSetattr
3823    vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3824    vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
3825    vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
3826    vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
3827    vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3828  END
3829
3830  let actual = getline(2, '$')
3831  let n_expected = len(expected)
3832  let n_actual = len(actual)
3833  call assert_equal(n_expected, n_actual, 'number of lines to compare')
3834
3835  " Compare line by line so the errors are easier to understand.  Missing lines
3836  " are compared with an empty string.
3837  for i in range(n_expected > n_actual ? n_expected : n_actual)
3838    call assert_equal(i >= n_expected ? '' : expected[i], i >= n_actual ? '' : actual[i])
3839  endfor
3840  close!
3841endfunc
3842
3843" Test import
3844func Test_python3_import()
3845  new
3846  py3 cb = vim.current.buffer
3847
3848  py3 << trim EOF
3849    sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
3850    sys.path.append(os.path.join(os.getcwd(), 'python_after'))
3851    vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
3852    l = []
3853    def callback(path):
3854        l.append(os.path.relpath(path))
3855    vim.foreach_rtp(callback)
3856    cb.append(repr(l))
3857    del l
3858    def callback(path):
3859        return os.path.relpath(path)
3860    cb.append(repr(vim.foreach_rtp(callback)))
3861    del callback
3862    from module import dir as d
3863    from modulex import ddir
3864    cb.append(d + ',' + ddir)
3865    import before
3866    cb.append(before.dir)
3867    import after
3868    cb.append(after.dir)
3869    import topmodule as tm
3870    import topmodule.submodule as tms
3871    import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
3872    cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
3873    cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
3874    cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
3875
3876    del before
3877    del after
3878    del d
3879    del ddir
3880    del tm
3881    del tms
3882    del tmsss
3883  EOF
3884
3885  let expected =<< trim END
3886    ['.']
3887    '.'
3888    3,xx
3889    before
3890    after
3891    pythonx/topmodule/__init__.py
3892    pythonx/topmodule/submodule/__init__.py
3893    pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
3894  END
3895  call assert_equal(expected, getline(2, '$'))
3896  close!
3897
3898  " Try to import a non-existing module with a dot (.)
3899  call AssertException(['py3 import a.b.c'], "No module named 'a'")
3900endfunc
3901
3902" Test exceptions
3903func Test_python3_exception()
3904  func Exe(e)
3905    execute a:e
3906  endfunc
3907
3908  new
3909  py3 cb = vim.current.buffer
3910
3911  py3 << trim EOF
3912    Exe = vim.bindeval('function("Exe")')
3913    ee('vim.command("throw \'abcN\'")')
3914    ee('Exe("throw \'def\'")')
3915    ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
3916    ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
3917    ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
3918    ee('vim.eval("xxx_unknown_function_xxx()")')
3919    ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
3920    del Exe
3921  EOF
3922  delfunction Exe
3923
3924  let expected =<< trim END
3925    vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
3926    Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
3927    vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
3928    vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
3929    vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
3930    vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
3931    vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
3932  END
3933  call assert_equal(expected, getline(2, '$'))
3934  close!
3935endfunc
3936
3937" Regression: interrupting vim.command propagates to next vim.command
3938func Test_python3_keyboard_interrupt()
3939  new
3940  py3 cb = vim.current.buffer
3941  py3 << trim EOF
3942    def test_keyboard_interrupt():
3943        try:
3944            vim.command('while 1 | endwhile')
3945        except KeyboardInterrupt:
3946            cb.append('Caught KeyboardInterrupt')
3947        except Exception:
3948            cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
3949        else:
3950            cb.append('!!!!!!!! No exception')
3951        try:
3952            vim.command('$ put =\'Running :put\'')
3953        except KeyboardInterrupt:
3954            cb.append('!!!!!!!! Caught KeyboardInterrupt')
3955        except Exception:
3956            cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
3957        else:
3958            cb.append('No exception')
3959  EOF
3960
3961  debuggreedy
3962  call inputsave()
3963  call feedkeys("s\ns\ns\ns\nq\n")
3964  redir => output
3965  debug silent! py3 test_keyboard_interrupt()
3966  redir END
3967  0 debuggreedy
3968  call inputrestore()
3969  py3 del test_keyboard_interrupt
3970
3971  let expected =<< trim END
3972    Caught KeyboardInterrupt
3973    Running :put
3974    No exception
3975  END
3976  call assert_equal(expected, getline(2, '$'))
3977  call assert_equal('', output)
3978  close!
3979endfunc
3980
3981" Regression: Iterator for a Vim object should hold a reference.
3982func Test_python3_iter_ref()
3983  let g:list_iter_ref_count_increase = -1
3984  let g:dict_iter_ref_count_increase = -1
3985  let g:bufmap_iter_ref_count_increase = -1
3986  let g:options_iter_ref_count_increase = -1
3987
3988  py3 << trim EOF
3989    import sys
3990    import vim
3991
3992    def test_python3_iter_ref():
3993      create_list = vim.Function('Create_vim_list')
3994      v = create_list()
3995      base_ref_count = sys.getrefcount(v)
3996      for el in v:
3997          vim.vars['list_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
3998
3999      create_dict = vim.Function('Create_vim_dict')
4000      v = create_dict()
4001      base_ref_count = sys.getrefcount(v)
4002      for el in v:
4003          vim.vars['dict_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
4004
4005      v = vim.buffers
4006      base_ref_count = sys.getrefcount(v)
4007      for el in v:
4008          vim.vars['bufmap_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
4009
4010      v = vim.options
4011      base_ref_count = sys.getrefcount(v)
4012      for el in v:
4013          vim.vars['options_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
4014
4015    test_python3_iter_ref()
4016  EOF
4017
4018  call assert_equal(1, g:list_iter_ref_count_increase)
4019  call assert_equal(1, g:dict_iter_ref_count_increase)
4020  call assert_equal(1, g:bufmap_iter_ref_count_increase)
4021  call assert_equal(1, g:options_iter_ref_count_increase)
4022endfunc
4023
4024func Test_python3_non_utf8_string()
4025  smap <Esc>@ <A-@>
4026  py3 vim.command('redir => _tmp_smaps | smap | redir END')
4027  py3 vim.eval('_tmp_smaps').splitlines()
4028  sunmap <Esc>@
4029endfunc
4030
4031func Test_python3_fold_hidden_buffer()
4032  CheckFeature folding
4033
4034  set fdm=expr fde=Fde(v:lnum)
4035  let b:regex = '^'
4036  func Fde(lnum)
4037    let ld = [{}]
4038    let lines = bufnr('%')->getbufline(1, '$')
4039    let was_import = 0
4040    for lnum in range(1, len(lines))
4041      let line = lines[lnum]
4042      call add(ld, {'a': b:regex})
4043      let ld[lnum].foldexpr = was_import ? 1 : '>1'
4044      let was_import = 1
4045    endfor
4046    return ld[a:lnum].foldexpr
4047  endfunc
4048
4049  call setline(1, repeat([''], 15) + repeat(['from'], 3))
4050  eval repeat(['x'], 17)->writefile('Xa.txt')
4051  split Xa.txt
4052  py3 import vim
4053  py3 b = vim.current.buffer
4054  py3 aaa = b[:]
4055  hide
4056  py3 b[:] = aaa
4057
4058  call delete('Xa.txt')
4059  set fdm& fde&
4060  delfunc Fde
4061  bwipe! Xa.txt
4062endfunc
4063
4064" vim: shiftwidth=2 sts=2 expandtab
4065