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