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