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