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