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