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