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