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