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