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