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