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