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