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