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