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