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