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