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