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