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