blob: c04495433dc4a12de6e91c35f1058724270cdfaf [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
zeertzjq449c2e52025-02-03 18:56:16 +0100470 python3 << trimm
471s+='F'
472trimm
473 call assert_equal('ABCDEF', pyxeval('s'))
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200474endfunc
475
Bram Moolenaarab589462020-07-06 21:03:06 +0200476" Test for the buffer range object
477func Test_python3_range2()
478 new
479 call setline(1, ['one', 'two', 'three'])
480 py3 b = vim.current.buffer
481 py3 r = b.range(1, 3)
482 call assert_equal(0, py3eval('r.start'))
483 call assert_equal(2, py3eval('r.end'))
484 call assert_equal('one', py3eval('r[0]'))
485 call assert_equal('one', py3eval('r[-3]'))
486 call AssertException(["let x = py3eval('r[-4]')"],
487 \ 'Vim(let):IndexError: line number out of range')
488 call assert_equal(['two', 'three'], py3eval('r[1:]'))
489 py3 r[0] = 'green'
490 call assert_equal(['green', 'two', 'three'], getline(1, '$'))
491 py3 r[0:2] = ['red', 'blue']
492 call assert_equal(['red', 'blue', 'three'], getline(1, '$'))
493
494 " try different invalid start/end index for the range slice
495 %d
496 call setline(1, ['one', 'two', 'three'])
497 py3 r[-10:1] = ["a"]
498 py3 r[10:12] = ["b"]
499 py3 r[-10:-9] = ["c"]
500 py3 r[1:0] = ["d"]
501 call assert_equal(['c', 'd', 'a', 'two', 'three', 'b'], getline(1, '$'))
502
Bram Moolenaarbb790dc2020-07-07 20:12:54 +0200503 " The following code used to trigger an ml_get error
504 %d
505 let x = py3eval('r[:]')
Bram Moolenaarab589462020-07-06 21:03:06 +0200506
507 " Non-existing range attribute
508 call AssertException(["let x = py3eval('r.abc')"],
509 \ "Vim(let):AttributeError: 'vim.range' object has no attribute 'abc'")
510
511 close!
512endfunc
513
514" Test for the python tabpage object
515func Test_python3_tabpage()
516 tabnew
517 py3 t = vim.tabpages[1]
518 py3 wl = t.windows
519 tabclose
520 " Accessing a closed tabpage
521 call AssertException(["let n = py3eval('t.number')"],
522 \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
523 call AssertException(["let n = py3eval('len(wl)')"],
524 \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
525 call AssertException(["py3 w = wl[0]"],
526 \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
527 call AssertException(["py3 vim.current.tabpage = t"],
528 \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
529 call assert_match('<tabpage object (deleted)', py3eval('repr(t)'))
530 %bw!
531endfunc
532
533" Test for the python window object
534func Test_python3_window()
535 " Test for setting the window height
536 10new
537 py3 vim.current.window.height = 5
538 call assert_equal(5, winheight(0))
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +0200539 py3 vim.current.window.height = 3.2
540 call assert_equal(3, winheight(0))
Bram Moolenaarab589462020-07-06 21:03:06 +0200541
542 " Test for setting the window width
543 10vnew
544 py3 vim.current.window.width = 6
545 call assert_equal(6, winwidth(0))
546
547 " Try accessing a closed window
548 py3 w = vim.current.window
549 py3 wopts = w.options
550 close
551 " Access the attributes of a closed window
552 call AssertException(["let n = py3eval('w.number')"],
553 \ 'Vim(let):vim.error: attempt to refer to deleted window')
554 call AssertException(["py3 w.height = 5"],
555 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
556 call AssertException(["py3 vim.current.window = w"],
557 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
558 " Try to set one of the options of the closed window
Bram Moolenaarbb790dc2020-07-07 20:12:54 +0200559 " The following caused ASAN failure
560 call AssertException(["py3 wopts['list'] = False"],
561 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
Bram Moolenaarab589462020-07-06 21:03:06 +0200562 call assert_match('<window object (deleted)', py3eval("repr(w)"))
563 %bw!
564endfunc
565
Bram Moolenaar6c87bbb2022-12-10 11:17:11 +0000566" This was causing trouble because "curbuf" was not matching curwin->w_buffer
567func Test_python3_window_set_height()
568 enew!
569 call setline(1, ['aaa', 'bbb', 'ccc'])
570 call cursor(2, 1)
571 set foldmethod=expr
572 new
573 wincmd w
574 python3 vim.windows[0].height = 5
575 call assert_equal(5, winheight(1))
576
577 call feedkeys('j', 'xt')
578 call assert_equal(3, getpos('.')[1])
579
580 bwipe!
581 bwipe!
582endfunc
583
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200584" Test for the python List object
585func Test_python3_list()
Bram Moolenaarab589462020-07-06 21:03:06 +0200586 " Try to convert a null List
587 call AssertException(["py3 t = vim.eval('test_null_list()')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100588 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200589
590 " Try to convert a List with a null List item
591 call AssertException(["py3 t = vim.eval('[test_null_list()]')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100592 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200593
Bram Moolenaar64ffa9b2020-11-04 12:23:06 +0100594 " Try to bind a null List variable (works because an empty list is used)
Bram Moolenaarab589462020-07-06 21:03:06 +0200595 let cmds =<< trim END
596 let l = test_null_list()
597 py3 ll = vim.bindeval('l')
598 END
Bram Moolenaar64ffa9b2020-11-04 12:23:06 +0100599 call AssertException(cmds, '')
Bram Moolenaarab589462020-07-06 21:03:06 +0200600
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200601 let l = []
602 py3 l = vim.bindeval('l')
603 py3 f = vim.bindeval('function("strlen")')
604 " Extending List directly with different types
605 py3 l += [1, "as'd", [1, 2, f, {'a': 1}]]
606 call assert_equal([1, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
607 call assert_equal([1, 2, function("strlen"), {'a': 1}], l[-1])
608 call assert_fails('echo l[-4]', 'E684:')
609
610 " List assignment
611 py3 l[0] = 0
612 call assert_equal([0, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
613 py3 l[-2] = f
614 call assert_equal([0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]], l)
Bram Moolenaarab589462020-07-06 21:03:06 +0200615
616 " appending to a list
617 let l = [1, 2]
618 py3 ll = vim.bindeval('l')
619 py3 ll[2] = 8
620 call assert_equal([1, 2, 8], l)
621
Bram Moolenaar21578272021-02-21 19:12:47 +0100622 " iterating over list from Python
623 py3 print([x for x in vim.Function("getline")(1, 2)])
624
Bram Moolenaarab589462020-07-06 21:03:06 +0200625 " Using dict as an index
626 call AssertException(['py3 ll[{}] = 10'],
627 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
628endfunc
629
630" Test for the python Dict object
631func Test_python3_dict()
632 " Try to convert a null Dict
633 call AssertException(["py3 t = vim.eval('test_null_dict()')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100634 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200635
636 " Try to convert a Dict with a null List value
637 call AssertException(["py3 t = vim.eval(\"{'a' : test_null_list()}\")"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100638 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200639
640 " Try to convert a Dict with a null string key
641 py3 t = vim.eval("{test_null_string() : 10}")
642 call assert_fails("let d = py3eval('t')", 'E859:')
643
644 " Dict length
645 let d = {'a' : 10, 'b' : 20}
646 py3 d = vim.bindeval('d')
647 call assert_equal(2, py3eval('len(d)'))
648
Dominique Pelle923dce22021-11-21 11:36:04 +0000649 " Deleting a non-existing key
Bram Moolenaarab589462020-07-06 21:03:06 +0200650 call AssertException(["py3 del d['c']"], "Vim(py3):KeyError: 'c'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200651endfunc
652
653" Extending Dictionary directly with different types
654func Test_python3_dict_extend()
655 let d = {}
656 func d.f()
657 return 1
658 endfunc
659
660 py3 f = vim.bindeval('function("strlen")')
661 py3 << trim EOF
662 d = vim.bindeval('d')
663 d['1'] = 'asd'
664 d.update() # Must not do anything, including throwing errors
665 d.update(b = [1, 2, f])
666 d.update((('-1', {'a': 1}),))
667 d.update({'0': -1})
668 dk = d.keys()
669 dv = d.values()
670 di = d.items()
671 dk.sort(key=repr)
672 dv.sort(key=repr)
673 di.sort(key=repr)
674 EOF
675
Bram Moolenaarab589462020-07-06 21:03:06 +0200676 " Try extending a locked dictionary
677 lockvar d
678 call AssertException(["py3 d.update({'b' : 20})"],
679 \ 'Vim(py3):vim.error: dictionary is locked')
680 unlockvar d
681
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200682 call assert_equal(1, py3eval("d['f'](self={})"))
683 call assert_equal("[b'-1', b'0', b'1', b'b', b'f']", py3eval('repr(dk)'))
684 call assert_equal("[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd']", substitute(py3eval('repr(dv)'),'0x\x\+','','g'))
685 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'))
686 call assert_equal(['0', '1', 'b', 'f', '-1'], keys(d))
687 call assert_equal("[-1, 'asd', [1, 2, function('strlen')], function('1'), {'a': 1}]", string(values(d)))
688 py3 del dk
689 py3 del di
690 py3 del dv
691endfunc
692
693func Test_python3_list_del_items()
694 " removing items with del
695 let l = [0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]]
696 py3 l = vim.bindeval('l')
697 py3 del l[2]
698 call assert_equal("[0, function('strlen')]", string(l))
699
700 let l = range(8)
701 py3 l = vim.bindeval('l')
702 py3 del l[:3]
703 py3 del l[1:]
704 call assert_equal([3], l)
705
706 " removing items out of range: silently skip items that don't exist
707
708 " The following two ranges delete nothing as they match empty list:
709 let l = [0, 1, 2, 3]
710 py3 l = vim.bindeval('l')
711 py3 del l[2:1]
712 call assert_equal([0, 1, 2, 3], l)
713 py3 del l[2:2]
714 call assert_equal([0, 1, 2, 3], l)
715 py3 del l[2:3]
716 call assert_equal([0, 1, 3], l)
717
718 let l = [0, 1, 2, 3]
719 py3 l = vim.bindeval('l')
720 py3 del l[2:4]
721 call assert_equal([0, 1], l)
722
723 let l = [0, 1, 2, 3]
724 py3 l = vim.bindeval('l')
725 py3 del l[2:5]
726 call assert_equal([0, 1], l)
727
728 let l = [0, 1, 2, 3]
729 py3 l = vim.bindeval('l')
730 py3 del l[2:6]
731 call assert_equal([0, 1], l)
732
733 " The following two ranges delete nothing as they match empty list:
734 let l = [0, 1, 2, 3]
735 py3 l = vim.bindeval('l')
736 py3 del l[-1:2]
737 call assert_equal([0, 1, 2, 3], l)
738 py3 del l[-2:2]
739 call assert_equal([0, 1, 2, 3], l)
740 py3 del l[-3:2]
741 call assert_equal([0, 2, 3], l)
742
743 let l = [0, 1, 2, 3]
744 py3 l = vim.bindeval('l')
745 py3 del l[-4:2]
746 call assert_equal([2, 3], l)
747
748 let l = [0, 1, 2, 3]
749 py3 l = vim.bindeval('l')
750 py3 del l[-5:2]
751 call assert_equal([2, 3], l)
752
753 let l = [0, 1, 2, 3]
754 py3 l = vim.bindeval('l')
755 py3 del l[-6:2]
756 call assert_equal([2, 3], l)
757
758 let l = [0, 1, 2, 3]
759 py3 l = vim.bindeval('l')
760 py3 del l[::2]
761 call assert_equal([1, 3], l)
762
763 let l = [0, 1, 2, 3]
764 py3 l = vim.bindeval('l')
765 py3 del l[3:0:-2]
766 call assert_equal([0, 2], l)
767
768 let l = [0, 1, 2, 3]
769 py3 l = vim.bindeval('l')
770 py3 del l[2:4:-2]
771 let l = [0, 1, 2, 3]
772endfunc
773
774func Test_python3_dict_del_items()
775 let d = eval("{'0' : -1, '1' : 'asd', 'b' : [1, 2, function('strlen')], 'f' : function('min'), '-1' : {'a': 1}}")
776 py3 d = vim.bindeval('d')
777 py3 del d['-1']
778 py3 del d['f']
779 call assert_equal([1, 2, function('strlen')], py3eval('d.get(''b'', 1)'))
780 call assert_equal([1, 2, function('strlen')], py3eval('d.pop(''b'')'))
781 call assert_equal(1, py3eval('d.get(''b'', 1)'))
782 call assert_equal('asd', py3eval('d.pop(''1'', 2)'))
783 call assert_equal(2, py3eval('d.pop(''1'', 2)'))
784 call assert_equal('True', py3eval('repr(d.has_key(''0''))'))
785 call assert_equal('False', py3eval('repr(d.has_key(''1''))'))
786 call assert_equal('True', py3eval('repr(''0'' in d)'))
787 call assert_equal('False', py3eval('repr(''1'' in d)'))
788 call assert_equal("[b'0']", py3eval('repr(list(iter(d)))'))
789 call assert_equal({'0' : -1}, d)
790 call assert_equal("(b'0', -1)", py3eval('repr(d.popitem())'))
791 call assert_equal('None', py3eval('repr(d.get(''0''))'))
792 call assert_equal('[]', py3eval('repr(list(iter(d)))'))
793endfunc
794
795" Slice assignment to a list
796func Test_python3_slice_assignment()
797 let l = [0, 1, 2, 3]
798 py3 l = vim.bindeval('l')
799 py3 l[0:0] = ['a']
800 call assert_equal(['a', 0, 1, 2, 3], l)
801
802 let l = [0, 1, 2, 3]
803 py3 l = vim.bindeval('l')
804 py3 l[1:2] = ['b']
805 call assert_equal([0, 'b', 2, 3], l)
806
807 let l = [0, 1, 2, 3]
808 py3 l = vim.bindeval('l')
809 py3 l[2:4] = ['c']
810 call assert_equal([0, 1, 'c'], l)
811
812 let l = [0, 1, 2, 3]
813 py3 l = vim.bindeval('l')
814 py3 l[4:4] = ['d']
815 call assert_equal([0, 1, 2, 3, 'd'], l)
816
817 let l = [0, 1, 2, 3]
818 py3 l = vim.bindeval('l')
819 py3 l[-1:2] = ['e']
820 call assert_equal([0, 1, 2, 'e', 3], l)
821
822 let l = [0, 1, 2, 3]
823 py3 l = vim.bindeval('l')
824 py3 l[-10:2] = ['f']
825 call assert_equal(['f', 2, 3], l)
826
827 let l = [0, 1, 2, 3]
828 py3 l = vim.bindeval('l')
829 py3 l[2:-10] = ['g']
830 call assert_equal([0, 1, 'g', 2, 3], l)
831
832 let l = []
833 py3 l = vim.bindeval('l')
834 py3 l[0:0] = ['h']
835 call assert_equal(['h'], l)
836
837 let l = range(8)
838 py3 l = vim.bindeval('l')
839 py3 l[2:6:2] = [10, 20]
840 call assert_equal([0, 1, 10, 3, 20, 5, 6, 7], l)
841
842 let l = range(8)
843 py3 l = vim.bindeval('l')
844 py3 l[6:2:-2] = [10, 20]
845 call assert_equal([0, 1, 2, 3, 20, 5, 10, 7], l)
846
847 let l = range(8)
848 py3 l = vim.bindeval('l')
849 py3 l[6:2] = ()
850 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
851
852 let l = range(8)
853 py3 l = vim.bindeval('l')
854 py3 l[6:2:1] = ()
855 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
856
857 let l = range(8)
858 py3 l = vim.bindeval('l')
859 py3 l[2:2:1] = ()
860 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
Bram Moolenaar0ab55d62020-07-07 20:50:39 +0200861
862 call AssertException(["py3 x = l[10:11:0]"],
863 \ "Vim(py3):ValueError: slice step cannot be zero")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200864endfunc
865
866" Locked variables
867func Test_python3_lockedvar()
868 new
869 py3 cb = vim.current.buffer
870 let l = [0, 1, 2, 3]
871 py3 l = vim.bindeval('l')
872 lockvar! l
873 py3 << trim EOF
874 try:
875 l[2]='i'
876 except vim.error:
877 cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
878 EOF
879 call assert_equal(['', "l[2] threw vim.error: error:('list is locked',)"],
880 \ getline(1, '$'))
Bram Moolenaarab589462020-07-06 21:03:06 +0200881
882 " Try to concatenate a locked list
883 call AssertException(['py3 l += [4, 5]'], 'Vim(py3):vim.error: list is locked')
884
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200885 call assert_equal([0, 1, 2, 3], l)
886 unlockvar! l
887 close!
888endfunc
889
890" Test for calling a function
891func Test_python3_function_call()
892 func New(...)
893 return ['NewStart'] + a:000 + ['NewEnd']
894 endfunc
895
896 func DictNew(...) dict
897 return ['DictNewStart'] + a:000 + ['DictNewEnd', self]
898 endfunc
899
900 new
901 let l = [function('New'), function('DictNew')]
902 py3 l = vim.bindeval('l')
903 py3 l.extend(list(l[0](1, 2, 3)))
904 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'], l)
905 py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
906 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}], l)
907 py3 l += [[l[0].name]]
908 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, ['New']], l)
909 py3 ee('l[1](1, 2, 3)')
910 call assert_equal("l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',))", getline(2))
911 %d
912 py3 f = l[0]
913 delfunction New
914 py3 ee('f(1, 2, 3)')
915 call assert_equal("f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',))", getline(2))
916 close!
917 delfunction DictNew
918endfunc
919
920func Test_python3_float()
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200921 let l = [0.0]
922 py3 l = vim.bindeval('l')
923 py3 l.extend([0.0])
924 call assert_equal([0.0, 0.0], l)
925endfunc
926
927" Test for Dict key errors
928func Test_python3_dict_key_error()
929 let messages = []
930 py3 << trim EOF
931 import sys
932 d = vim.bindeval('{}')
933 m = vim.bindeval('messages')
934 def em(expr, g=globals(), l=locals()):
935 try:
936 exec(expr, g, l)
937 except Exception as e:
938 if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
939 m.extend([TypeError.__name__])
940 else:
941 m.extend([e.__class__.__name__])
942
943 em('d["abc1"]')
944 em('d["abc1"]="\\0"')
945 em('d["abc1"]=vim')
946 em('d[""]=1')
947 em('d["a\\0b"]=1')
948 em('d[b"a\\0b"]=1')
949 em('d.pop("abc1")')
950 em('d.popitem()')
951 del em
952 del m
953 EOF
954
955 call assert_equal(['KeyError', 'TypeError', 'TypeError', 'ValueError',
956 \ 'TypeError', 'TypeError', 'KeyError', 'KeyError'], messages)
957 unlet messages
958endfunc
959
960" Test for locked and scope attributes
961func Test_python3_lock_scope_attr()
962 let d = {} | let dl = {} | lockvar dl
963 let res = []
964 for s in split("d dl v: g:")
965 let name = tr(s, ':', 's')
966 execute 'py3 ' .. name .. ' = vim.bindeval("' .. s .. '")'
967 call add(res, s .. ' : ' .. join(map(['locked', 'scope'],
968 \ 'v:val .. ":" .. py3eval(name .. "." .. v:val)'), ';'))
969 endfor
970 call assert_equal(['d : locked:0;scope:0', 'dl : locked:1;scope:0',
971 \ 'v: : locked:2;scope:1', 'g: : locked:0;scope:2'], res)
972
973 silent! let d.abc2 = 1
974 silent! let dl.abc3 = 1
975 py3 d.locked = True
976 py3 dl.locked = False
977 silent! let d.def = 1
978 silent! let dl.def = 1
979 call assert_equal({'abc2': 1}, d)
980 call assert_equal({'def': 1}, dl)
981 unlet d dl
982
983 let l = [] | let ll = [] | lockvar ll
984 let res = []
985 for s in split("l ll")
986 let name = tr(s, ':', 's')
987 execute 'py3 ' .. name .. '=vim.bindeval("' .. s .. '")'
988 call add(res, s .. ' : locked:' .. py3eval(name .. '.locked'))
989 endfor
990 call assert_equal(['l : locked:0', 'll : locked:1'], res)
991
992 silent! call extend(l, [0])
993 silent! call extend(ll, [0])
994 py3 l.locked = True
995 py3 ll.locked = False
996 silent! call extend(l, [1])
997 silent! call extend(ll, [1])
998 call assert_equal([0], l)
999 call assert_equal([1], ll)
1000 unlet l ll
Bram Moolenaarab589462020-07-06 21:03:06 +02001001
1002 " Try changing an attribute of a fixed list
1003 py3 a = vim.bindeval('v:argv')
1004 call AssertException(['py3 a.locked = 0'],
1005 \ 'Vim(py3):TypeError: cannot modify fixed list')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001006endfunc
1007
1008" Test for py3eval()
1009func Test_python3_pyeval()
1010 let l = py3eval('[0, 1, 2]')
1011 call assert_equal([0, 1, 2], l)
1012
1013 let d = py3eval('{"a": "b", "c": 1, "d": ["e"]}')
1014 call assert_equal([['a', 'b'], ['c', 1], ['d', ['e']]], sort(items(d)))
1015
1016 let v:errmsg = ''
1017 call assert_equal(v:none, py3eval('None'))
1018 call assert_equal('', v:errmsg)
1019
Bram Moolenaarab589462020-07-06 21:03:06 +02001020 py3 v = vim.eval('test_null_function()')
1021 call assert_equal(v:none, py3eval('v'))
1022
Bram Moolenaar73e28dc2022-09-17 21:08:33 +01001023 call assert_equal(0.0, py3eval('0.0'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001024
Bram Moolenaarab589462020-07-06 21:03:06 +02001025 " Evaluate an invalid values
1026 call AssertException(['let v = py3eval(''"\0"'')'], 'E859:')
1027 call AssertException(['let v = py3eval(''{"\0" : 1}'')'], 'E859:')
1028 call AssertException(['let v = py3eval("undefined_name")'],
1029 \ "Vim(let):NameError: name 'undefined_name' is not defined")
1030 call AssertException(['let v = py3eval("vim")'], 'E859:')
1031endfunc
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001032
Ben Jacksonea19e782024-11-06 21:50:05 +01001033" Test for py3eval with locals
1034func Test_python3_pyeval_locals()
1035 let str = 'a string'
1036 let num = 0xbadb33f
1037 let d = {'a': 1, 'b': 2, 'c': str}
1038 let l = [ str, num, d ]
1039
1040 let locals = #{
1041 \ s: str,
1042 \ n: num,
1043 \ d: d,
1044 \ l: l,
1045 \ }
1046
1047 " check basics
1048 call assert_equal('a string', py3eval('s', locals))
1049 call assert_equal(0xbadb33f, py3eval('n', locals))
1050 call assert_equal(d, py3eval('d', locals))
1051 call assert_equal(l, py3eval('l', locals))
1052 call assert_equal('a,b,c', py3eval('b",".join(l)', {'l': ['a', 'b', 'c']}))
1053 call assert_equal('hello', 's'->py3eval({'s': 'hello'}))
1054 call assert_equal('a,b,c', 'b",".join(l)'->py3eval({'l': ['a', 'b', 'c']}))
1055
1056 py3 << trim EOF
1057 def __UpdateDict(d, upd):
1058 d.update(upd)
1059 return d
1060
1061 def __ExtendList(l, *args):
1062 l.extend(*args)
1063 return l
1064 EOF
1065
1066 " check assign to dict member works like bindeval
1067 call assert_equal(3, py3eval('__UpdateDict( d, {"c": 3} )["c"]', locals))
1068 call assert_equal(3, d['c'])
1069
1070 " check append lo list
1071 call assert_equal(4, py3eval('len(__ExtendList(l, ["new item"]))', locals))
1072 call assert_equal("new item", l[-1])
1073
1074 " check calling a function
1075 let StrLen = function('strlen')
1076 call assert_equal(3, py3eval('f("abc")', {'f': StrLen}))
1077endfunc
1078
Bram Moolenaarab589462020-07-06 21:03:06 +02001079" Test for vim.bindeval()
1080func Test_python3_vim_bindeval()
1081 " Float
1082 let f = 3.14
1083 py3 f = vim.bindeval('f')
1084 call assert_equal(3.14, py3eval('f'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001085
Bram Moolenaarab589462020-07-06 21:03:06 +02001086 " Blob
1087 let b = 0z12
1088 py3 b = vim.bindeval('b')
1089 call assert_equal("\x12", py3eval('b'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001090
Bram Moolenaarab589462020-07-06 21:03:06 +02001091 " Bool
1092 call assert_equal(1, py3eval("vim.bindeval('v:true')"))
1093 call assert_equal(0, py3eval("vim.bindeval('v:false')"))
1094 call assert_equal(v:none, py3eval("vim.bindeval('v:null')"))
1095 call assert_equal(v:none, py3eval("vim.bindeval('v:none')"))
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02001096
1097 " channel/job
Dominique Pelle56c9fd02021-05-19 00:16:14 +02001098 if has('channel')
1099 call assert_equal(v:none, py3eval("vim.bindeval('test_null_channel()')"))
1100 endif
1101 if has('job')
1102 call assert_equal(v:none, py3eval("vim.bindeval('test_null_job()')"))
1103 endif
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001104endfunc
1105
1106" threading
1107" Running py3do command (Test_pydo) before this test, stops the python thread
1108" from running. So this test should be run before the pydo test
Bram Moolenaarab589462020-07-06 21:03:06 +02001109func Test_aaa_python3_threading()
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001110 let l = [0]
1111 py3 l = vim.bindeval('l')
1112 py3 << trim EOF
1113 import threading
1114 import time
1115
1116 class T(threading.Thread):
1117 def __init__(self):
1118 threading.Thread.__init__(self)
1119 self.t = 0
1120 self.running = True
1121
1122 def run(self):
1123 while self.running:
1124 self.t += 1
1125 time.sleep(0.1)
1126
1127 t = T()
1128 del T
1129 t.start()
1130 EOF
1131
1132 sleep 1
1133 py3 t.running = False
1134 py3 t.join()
1135
1136 " Check if the background thread is working. Count should be 10, but on a
1137 " busy system (AppVeyor) it can be much lower.
1138 py3 l[0] = t.t > 4
1139 py3 del time
1140 py3 del threading
1141 py3 del t
1142 call assert_equal([1], l)
1143endfunc
1144
1145" settrace
1146func Test_python3_settrace()
1147 let l = []
1148 py3 l = vim.bindeval('l')
1149 py3 << trim EOF
1150 import sys
1151
1152 def traceit(frame, event, arg):
1153 global l
1154 if event == "line":
1155 l += [frame.f_lineno]
1156 return traceit
1157
1158 def trace_main():
1159 for i in range(5):
1160 pass
1161 EOF
1162 py3 sys.settrace(traceit)
1163 py3 trace_main()
1164 py3 sys.settrace(None)
1165 py3 del traceit
1166 py3 del trace_main
1167 call assert_equal([1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1], l)
1168endfunc
1169
1170" Slice
1171func Test_python3_list_slice()
1172 py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
1173 py3 l = ll[:4]
1174 call assert_equal([0, 1, 2, 3], py3eval('l'))
1175 py3 l = ll[2:]
1176 call assert_equal([2, 3, 4, 5], py3eval('l'))
1177 py3 l = ll[:-4]
1178 call assert_equal([0, 1], py3eval('l'))
1179 py3 l = ll[-2:]
1180 call assert_equal([4, 5], py3eval('l'))
1181 py3 l = ll[2:4]
1182 call assert_equal([2, 3], py3eval('l'))
1183 py3 l = ll[4:2]
1184 call assert_equal([], py3eval('l'))
1185 py3 l = ll[-4:-2]
1186 call assert_equal([2, 3], py3eval('l'))
1187 py3 l = ll[-2:-4]
1188 call assert_equal([], py3eval('l'))
1189 py3 l = ll[:]
1190 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1191 py3 l = ll[0:6]
1192 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1193 py3 l = ll[-10:10]
1194 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1195 py3 l = ll[4:2:-1]
1196 call assert_equal([4, 3], py3eval('l'))
1197 py3 l = ll[::2]
1198 call assert_equal([0, 2, 4], py3eval('l'))
1199 py3 l = ll[4:2:1]
1200 call assert_equal([], py3eval('l'))
Bram Moolenaarab589462020-07-06 21:03:06 +02001201
1202 " Error case: Use an invalid index
1203 call AssertException(['py3 ll[-10] = 5'], 'Vim(py3):vim.error: internal error:')
1204
1205 " Use a step value of 0
1206 call AssertException(['py3 ll[0:3:0] = [1, 2, 3]'],
1207 \ 'Vim(py3):ValueError: slice step cannot be zero')
1208
1209 " Error case: Invalid slice type
1210 call AssertException(["py3 x = ll['abc']"],
1211 \ "Vim(py3):TypeError: index must be int or slice, not str")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001212 py3 del l
Bram Moolenaarab589462020-07-06 21:03:06 +02001213
1214 " Error case: List with a null list item
1215 let l = [test_null_list()]
1216 py3 ll = vim.bindeval('l')
1217 call AssertException(["py3 x = ll[:]"],
Bram Moolenaar07761a32020-12-22 12:50:10 +01001218 \ s:system_error_pat)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001219endfunc
1220
1221" Vars
1222func Test_python3_vars()
1223 let g:foo = 'bac'
1224 let w:abc3 = 'def'
1225 let b:baz = 'bar'
1226 let t:bar = 'jkl'
1227 try
1228 throw "Abc"
1229 catch /Abc/
1230 call assert_equal('Abc', py3eval('vim.vvars[''exception'']'))
1231 endtry
1232 call assert_equal('bac', py3eval('vim.vars[''foo'']'))
1233 call assert_equal('def', py3eval('vim.current.window.vars[''abc3'']'))
1234 call assert_equal('bar', py3eval('vim.current.buffer.vars[''baz'']'))
1235 call assert_equal('jkl', py3eval('vim.current.tabpage.vars[''bar'']'))
1236endfunc
1237
1238" Options
1239" paste: boolean, global
1240" previewheight number, global
1241" operatorfunc: string, global
1242" number: boolean, window-local
1243" numberwidth: number, window-local
1244" colorcolumn: string, window-local
1245" statusline: string, window-local/global
1246" autoindent: boolean, buffer-local
1247" shiftwidth: number, buffer-local
1248" omnifunc: string, buffer-local
1249" preserveindent: boolean, buffer-local/global
1250" path: string, buffer-local/global
1251func Test_python3_opts()
1252 let g:res = []
1253 let g:bufs = [bufnr('%')]
1254 new
1255 let g:bufs += [bufnr('%')]
1256 vnew
1257 let g:bufs += [bufnr('%')]
1258 wincmd j
1259 vnew
1260 let g:bufs += [bufnr('%')]
1261 wincmd l
1262
1263 func RecVars(opt)
1264 let gval = string(eval('&g:' .. a:opt))
1265 let wvals = join(map(range(1, 4),
1266 \ 'v:val .. ":" .. string(getwinvar(v:val, "&" .. a:opt))'))
1267 let bvals = join(map(copy(g:bufs),
1268 \ 'v:val .. ":" .. string(getbufvar(v:val, "&" .. a:opt))'))
1269 call add(g:res, ' G: ' .. gval)
1270 call add(g:res, ' W: ' .. wvals)
1271 call add(g:res, ' B: ' .. wvals)
1272 endfunc
1273
1274 py3 << trim EOF
1275 def e(s, g=globals(), l=locals()):
1276 try:
1277 exec(s, g, l)
1278 except Exception as e:
1279 vim.command('return ' + repr(e.__class__.__name__))
1280
1281 def ev(s, g=globals(), l=locals()):
1282 try:
1283 return eval(s, g, l)
1284 except Exception as e:
1285 vim.command('let exc=' + repr(e.__class__.__name__))
1286 return 0
1287 EOF
1288
1289 func E(s)
1290 python3 e(vim.eval('a:s'))
1291 endfunc
1292
1293 func Ev(s)
1294 let r = py3eval('ev(vim.eval("a:s"))')
1295 if exists('exc')
1296 throw exc
1297 endif
1298 return r
1299 endfunc
1300
1301 py3 gopts1 = vim.options
1302 py3 wopts1 = vim.windows[2].options
1303 py3 wopts2 = vim.windows[0].options
1304 py3 wopts3 = vim.windows[1].options
1305 py3 bopts1 = vim.buffers[vim.bindeval("g:bufs")[2]].options
1306 py3 bopts2 = vim.buffers[vim.bindeval("g:bufs")[1]].options
1307 py3 bopts3 = vim.buffers[vim.bindeval("g:bufs")[0]].options
1308 call add(g:res, 'wopts iters equal: ' ..
1309 \ py3eval('list(wopts1) == list(wopts2)'))
1310 call add(g:res, 'bopts iters equal: ' ..
1311 \ py3eval('list(bopts1) == list(bopts2)'))
1312 py3 gset = set(iter(gopts1))
1313 py3 wset = set(iter(wopts1))
1314 py3 bset = set(iter(bopts1))
1315
1316 set path=.,..,,
1317 let lst = []
1318 let lst += [['paste', 1, 0, 1, 2, 1, 1, 0]]
1319 let lst += [['previewheight', 5, 1, 6, 'a', 0, 1, 0]]
1320 let lst += [['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0]]
1321 let lst += [['number', 0, 1, 1, 0, 1, 0, 1]]
1322 let lst += [['numberwidth', 2, 3, 5, -100, 0, 0, 1]]
1323 let lst += [['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1]]
1324 let lst += [['statusline', '1', '2', '4', 0, 0, 1, 1]]
1325 let lst += [['autoindent', 0, 1, 1, 2, 1, 0, 2]]
1326 let lst += [['shiftwidth', 0, 2, 1, 3, 0, 0, 2]]
1327 let lst += [['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2]]
1328 let lst += [['preserveindent', 0, 1, 1, 2, 1, 1, 2]]
1329 let lst += [['path', '.,,', ',,', '.', 0, 0, 1, 2]]
1330 for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
1331 py3 oname = vim.eval('oname')
1332 py3 oval1 = vim.bindeval('oval1')
1333 py3 oval2 = vim.bindeval('oval2')
1334 py3 oval3 = vim.bindeval('oval3')
1335 if invval is 0 || invval is 1
1336 py3 invval = bool(vim.bindeval('invval'))
1337 else
1338 py3 invval = vim.bindeval('invval')
1339 endif
1340 if bool
1341 py3 oval1 = bool(oval1)
1342 py3 oval2 = bool(oval2)
1343 py3 oval3 = bool(oval3)
1344 endif
1345 call add(g:res, '>>> ' .. oname)
1346 call add(g:res, ' g/w/b:' .. py3eval('oname in gset') .. '/' ..
1347 \ py3eval('oname in wset') .. '/' .. py3eval('oname in bset'))
1348 call add(g:res, ' g/w/b (in):' .. py3eval('oname in gopts1') .. '/' ..
1349 \ py3eval('oname in wopts1') .. '/' .. py3eval('oname in bopts1'))
1350 for v in ['gopts1', 'wopts1', 'bopts1']
1351 try
1352 call add(g:res, ' p/' .. v .. ': ' .. Ev('repr(' .. v .. '[''' .. oname .. '''])'))
1353 catch
1354 call add(g:res, ' p/' .. v .. '! ' .. v:exception)
1355 endtry
1356 let r = E(v .. '[''' .. oname .. ''']=invval')
1357 if r isnot 0
1358 call add(g:res, ' inv: ' .. string(invval) .. '! ' .. r)
1359 endif
1360 for vv in (v is# 'gopts1' ? [v] : [v, v[:-2] .. '2', v[:-2] .. '3'])
1361 let val = substitute(vv, '^.opts', 'oval', '')
1362 let r = E(vv .. '[''' .. oname .. ''']=' .. val)
1363 if r isnot 0
1364 call add(g:res, ' ' .. vv .. '! ' .. r)
1365 endif
1366 endfor
1367 endfor
1368 call RecVars(oname)
1369 for v in ['wopts3', 'bopts3']
1370 let r = E('del ' .. v .. '["' .. oname .. '"]')
1371 if r isnot 0
1372 call add(g:res, ' del ' .. v .. '! ' .. r)
1373 endif
1374 endfor
1375 call RecVars(oname)
1376 endfor
1377 delfunction RecVars
1378 delfunction E
1379 delfunction Ev
1380 py3 del ev
1381 py3 del e
1382 only
1383 for buf in g:bufs[1:]
1384 execute 'bwipeout!' buf
1385 endfor
1386 py3 del gopts1
1387 py3 del wopts1
1388 py3 del wopts2
1389 py3 del wopts3
1390 py3 del bopts1
1391 py3 del bopts2
1392 py3 del bopts3
1393 py3 del oval1
1394 py3 del oval2
1395 py3 del oval3
1396 py3 del oname
1397 py3 del invval
1398
1399 let expected =<< trim END
1400 wopts iters equal: 1
1401 bopts iters equal: 1
1402 >>> paste
1403 g/w/b:1/0/0
1404 g/w/b (in):1/0/0
1405 p/gopts1: False
1406 p/wopts1! KeyError
1407 inv: 2! KeyError
1408 wopts1! KeyError
1409 wopts2! KeyError
1410 wopts3! KeyError
1411 p/bopts1! KeyError
1412 inv: 2! KeyError
1413 bopts1! KeyError
1414 bopts2! KeyError
1415 bopts3! KeyError
1416 G: 1
1417 W: 1:1 2:1 3:1 4:1
1418 B: 1:1 2:1 3:1 4:1
1419 del wopts3! KeyError
1420 del bopts3! KeyError
1421 G: 1
1422 W: 1:1 2:1 3:1 4:1
1423 B: 1:1 2:1 3:1 4:1
1424 >>> previewheight
1425 g/w/b:1/0/0
1426 g/w/b (in):1/0/0
1427 p/gopts1: 12
1428 inv: 'a'! TypeError
1429 p/wopts1! KeyError
1430 inv: 'a'! KeyError
1431 wopts1! KeyError
1432 wopts2! KeyError
1433 wopts3! KeyError
1434 p/bopts1! KeyError
1435 inv: 'a'! KeyError
1436 bopts1! KeyError
1437 bopts2! KeyError
1438 bopts3! KeyError
1439 G: 5
1440 W: 1:5 2:5 3:5 4:5
1441 B: 1:5 2:5 3:5 4:5
1442 del wopts3! KeyError
1443 del bopts3! KeyError
1444 G: 5
1445 W: 1:5 2:5 3:5 4:5
1446 B: 1:5 2:5 3:5 4:5
1447 >>> operatorfunc
1448 g/w/b:1/0/0
1449 g/w/b (in):1/0/0
1450 p/gopts1: b''
1451 inv: 2! TypeError
1452 p/wopts1! KeyError
1453 inv: 2! KeyError
1454 wopts1! KeyError
1455 wopts2! KeyError
1456 wopts3! KeyError
1457 p/bopts1! KeyError
1458 inv: 2! KeyError
1459 bopts1! KeyError
1460 bopts2! KeyError
1461 bopts3! KeyError
1462 G: 'A'
1463 W: 1:'A' 2:'A' 3:'A' 4:'A'
1464 B: 1:'A' 2:'A' 3:'A' 4:'A'
1465 del wopts3! KeyError
1466 del bopts3! KeyError
1467 G: 'A'
1468 W: 1:'A' 2:'A' 3:'A' 4:'A'
1469 B: 1:'A' 2:'A' 3:'A' 4:'A'
1470 >>> number
1471 g/w/b:0/1/0
1472 g/w/b (in):0/1/0
1473 p/gopts1! KeyError
1474 inv: 0! KeyError
1475 gopts1! KeyError
1476 p/wopts1: False
1477 p/bopts1! KeyError
1478 inv: 0! KeyError
1479 bopts1! KeyError
1480 bopts2! KeyError
1481 bopts3! KeyError
1482 G: 0
1483 W: 1:1 2:1 3:0 4:0
1484 B: 1:1 2:1 3:0 4:0
1485 del wopts3! ValueError
1486 del bopts3! KeyError
1487 G: 0
1488 W: 1:1 2:1 3:0 4:0
1489 B: 1:1 2:1 3:0 4:0
1490 >>> numberwidth
1491 g/w/b:0/1/0
1492 g/w/b (in):0/1/0
1493 p/gopts1! KeyError
1494 inv: -100! KeyError
1495 gopts1! KeyError
1496 p/wopts1: 4
1497 inv: -100! error
1498 p/bopts1! KeyError
1499 inv: -100! KeyError
1500 bopts1! KeyError
1501 bopts2! KeyError
1502 bopts3! KeyError
1503 G: 4
1504 W: 1:3 2:5 3:2 4:4
1505 B: 1:3 2:5 3:2 4:4
1506 del wopts3! ValueError
1507 del bopts3! KeyError
1508 G: 4
1509 W: 1:3 2:5 3:2 4:4
1510 B: 1:3 2:5 3:2 4:4
1511 >>> colorcolumn
1512 g/w/b:0/1/0
1513 g/w/b (in):0/1/0
1514 p/gopts1! KeyError
1515 inv: 'abc4'! KeyError
1516 gopts1! KeyError
1517 p/wopts1: b''
1518 inv: 'abc4'! error
1519 p/bopts1! KeyError
1520 inv: 'abc4'! KeyError
1521 bopts1! KeyError
1522 bopts2! KeyError
1523 bopts3! KeyError
1524 G: ''
1525 W: 1:'+2' 2:'+3' 3:'+1' 4:''
1526 B: 1:'+2' 2:'+3' 3:'+1' 4:''
1527 del wopts3! ValueError
1528 del bopts3! KeyError
1529 G: ''
1530 W: 1:'+2' 2:'+3' 3:'+1' 4:''
1531 B: 1:'+2' 2:'+3' 3:'+1' 4:''
1532 >>> statusline
1533 g/w/b:1/1/0
1534 g/w/b (in):1/1/0
1535 p/gopts1: b''
1536 inv: 0! TypeError
1537 p/wopts1: None
1538 inv: 0! TypeError
1539 p/bopts1! KeyError
1540 inv: 0! KeyError
1541 bopts1! KeyError
1542 bopts2! KeyError
1543 bopts3! KeyError
1544 G: '1'
1545 W: 1:'2' 2:'4' 3:'1' 4:'1'
1546 B: 1:'2' 2:'4' 3:'1' 4:'1'
1547 del bopts3! KeyError
1548 G: '1'
1549 W: 1:'2' 2:'1' 3:'1' 4:'1'
1550 B: 1:'2' 2:'1' 3:'1' 4:'1'
1551 >>> autoindent
1552 g/w/b:0/0/1
1553 g/w/b (in):0/0/1
1554 p/gopts1! KeyError
1555 inv: 2! KeyError
1556 gopts1! KeyError
1557 p/wopts1! KeyError
1558 inv: 2! KeyError
1559 wopts1! KeyError
1560 wopts2! KeyError
1561 wopts3! KeyError
1562 p/bopts1: False
1563 G: 0
1564 W: 1:0 2:1 3:0 4:1
1565 B: 1:0 2:1 3:0 4:1
1566 del wopts3! KeyError
1567 del bopts3! ValueError
1568 G: 0
1569 W: 1:0 2:1 3:0 4:1
1570 B: 1:0 2:1 3:0 4:1
1571 >>> shiftwidth
1572 g/w/b:0/0/1
1573 g/w/b (in):0/0/1
1574 p/gopts1! KeyError
1575 inv: 3! KeyError
1576 gopts1! KeyError
1577 p/wopts1! KeyError
1578 inv: 3! KeyError
1579 wopts1! KeyError
1580 wopts2! KeyError
1581 wopts3! KeyError
1582 p/bopts1: 8
1583 G: 8
1584 W: 1:0 2:2 3:8 4:1
1585 B: 1:0 2:2 3:8 4:1
1586 del wopts3! KeyError
1587 del bopts3! ValueError
1588 G: 8
1589 W: 1:0 2:2 3:8 4:1
1590 B: 1:0 2:2 3:8 4:1
1591 >>> omnifunc
1592 g/w/b:0/0/1
1593 g/w/b (in):0/0/1
1594 p/gopts1! KeyError
1595 inv: 1! KeyError
1596 gopts1! KeyError
1597 p/wopts1! KeyError
1598 inv: 1! KeyError
1599 wopts1! KeyError
1600 wopts2! KeyError
1601 wopts3! KeyError
1602 p/bopts1: b''
1603 inv: 1! TypeError
1604 G: ''
1605 W: 1:'A' 2:'B' 3:'' 4:'C'
1606 B: 1:'A' 2:'B' 3:'' 4:'C'
1607 del wopts3! KeyError
1608 del bopts3! ValueError
1609 G: ''
1610 W: 1:'A' 2:'B' 3:'' 4:'C'
1611 B: 1:'A' 2:'B' 3:'' 4:'C'
1612 >>> preserveindent
1613 g/w/b:0/0/1
1614 g/w/b (in):0/0/1
1615 p/gopts1! KeyError
1616 inv: 2! KeyError
1617 gopts1! KeyError
1618 p/wopts1! KeyError
1619 inv: 2! KeyError
1620 wopts1! KeyError
1621 wopts2! KeyError
1622 wopts3! KeyError
1623 p/bopts1: False
1624 G: 0
1625 W: 1:0 2:1 3:0 4:1
1626 B: 1:0 2:1 3:0 4:1
1627 del wopts3! KeyError
1628 del bopts3! ValueError
1629 G: 0
1630 W: 1:0 2:1 3:0 4:1
1631 B: 1:0 2:1 3:0 4:1
1632 >>> path
1633 g/w/b:1/0/1
1634 g/w/b (in):1/0/1
1635 p/gopts1: b'.,..,,'
1636 inv: 0! TypeError
1637 p/wopts1! KeyError
1638 inv: 0! KeyError
1639 wopts1! KeyError
1640 wopts2! KeyError
1641 wopts3! KeyError
1642 p/bopts1: None
1643 inv: 0! TypeError
1644 G: '.,,'
1645 W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1646 B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1647 del wopts3! KeyError
1648 G: '.,,'
1649 W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1650 B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1651 END
1652
1653 call assert_equal(expected, g:res)
1654 unlet g:res
Bram Moolenaarab589462020-07-06 21:03:06 +02001655
1656 call assert_equal(0, py3eval("'' in vim.options"))
1657
1658 " use an empty key to index vim.options
1659 call AssertException(["let v = py3eval(\"vim.options['']\")"],
1660 \ 'Vim(let):ValueError: empty keys are not allowed')
1661 call AssertException(["py3 vim.current.window.options[''] = 0"],
1662 \ 'Vim(py3):ValueError: empty keys are not allowed')
1663 call AssertException(["py3 vim.current.window.options[{}] = 0"],
1664 \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got dict')
1665
1666 " set one of the number options to a very large number
1667 let cmd = ["py3 vim.options['previewheight'] = 9999999999999999"]
1668 call AssertException(cmd, "Vim(py3):OverflowError:")
1669
1670 " unset a global-local string option
1671 call AssertException(["py3 del vim.options['errorformat']"],
1672 \ 'Vim(py3):ValueError: unable to unset global option errorformat')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001673endfunc
1674
1675" Test for vim.buffer object
1676func Test_python3_buffer()
1677 new
1678 call setline(1, "Hello\nWorld")
1679 call assert_fails("let x = py3eval('vim.current.buffer[0]')", 'E859:')
1680 %bw!
1681
1682 edit Xfile1
1683 let bnr1 = bufnr()
1684 py3 cb = vim.current.buffer
1685 vnew Xfile2
1686 let bnr2 = bufnr()
1687 call setline(1, ['First line', 'Second line', 'Third line'])
1688 py3 b = vim.current.buffer
1689 wincmd w
1690
Bram Moolenaarab589462020-07-06 21:03:06 +02001691 " Test for getting lines from the buffer using a slice
1692 call assert_equal(['First line'], py3eval('b[-10:1]'))
1693 call assert_equal(['Third line'], py3eval('b[2:10]'))
1694 call assert_equal([], py3eval('b[2:0]'))
1695 call assert_equal([], py3eval('b[10:12]'))
1696 call assert_equal([], py3eval('b[-10:-8]'))
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02001697 call AssertException(["py3 x = b[0:3:0]"],
1698 \ 'Vim(py3):ValueError: slice step cannot be zero')
1699 call AssertException(["py3 b[0:3:0] = 'abc'"],
1700 \ 'Vim(py3):ValueError: slice step cannot be zero')
1701 call AssertException(["py3 x = b[{}]"],
1702 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1703 call AssertException(["py3 b[{}] = 'abc'"],
1704 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1705
1706 " Test for getting lines using a range
1707 call AssertException(["py3 x = b.range(0,3)[0:2:0]"],
1708 \ "Vim(py3):ValueError: slice step cannot be zero")
1709 call AssertException(["py3 b.range(0,3)[0:2:0] = 'abc'"],
1710 \ "Vim(py3):ValueError: slice step cannot be zero")
Bram Moolenaarab589462020-07-06 21:03:06 +02001711
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001712 " Tests BufferAppend and BufferItem
1713 py3 cb.append(b[0])
1714 call assert_equal(['First line'], getbufline(bnr1, 2))
1715 %d
1716
Bram Moolenaarab589462020-07-06 21:03:06 +02001717 " Try to append using out-of-range line number
1718 call AssertException(["py3 b.append('abc', 10)"],
1719 \ 'Vim(py3):IndexError: line number out of range')
1720
1721 " Append a non-string item
1722 call AssertException(["py3 b.append([22])"],
1723 \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got int')
1724
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001725 " Tests BufferSlice and BufferAssSlice
1726 py3 cb.append('abc5') # Will be overwritten
1727 py3 cb[-1:] = b[:-2]
1728 call assert_equal(['First line'], getbufline(bnr1, 2))
1729 %d
1730
1731 " Test BufferLength and BufferAssSlice
1732 py3 cb.append('def') # Will not be overwritten
1733 py3 cb[len(cb):] = b[:]
1734 call assert_equal(['def', 'First line', 'Second line', 'Third line'],
1735 \ getbufline(bnr1, 2, '$'))
1736 %d
1737
1738 " Test BufferAssItem and BufferMark
1739 call setbufline(bnr1, 1, ['one', 'two', 'three'])
1740 call cursor(1, 3)
1741 normal ma
1742 py3 cb.append('ghi') # Will be overwritten
1743 py3 cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
1744 call assert_equal(['(3, 2)'], getbufline(bnr1, 4))
1745 %d
1746
1747 " Test BufferRepr
1748 py3 cb.append(repr(cb) + repr(b))
1749 call assert_equal(['<buffer Xfile1><buffer Xfile2>'], getbufline(bnr1, 2))
1750 %d
1751
1752 " Modify foreign buffer
1753 py3 << trim EOF
1754 b.append('foo')
1755 b[0]='bar'
1756 b[0:0]=['baz']
1757 vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
1758 EOF
1759 call assert_equal(['baz', 'bar', 'Second line', 'Third line', 'foo'],
1760 \ getbufline(bnr2, 1, '$'))
1761 %d
1762
1763 " Test assigning to name property
1764 augroup BUFS
1765 autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
1766 autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
1767 augroup END
1768 py3 << trim EOF
1769 import os
1770 old_name = cb.name
1771 cb.name = 'foo'
1772 cb.append(cb.name[-11:].replace(os.path.sep, '/'))
1773 b.name = 'bar'
1774 cb.append(b.name[-11:].replace(os.path.sep, '/'))
1775 cb.name = old_name
1776 cb.append(cb.name[-14:].replace(os.path.sep, '/'))
1777 del old_name
1778 EOF
1779 call assert_equal([bnr1 .. ':BufFilePre:' .. bnr1,
1780 \ bnr1 .. ':BufFilePost:' .. bnr1,
1781 \ 'testdir/foo',
1782 \ bnr2 .. ':BufFilePre:' .. bnr2,
1783 \ bnr2 .. ':BufFilePost:' .. bnr2,
1784 \ 'testdir/bar',
1785 \ bnr1 .. ':BufFilePre:' .. bnr1,
1786 \ bnr1 .. ':BufFilePost:' .. bnr1,
1787 \ 'testdir/Xfile1'], getbufline(bnr1, 2, '$'))
1788 %d
1789
1790 " Test CheckBuffer
1791 py3 << trim EOF
1792 for _b in vim.buffers:
1793 if _b is not cb:
1794 vim.command('bwipeout! ' + str(_b.number))
1795 del _b
1796 cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
1797 EOF
1798 call assert_equal('valid: b:False, cb:True', getline(2))
1799 %d
1800
1801 py3 << trim EOF
1802 for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
1803 try:
1804 exec(expr)
1805 except vim.error:
1806 pass
1807 else:
1808 # Usually a SEGV here
1809 # Should not happen in any case
1810 cb.append('No exception for ' + expr)
1811 vim.command('cd .')
1812 del b
1813 EOF
1814 call assert_equal([''], getline(1, '$'))
1815
Bram Moolenaarab589462020-07-06 21:03:06 +02001816 " Delete all the lines in a buffer
1817 call setline(1, ['a', 'b', 'c'])
1818 py3 vim.current.buffer[:] = []
1819 call assert_equal([''], getline(1, '$'))
1820
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02001821 " Test for buffer marks
1822 call assert_equal(v:none, py3eval("vim.current.buffer.mark('r')"))
1823
Bram Moolenaarab589462020-07-06 21:03:06 +02001824 " Test for modifying a 'nomodifiable' buffer
1825 setlocal nomodifiable
1826 call AssertException(["py3 vim.current.buffer[0] = 'abc'"],
1827 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1828 call AssertException(["py3 vim.current.buffer[0] = None"],
1829 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1830 call AssertException(["py3 vim.current.buffer[:] = None"],
1831 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1832 call AssertException(["py3 vim.current.buffer[:] = []"],
1833 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1834 call AssertException(["py3 vim.current.buffer.append('abc')"],
1835 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1836 call AssertException(["py3 vim.current.buffer.append([])"],
1837 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
1838 setlocal modifiable
1839
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001840 augroup BUFS
1841 autocmd!
1842 augroup END
1843 augroup! BUFS
1844 %bw!
Bram Moolenaarab589462020-07-06 21:03:06 +02001845
1846 " Range object for a deleted buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001847 new Xp3buffile
Bram Moolenaarab589462020-07-06 21:03:06 +02001848 call setline(1, ['one', 'two', 'three'])
1849 py3 b = vim.current.buffer
1850 py3 r = vim.current.buffer.range(0, 2)
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001851 call assert_equal('<range Xp3buffile (0:2)>', py3eval('repr(r)'))
Bram Moolenaarab589462020-07-06 21:03:06 +02001852 %bw!
1853 call AssertException(['py3 r[:] = []'],
1854 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1855 call assert_match('<buffer object (deleted)', py3eval('repr(b)'))
1856 call assert_match('<range object (for deleted buffer)', py3eval('repr(r)'))
1857 call AssertException(["let n = py3eval('len(r)')"],
1858 \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
1859 call AssertException(["py3 r.append('abc')"],
1860 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1861
1862 " object for a deleted buffer
1863 call AssertException(["py3 b[0] = 'one'"],
1864 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1865 call AssertException(["py3 b.append('one')"],
1866 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1867 call AssertException(["let n = py3eval('len(b)')"],
1868 \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
1869 call AssertException(["py3 pos = b.mark('a')"],
1870 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1871 call AssertException(["py3 vim.current.buffer = b"],
1872 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
1873 call AssertException(["py3 rn = b.range(0, 2)"],
1874 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001875endfunc
1876
1877" Test vim.buffers object
1878func Test_python3_buffers()
1879 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001880 edit Xp3buffile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001881 py3 cb = vim.current.buffer
1882 set hidden
1883 edit a
1884 buffer #
1885 edit b
1886 buffer #
1887 edit c
1888 buffer #
1889 py3 << trim EOF
1890 # Check GCing iterator that was not fully exhausted
1891 i = iter(vim.buffers)
1892 cb.append('i:' + str(next(i)))
1893 # and also check creating more than one iterator at a time
1894 i2 = iter(vim.buffers)
1895 cb.append('i2:' + str(next(i2)))
1896 cb.append('i:' + str(next(i)))
1897 # The following should trigger GC and not cause any problems
1898 del i
1899 del i2
1900 i3 = iter(vim.buffers)
1901 cb.append('i3:' + str(next(i3)))
1902 del i3
1903 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001904 call assert_equal(['i:<buffer Xp3buffile>',
1905 \ 'i2:<buffer Xp3buffile>', 'i:<buffer a>', 'i3:<buffer Xp3buffile>'],
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001906 \ getline(2, '$'))
1907 %d
1908
1909 py3 << trim EOF
1910 prevnum = 0
1911 for b in vim.buffers:
1912 # Check buffer order
1913 if prevnum >= b.number:
1914 cb.append('!!! Buffer numbers not in strictly ascending order')
1915 # Check indexing: vim.buffers[number].number == number
1916 cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + \
1917 '=' + repr(b))
1918 prevnum = b.number
1919 del prevnum
1920
1921 cb.append(str(len(vim.buffers)))
1922 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001923 call assert_equal([bufnr('Xp3buffile') .. ':<buffer Xp3buffile>=<buffer Xp3buffile>',
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001924 \ bufnr('a') .. ':<buffer a>=<buffer a>',
1925 \ bufnr('b') .. ':<buffer b>=<buffer b>',
1926 \ bufnr('c') .. ':<buffer c>=<buffer c>', '4'], getline(2, '$'))
1927 %d
1928
1929 py3 << trim EOF
1930 bnums = list(map(lambda b: b.number, vim.buffers))[1:]
1931
1932 # Test wiping out buffer with existing iterator
1933 i4 = iter(vim.buffers)
1934 cb.append('i4:' + str(next(i4)))
1935 vim.command('bwipeout! ' + str(bnums.pop(0)))
1936 try:
1937 next(i4)
1938 except vim.error:
1939 pass
1940 else:
1941 cb.append('!!!! No vim.error')
1942 i4 = iter(vim.buffers)
1943 vim.command('bwipeout! ' + str(bnums.pop(-1)))
1944 vim.command('bwipeout! ' + str(bnums.pop(-1)))
1945 cb.append('i4:' + str(next(i4)))
1946 try:
1947 next(i4)
1948 except StopIteration:
1949 cb.append('StopIteration')
1950 del i4
1951 del bnums
1952 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001953 call assert_equal(['i4:<buffer Xp3buffile>',
1954 \ 'i4:<buffer Xp3buffile>', 'StopIteration'], getline(2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001955 %bw!
1956endfunc
1957
1958" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
1959func Test_python3_tabpage_window()
1960 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001961 edit Xp3buffile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001962 py3 cb = vim.current.buffer
1963 tabnew 0
1964 tabnew 1
1965 vnew a.1
1966 tabnew 2
1967 vnew a.2
1968 vnew b.2
1969 vnew c.2
1970
1971 py3 << trim EOF
1972 cb.append('Number of tabs: ' + str(len(vim.tabpages)))
1973 cb.append('Current tab pages:')
1974 def W(w):
1975 if '(unknown)' in repr(w):
1976 return '<window object (unknown)>'
1977 else:
1978 return repr(w)
1979
1980 def Cursor(w, start=len(cb)):
1981 if w.buffer is cb:
1982 return repr((start - w.cursor[0], w.cursor[1]))
1983 else:
1984 return repr(w.cursor)
1985
1986 for t in vim.tabpages:
1987 cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + \
1988 str(len(t.windows)) + ' windows, current is ' + W(t.window))
1989 cb.append(' Windows:')
1990 for w in t.windows:
1991 cb.append(' ' + W(w) + '(' + str(w.number) + ')' + \
1992 ': displays buffer ' + repr(w.buffer) + \
1993 '; cursor is at ' + Cursor(w))
1994 # Other values depend on the size of the terminal, so they are checked
1995 # partly:
1996 for attr in ('height', 'row', 'width', 'col'):
1997 try:
1998 aval = getattr(w, attr)
1999 if type(aval) is not int:
2000 raise TypeError
2001 if aval < 0:
2002 raise ValueError
2003 except Exception as e:
2004 cb.append('!!!!!! Error while getting attribute ' + attr + \
2005 ': ' + e.__class__.__name__)
2006 del aval
2007 del attr
2008 w.cursor = (len(w.buffer), 0)
2009 del W
2010 del Cursor
2011 cb.append('Number of windows in current tab page: ' + \
2012 str(len(vim.windows)))
2013 if list(vim.windows) != list(vim.current.tabpage.windows):
2014 cb.append('!!!!!! Windows differ')
2015 EOF
2016
2017 let expected =<< trim END
2018 Number of tabs: 4
2019 Current tab pages:
2020 <tabpage 0>(1): 1 windows, current is <window object (unknown)>
2021 Windows:
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002022 <window object (unknown)>(1): displays buffer <buffer Xp3buffile>; cursor is at (2, 0)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002023 <tabpage 1>(2): 1 windows, current is <window object (unknown)>
2024 Windows:
2025 <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
2026 <tabpage 2>(3): 2 windows, current is <window object (unknown)>
2027 Windows:
2028 <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
2029 <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
2030 <tabpage 3>(4): 4 windows, current is <window 0>
2031 Windows:
2032 <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
2033 <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
2034 <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
2035 <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
2036 Number of windows in current tab page: 4
2037 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002038 call assert_equal(expected, getbufline(bufnr('Xp3buffile'), 2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002039 %bw!
2040endfunc
2041
2042" Test vim.current
2043func Test_python3_vim_current()
2044 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002045 edit Xpy3cfile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002046 py3 cb = vim.current.buffer
2047 tabnew 0
2048 tabnew 1
2049 vnew a.1
2050 tabnew 2
2051 vnew a.2
2052 vnew b.2
2053 vnew c.2
2054
2055 py3 << trim EOF
2056 def H(o):
2057 return repr(o)
2058 cb.append('Current tab page: ' + repr(vim.current.tabpage))
2059 cb.append('Current window: ' + repr(vim.current.window) + ': ' + \
2060 H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
2061 cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + \
2062 H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ \
2063 ' is ' + H(vim.current.tabpage.window.buffer))
2064 del H
2065 EOF
2066 let expected =<< trim END
2067 Current tab page: <tabpage 3>
2068 Current window: <window 0>: <window 0> is <window 0>
2069 Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
2070 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002071 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
2072 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002073
2074 " Assigning: fails
2075 py3 << trim EOF
2076 try:
2077 vim.current.window = vim.tabpages[0].window
2078 except ValueError:
2079 cb.append('ValueError at assigning foreign tab window')
2080
2081 for attr in ('window', 'tabpage', 'buffer'):
2082 try:
2083 setattr(vim.current, attr, None)
2084 except TypeError:
2085 cb.append('Type error at assigning None to vim.current.' + attr)
2086 del attr
2087 EOF
2088
2089 let expected =<< trim END
2090 ValueError at assigning foreign tab window
2091 Type error at assigning None to vim.current.window
2092 Type error at assigning None to vim.current.tabpage
2093 Type error at assigning None to vim.current.buffer
2094 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002095 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
2096 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002097
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002098 call setbufline(bufnr('Xpy3cfile'), 1, 'python interface')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002099 py3 << trim EOF
2100 # Assigning: success
2101 vim.current.tabpage = vim.tabpages[-2]
2102 vim.current.buffer = cb
2103 vim.current.window = vim.windows[0]
2104 vim.current.window.cursor = (len(vim.current.buffer), 0)
2105 cb.append('Current tab page: ' + repr(vim.current.tabpage))
2106 cb.append('Current window: ' + repr(vim.current.window))
2107 cb.append('Current buffer: ' + repr(vim.current.buffer))
2108 cb.append('Current line: ' + repr(vim.current.line))
2109 EOF
2110
2111 let expected =<< trim END
2112 Current tab page: <tabpage 2>
2113 Current window: <window 0>
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002114 Current buffer: <buffer Xpy3cfile>
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002115 Current line: 'python interface'
2116 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002117 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
Bram Moolenaarab589462020-07-06 21:03:06 +02002118 py3 vim.current.line = 'one line'
2119 call assert_equal('one line', getline('.'))
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002120 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002121
2122 py3 << trim EOF
2123 ws = list(vim.windows)
2124 ts = list(vim.tabpages)
2125 for b in vim.buffers:
2126 if b is not cb:
2127 vim.command('bwipeout! ' + str(b.number))
2128 del b
2129 cb.append('w.valid: ' + repr([w.valid for w in ws]))
2130 cb.append('t.valid: ' + repr([t.valid for t in ts]))
2131 del w
2132 del t
2133 del ts
2134 del ws
2135 EOF
2136 let expected =<< trim END
2137 w.valid: [True, False]
2138 t.valid: [True, False, True, False]
2139 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002140 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002141 %bw!
2142endfunc
2143
2144" Test types
2145func Test_python3_types()
2146 %d
2147 py3 cb = vim.current.buffer
2148 py3 << trim EOF
2149 for expr, attr in (
2150 ('vim.vars', 'Dictionary'),
2151 ('vim.options', 'Options'),
2152 ('vim.bindeval("{}")', 'Dictionary'),
2153 ('vim.bindeval("[]")', 'List'),
2154 ('vim.bindeval("function(\'tr\')")', 'Function'),
2155 ('vim.current.buffer', 'Buffer'),
2156 ('vim.current.range', 'Range'),
2157 ('vim.current.window', 'Window'),
2158 ('vim.current.tabpage', 'TabPage'),
2159 ):
2160 cb.append(expr + ':' + attr + ':' + \
2161 repr(type(eval(expr)) is getattr(vim, attr)))
2162 del expr
2163 del attr
2164 EOF
2165 let expected =<< trim END
2166 vim.vars:Dictionary:True
2167 vim.options:Options:True
2168 vim.bindeval("{}"):Dictionary:True
2169 vim.bindeval("[]"):List:True
2170 vim.bindeval("function('tr')"):Function:True
2171 vim.current.buffer:Buffer:True
2172 vim.current.range:Range:True
2173 vim.current.window:Window:True
2174 vim.current.tabpage:TabPage:True
2175 END
2176 call assert_equal(expected, getline(2, '$'))
2177endfunc
2178
2179" Test __dir__() method
2180func Test_python3_dir_method()
2181 %d
2182 py3 cb = vim.current.buffer
2183 py3 << trim EOF
2184 for name, o in (
2185 ('current', vim.current),
2186 ('buffer', vim.current.buffer),
2187 ('window', vim.current.window),
2188 ('tabpage', vim.current.tabpage),
2189 ('range', vim.current.range),
2190 ('dictionary', vim.bindeval('{}')),
2191 ('list', vim.bindeval('[]')),
2192 ('function', vim.bindeval('function("tr")')),
2193 ('output', sys.stdout),
2194 ):
2195 cb.append(name + ':' + ','.join(dir(o)))
2196 del name
2197 del o
2198 EOF
2199 let expected =<< trim END
2200 current:__dir__,buffer,line,range,tabpage,window
2201 buffer:__dir__,append,mark,name,number,options,range,valid,vars
2202 window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
2203 tabpage:__dir__,number,valid,vars,window,windows
2204 range:__dir__,append,end,start
2205 dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
2206 list:__dir__,extend,locked
2207 function:__dir__,args,auto_rebind,self,softspace
2208 output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
2209 END
2210 call assert_equal(expected, getline(2, '$'))
2211endfunc
2212
2213" Test vim.*.__new__
2214func Test_python3_new()
2215 call assert_equal({}, py3eval('vim.Dictionary({})'))
2216 call assert_equal({'a': 1}, py3eval('vim.Dictionary(a=1)'))
2217 call assert_equal({'a': 1}, py3eval('vim.Dictionary(((''a'', 1),))'))
2218 call assert_equal([], py3eval('vim.List()'))
2219 call assert_equal(['a', 'b', 'c', '7'], py3eval('vim.List(iter(''abc7''))'))
2220 call assert_equal(function('tr'), py3eval('vim.Function(''tr'')'))
2221 call assert_equal(function('tr', [123, 3, 4]),
2222 \ py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
2223 call assert_equal(function('tr'), py3eval('vim.Function(''tr'', args=[])'))
2224 call assert_equal(function('tr', {}),
2225 \ py3eval('vim.Function(''tr'', self={})'))
2226 call assert_equal(function('tr', [123, 3, 4], {}),
2227 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
2228 call assert_equal(function('tr'),
2229 \ py3eval('vim.Function(''tr'', auto_rebind=False)'))
2230 call assert_equal(function('tr', [123, 3, 4]),
2231 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
2232 call assert_equal(function('tr'),
2233 \ py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
2234 call assert_equal(function('tr', {}),
2235 \ py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
2236 call assert_equal(function('tr', [123, 3, 4], {}),
2237 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
2238endfunc
2239
2240" Test vim.Function
2241func Test_python3_vim_func()
Bram Moolenaarab589462020-07-06 21:03:06 +02002242 func Args(...)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002243 return a:000
2244 endfunc
2245
Bram Moolenaarab589462020-07-06 21:03:06 +02002246 func SelfArgs(...) dict
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002247 return [a:000, self]
2248 endfunc
2249
2250 " The following four lines should not crash
2251 let Pt = function('tr', [[]], {'l': []})
2252 py3 Pt = vim.bindeval('Pt')
2253 unlet Pt
2254 py3 del Pt
2255
Bram Moolenaarab589462020-07-06 21:03:06 +02002256 call assert_equal(3, py3eval('vim.strwidth("a\tb")'))
2257
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002258 %bw!
2259 py3 cb = vim.current.buffer
2260 py3 << trim EOF
2261 def ecall(out_prefix, func, *args, **kwargs):
2262 line = out_prefix + ': '
2263 try:
2264 ret = func(*args, **kwargs)
2265 except Exception:
2266 line += '!exception: ' + emsg(sys.exc_info())
2267 else:
2268 line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
2269 cb.append(line)
2270 a = vim.Function('Args')
2271 pa1 = vim.Function('Args', args=['abcArgsPA1'])
2272 pa2 = vim.Function('Args', args=[])
2273 pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
2274 pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
2275 cb.append('a: ' + repr(a))
2276 cb.append('pa1: ' + repr(pa1))
2277 cb.append('pa2: ' + repr(pa2))
2278 cb.append('pa3: ' + repr(pa3))
2279 cb.append('pa4: ' + repr(pa4))
2280 sa = vim.Function('SelfArgs')
2281 psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
2282 psa2 = vim.Function('SelfArgs', args=[])
2283 psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
2284 psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
2285 psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
2286 psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
2287 psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
2288 psa8 = vim.Function('SelfArgs', auto_rebind=False)
2289 psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
2290 psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
2291 psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
2292 psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
2293 cb.append('sa: ' + repr(sa))
2294 cb.append('psa1: ' + repr(psa1))
2295 cb.append('psa2: ' + repr(psa2))
2296 cb.append('psa3: ' + repr(psa3))
2297 cb.append('psa4: ' + repr(psa4))
2298 cb.append('psa5: ' + repr(psa5))
2299 cb.append('psa6: ' + repr(psa6))
2300 cb.append('psa7: ' + repr(psa7))
2301 cb.append('psa8: ' + repr(psa8))
2302 cb.append('psa9: ' + repr(psa9))
2303 cb.append('psaA: ' + repr(psaA))
2304 cb.append('psaB: ' + repr(psaB))
2305 cb.append('psaC: ' + repr(psaC))
2306
2307 psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
2308 psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
2309 psar.self['rec'] = psar
2310 psar.self['self'] = psar.self
2311 psar.self['args'] = psar.args
2312
2313 try:
2314 cb.append('psar: ' + repr(psar))
2315 except Exception:
2316 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
2317 EOF
2318
2319 let expected =<< trim END
2320 a: <vim.Function 'Args'>
2321 pa1: <vim.Function 'Args', args=['abcArgsPA1']>
2322 pa2: <vim.Function 'Args'>
2323 pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
2324 pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
2325 sa: <vim.Function 'SelfArgs'>
2326 psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
2327 psa2: <vim.Function 'SelfArgs'>
2328 psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
2329 psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
2330 psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
2331 psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
2332 psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
2333 psa8: <vim.Function 'SelfArgs'>
2334 psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
2335 psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
2336 psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
2337 psaC: <vim.Function 'SelfArgs'>
2338 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'}]}>
2339 END
2340 call assert_equal(expected, getline(2, '$'))
2341 %d
2342
2343 call assert_equal(function('Args'), py3eval('a'))
2344 call assert_equal(function('Args', ['abcArgsPA1']), py3eval('pa1'))
2345 call assert_equal(function('Args'), py3eval('pa2'))
2346 call assert_equal(function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}), py3eval('pa3'))
2347 call assert_equal(function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}), py3eval('pa4'))
2348 call assert_equal(function('SelfArgs'), py3eval('sa'))
2349 call assert_equal(function('SelfArgs', ['abcArgsPSA1']), py3eval('psa1'))
2350 call assert_equal(function('SelfArgs'), py3eval('psa2'))
2351 call assert_equal(function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}), py3eval('psa3'))
2352 call assert_equal(function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}), py3eval('psa4'))
2353 call assert_equal(function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}), py3eval('psa5'))
2354 call assert_equal(function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}), py3eval('psa6'))
2355 call assert_equal(function('SelfArgs', ['abcArgsPSA7']), py3eval('psa7'))
2356 call assert_equal(function('SelfArgs'), py3eval('psa8'))
2357 call assert_equal(function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}), py3eval('psa9'))
2358 call assert_equal(function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}), py3eval('psaA'))
2359 call assert_equal(function('SelfArgs', ['abcArgsPSAB']), py3eval('psaB'))
2360 call assert_equal(function('SelfArgs'), py3eval('psaC'))
2361
2362 let res = []
2363 for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7',
2364 \ 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
2365 let d = {'f': py3eval(v)}
2366 call add(res, 'd.' .. v .. '(): ' .. string(d.f()))
2367 endfor
2368
2369 let expected =<< trim END
2370 d.sa(): [[], {'f': function('SelfArgs')}]
2371 d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
2372 d.psa2(): [[], {'f': function('SelfArgs')}]
2373 d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2374 d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2375 d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
2376 d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
2377 d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
2378 d.psa8(): [[], {'f': function('SelfArgs')}]
2379 d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
2380 d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
2381 d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
2382 d.psaC(): [[], {'f': function('SelfArgs')}]
2383 END
2384 call assert_equal(expected, res)
2385
2386 py3 ecall('a()', a, )
2387 py3 ecall('pa1()', pa1, )
2388 py3 ecall('pa2()', pa2, )
2389 py3 ecall('pa3()', pa3, )
2390 py3 ecall('pa4()', pa4, )
2391 py3 ecall('sa()', sa, )
2392 py3 ecall('psa1()', psa1, )
2393 py3 ecall('psa2()', psa2, )
2394 py3 ecall('psa3()', psa3, )
2395 py3 ecall('psa4()', psa4, )
2396
2397 py3 ecall('a(42, 43)', a, 42, 43)
2398 py3 ecall('pa1(42, 43)', pa1, 42, 43)
2399 py3 ecall('pa2(42, 43)', pa2, 42, 43)
2400 py3 ecall('pa3(42, 43)', pa3, 42, 43)
2401 py3 ecall('pa4(42, 43)', pa4, 42, 43)
2402 py3 ecall('sa(42, 43)', sa, 42, 43)
2403 py3 ecall('psa1(42, 43)', psa1, 42, 43)
2404 py3 ecall('psa2(42, 43)', psa2, 42, 43)
2405 py3 ecall('psa3(42, 43)', psa3, 42, 43)
2406 py3 ecall('psa4(42, 43)', psa4, 42, 43)
2407
2408 py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
2409 py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
2410 py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
2411 py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
2412 py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
2413 py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
2414 py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
2415 py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
2416 py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
2417 py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
2418
2419 py3 ecall('a(self={"20": 1})', a, self={'20': 1})
2420 py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
2421 py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
2422 py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
2423 py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
2424 py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
2425 py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
2426 py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
2427 py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
2428 py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
2429
2430 py3 << trim EOF
2431 def s(v):
2432 if v is None:
2433 return repr(v)
2434 else:
2435 return str(vim.Function('string')(v), 'utf-8')
2436
2437 cb.append('a.args: ' + s(a.args))
2438 cb.append('pa1.args: ' + s(pa1.args))
2439 cb.append('pa2.args: ' + s(pa2.args))
2440 cb.append('pa3.args: ' + s(pa3.args))
2441 cb.append('pa4.args: ' + s(pa4.args))
2442 cb.append('sa.args: ' + s(sa.args))
2443 cb.append('psa1.args: ' + s(psa1.args))
2444 cb.append('psa2.args: ' + s(psa2.args))
2445 cb.append('psa3.args: ' + s(psa3.args))
2446 cb.append('psa4.args: ' + s(psa4.args))
2447
2448 cb.append('a.self: ' + s(a.self))
2449 cb.append('pa1.self: ' + s(pa1.self))
2450 cb.append('pa2.self: ' + s(pa2.self))
2451 cb.append('pa3.self: ' + s(pa3.self))
2452 cb.append('pa4.self: ' + s(pa4.self))
2453 cb.append('sa.self: ' + s(sa.self))
2454 cb.append('psa1.self: ' + s(psa1.self))
2455 cb.append('psa2.self: ' + s(psa2.self))
2456 cb.append('psa3.self: ' + s(psa3.self))
2457 cb.append('psa4.self: ' + s(psa4.self))
2458
2459 cb.append('a.name: ' + s(a.name))
2460 cb.append('pa1.name: ' + s(pa1.name))
2461 cb.append('pa2.name: ' + s(pa2.name))
2462 cb.append('pa3.name: ' + s(pa3.name))
2463 cb.append('pa4.name: ' + s(pa4.name))
2464 cb.append('sa.name: ' + s(sa.name))
2465 cb.append('psa1.name: ' + s(psa1.name))
2466 cb.append('psa2.name: ' + s(psa2.name))
2467 cb.append('psa3.name: ' + s(psa3.name))
2468 cb.append('psa4.name: ' + s(psa4.name))
2469
2470 cb.append('a.auto_rebind: ' + s(a.auto_rebind))
2471 cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
2472 cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
2473 cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
2474 cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
2475 cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
2476 cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
2477 cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
2478 cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
2479 cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
2480 cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
2481 cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
2482 cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
2483 cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
2484 cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
2485 cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
2486 cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
2487 cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
2488
2489 del s
2490
2491 del a
2492 del pa1
2493 del pa2
2494 del pa3
2495 del pa4
2496 del sa
2497 del psa1
2498 del psa2
2499 del psa3
2500 del psa4
2501 del psa5
2502 del psa6
2503 del psa7
2504 del psa8
2505 del psa9
2506 del psaA
2507 del psaB
2508 del psaC
2509 del psar
2510
2511 del ecall
2512 EOF
2513
2514 let expected =<< trim END
2515 a(): !result: []
2516 pa1(): !result: ['abcArgsPA1']
2517 pa2(): !result: []
2518 pa3(): !result: ['abcArgsPA3']
2519 pa4(): !result: []
2520 sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2521 psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2522 psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2523 psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2524 psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2525 a(42, 43): !result: [42, 43]
2526 pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
2527 pa2(42, 43): !result: [42, 43]
2528 pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
2529 pa4(42, 43): !result: [42, 43]
2530 sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2531 psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2532 psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2533 psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2534 psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2535 a(42, self={"20": 1}): !result: [42]
2536 pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
2537 pa2(42, self={"20": 1}): !result: [42]
2538 pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
2539 pa4(42, self={"20": 1}): !result: [42]
2540 sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
2541 psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
2542 psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
2543 psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
2544 psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
2545 a(self={"20": 1}): !result: []
2546 pa1(self={"20": 1}): !result: ['abcArgsPA1']
2547 pa2(self={"20": 1}): !result: []
2548 pa3(self={"20": 1}): !result: ['abcArgsPA3']
2549 pa4(self={"20": 1}): !result: []
2550 sa(self={"20": 1}): !result: [[], {'20': 1}]
2551 psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
2552 psa2(self={"20": 1}): !result: [[], {'20': 1}]
2553 psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
2554 psa4(self={"20": 1}): !result: [[], {'20': 1}]
2555 a.args: None
2556 pa1.args: ['abcArgsPA1']
2557 pa2.args: None
2558 pa3.args: ['abcArgsPA3']
2559 pa4.args: None
2560 sa.args: None
2561 psa1.args: ['abcArgsPSA1']
2562 psa2.args: None
2563 psa3.args: ['abcArgsPSA3']
2564 psa4.args: None
2565 a.self: None
2566 pa1.self: None
2567 pa2.self: None
2568 pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
2569 pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
2570 sa.self: None
2571 psa1.self: None
2572 psa2.self: None
2573 psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
2574 psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
2575 a.name: 'Args'
2576 pa1.name: 'Args'
2577 pa2.name: 'Args'
2578 pa3.name: 'Args'
2579 pa4.name: 'Args'
2580 sa.name: 'SelfArgs'
2581 psa1.name: 'SelfArgs'
2582 psa2.name: 'SelfArgs'
2583 psa3.name: 'SelfArgs'
2584 psa4.name: 'SelfArgs'
2585 a.auto_rebind: 1
2586 pa1.auto_rebind: 1
2587 pa2.auto_rebind: 1
2588 pa3.auto_rebind: 0
2589 pa4.auto_rebind: 0
2590 sa.auto_rebind: 1
2591 psa1.auto_rebind: 1
2592 psa2.auto_rebind: 1
2593 psa3.auto_rebind: 0
2594 psa4.auto_rebind: 0
2595 psa5.auto_rebind: 0
2596 psa6.auto_rebind: 0
2597 psa7.auto_rebind: 1
2598 psa8.auto_rebind: 1
2599 psa9.auto_rebind: 1
2600 psaA.auto_rebind: 1
2601 psaB.auto_rebind: 1
2602 psaC.auto_rebind: 1
2603 END
2604 call assert_equal(expected, getline(2, '$'))
2605 %bw!
2606endfunc
2607
2608" Test stdout/stderr
2609func Test_python3_stdin_stderr()
2610 let caught_writeerr = 0
2611 let caught_writelineerr = 0
2612 redir => messages
2613 py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
2614 try
2615 py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
2616 catch /abc9def/
2617 let caught_writeerr = 1
2618 endtry
2619 py3 sys.stdout.writelines(iter('abcA'))
2620 try
2621 py3 sys.stderr.writelines(iter('abcB'))
2622 catch /abcB/
2623 let caught_writelineerr = 1
2624 endtry
2625 redir END
2626 call assert_equal("\nabc8def\nabcA", messages)
2627 call assert_equal(1, caught_writeerr)
2628 call assert_equal(1, caught_writelineerr)
2629endfunc
2630
2631" Test subclassing
2632func Test_python3_subclass()
2633 new
2634 func Put(...)
2635 return a:000
2636 endfunc
2637
2638 py3 << trim EOF
2639 class DupDict(vim.Dictionary):
2640 def __setitem__(self, key, value):
2641 super(DupDict, self).__setitem__(key, value)
2642 super(DupDict, self).__setitem__('dup_' + key, value)
2643 dd = DupDict()
2644 dd['a'] = 'b'
2645
2646 class DupList(vim.List):
2647 def __getitem__(self, idx):
2648 return [super(DupList, self).__getitem__(idx)] * 2
2649
2650 dl = DupList()
2651 dl2 = DupList(iter('abcC'))
2652 dl.extend(dl2[0])
2653
2654 class DupFun(vim.Function):
2655 def __call__(self, arg):
2656 return super(DupFun, self).__call__(arg, arg)
2657
2658 df = DupFun('Put')
2659 EOF
2660
2661 call assert_equal(['a', 'dup_a'], sort(keys(py3eval('dd'))))
2662 call assert_equal(['a', 'a'], py3eval('dl'))
2663 call assert_equal(['a', 'b', 'c', 'C'], py3eval('dl2'))
2664 call assert_equal([2, 2], py3eval('df(2)'))
2665 call assert_equal(1, py3eval('dl') is# py3eval('dl'))
2666 call assert_equal(1, py3eval('dd') is# py3eval('dd'))
2667 call assert_equal(function('Put'), py3eval('df'))
2668 delfunction Put
2669 py3 << trim EOF
2670 del DupDict
2671 del DupList
2672 del DupFun
2673 del dd
2674 del dl
2675 del dl2
2676 del df
2677 EOF
2678 close!
2679endfunc
2680
2681" Test chdir
2682func Test_python3_chdir()
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002683 new Xp3cdfile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002684 py3 cb = vim.current.buffer
2685 py3 << trim EOF
2686 import os
2687 fnamemodify = vim.Function('fnamemodify')
2688 cb.append(str(fnamemodify('.', ':p:h:t')))
2689 cb.append(vim.eval('@%'))
2690 os.chdir('..')
2691 path = fnamemodify('.', ':p:h:t')
Bram Moolenaar7d697962020-08-31 21:30:32 +02002692 if path != b'src' and path != b'src2':
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002693 # Running tests from a shadow directory, so move up another level
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002694 # This will result in @% looking like shadow/testdir/Xp3cdfile, hence the
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002695 # slicing to remove the leading path and path separator
2696 os.chdir('..')
2697 cb.append(str(fnamemodify('.', ':p:h:t')))
2698 cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
2699 os.chdir(path)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002700 else:
Bram Moolenaar7d697962020-08-31 21:30:32 +02002701 # Also accept running from src2/testdir/ for MS-Windows CI.
2702 cb.append(str(fnamemodify('.', ':p:h:t').replace(b'src2', b'src')))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002703 cb.append(vim.eval('@%').replace(os.path.sep, '/'))
2704 del path
2705 os.chdir('testdir')
2706 cb.append(str(fnamemodify('.', ':p:h:t')))
2707 cb.append(vim.eval('@%'))
2708 del fnamemodify
2709 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002710 call assert_equal(["b'testdir'", 'Xp3cdfile', "b'src'", 'testdir/Xp3cdfile',
2711 \"b'testdir'", 'Xp3cdfile'], getline(2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002712 close!
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02002713 call AssertException(["py3 vim.chdir(None)"], "Vim(py3):TypeError:")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002714endfunc
2715
2716" Test errors
2717func Test_python3_errors()
2718 func F() dict
2719 endfunc
2720
2721 func D()
2722 endfunc
2723
2724 new
2725 py3 cb = vim.current.buffer
2726
2727 py3 << trim EOF
K.Takata1be7e212021-11-16 13:08:56 +00002728 import os
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002729 d = vim.Dictionary()
2730 ned = vim.Dictionary(foo='bar', baz='abcD')
2731 dl = vim.Dictionary(a=1)
2732 dl.locked = True
2733 l = vim.List()
2734 ll = vim.List('abcE')
2735 ll.locked = True
2736 nel = vim.List('abcO')
2737 f = vim.Function('string')
2738 fd = vim.Function('F')
2739 fdel = vim.Function('D')
2740 vim.command('delfunction D')
2741
2742 def subexpr_test(expr, name, subexprs):
2743 cb.append('>>> Testing %s using %s' % (name, expr))
2744 for subexpr in subexprs:
2745 ee(expr % subexpr)
2746 cb.append('<<< Finished')
2747
2748 def stringtochars_test(expr):
2749 return subexpr_test(expr, 'StringToChars', (
2750 '1', # Fail type checks
2751 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
2752 '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
2753 ))
2754
2755 class Mapping(object):
2756 def __init__(self, d):
2757 self.d = d
2758
2759 def __getitem__(self, key):
2760 return self.d[key]
2761
2762 def keys(self):
2763 return self.d.keys()
2764
2765 def items(self):
2766 return self.d.items()
2767
2768 def convertfrompyobject_test(expr, recurse=True):
2769 # pydict_to_tv
2770 stringtochars_test(expr % '{%s : 1}')
2771 if recurse:
2772 convertfrompyobject_test(expr % '{"abcF" : %s}', False)
2773 # pymap_to_tv
2774 stringtochars_test(expr % 'Mapping({%s : 1})')
2775 if recurse:
2776 convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
2777 # pyseq_to_tv
2778 iter_test(expr)
2779 return subexpr_test(expr, 'ConvertFromPyObject', (
2780 'None', # Not conversible
2781 '{b"": 1}', # Empty key not allowed
2782 '{"": 1}', # Same, but with unicode object
2783 'FailingMapping()', #
2784 'FailingMappingKey()', #
2785 'FailingNumber()', #
2786 ))
2787
2788 def convertfrompymapping_test(expr):
2789 convertfrompyobject_test(expr)
2790 return subexpr_test(expr, 'ConvertFromPyMapping', (
2791 '[]',
2792 ))
2793
2794 def iter_test(expr):
2795 return subexpr_test(expr, '*Iter*', (
2796 'FailingIter()',
2797 'FailingIterNext()',
2798 ))
2799
2800 def number_test(expr, natural=False, unsigned=False):
2801 if natural:
2802 unsigned = True
2803 return subexpr_test(expr, 'NumberToLong', (
2804 '[]',
2805 'None',
2806 ) + (('-1',) if unsigned else ())
2807 + (('0',) if natural else ()))
2808
2809 class FailingTrue(object):
2810 def __bool__(self):
2811 raise NotImplementedError('bool')
2812
2813 class FailingIter(object):
2814 def __iter__(self):
2815 raise NotImplementedError('iter')
2816
2817 class FailingIterNext(object):
2818 def __iter__(self):
2819 return self
2820
2821 def __next__(self):
2822 raise NotImplementedError('next')
2823
2824 class FailingIterNextN(object):
2825 def __init__(self, n):
2826 self.n = n
2827
2828 def __iter__(self):
2829 return self
2830
2831 def __next__(self):
2832 if self.n:
2833 self.n -= 1
2834 return 1
2835 else:
2836 raise NotImplementedError('next N')
2837
2838 class FailingMappingKey(object):
2839 def __getitem__(self, item):
2840 raise NotImplementedError('getitem:mappingkey')
2841
2842 def keys(self):
2843 return list("abcH")
2844
2845 class FailingMapping(object):
2846 def __getitem__(self):
2847 raise NotImplementedError('getitem:mapping')
2848
2849 def keys(self):
2850 raise NotImplementedError('keys')
2851
2852 class FailingList(list):
2853 def __getitem__(self, idx):
2854 if i == 2:
2855 raise NotImplementedError('getitem:list')
2856 else:
2857 return super(FailingList, self).__getitem__(idx)
2858
2859 class NoArgsCall(object):
2860 def __call__(self):
2861 pass
2862
2863 class FailingCall(object):
2864 def __call__(self, path):
2865 raise NotImplementedError('call')
2866
2867 class FailingNumber(object):
2868 def __int__(self):
2869 raise NotImplementedError('int')
2870
2871 cb.append("> Output")
2872 cb.append(">> OutputSetattr")
2873 ee('del sys.stdout.softspace')
2874 number_test('sys.stdout.softspace = %s', unsigned=True)
2875 number_test('sys.stderr.softspace = %s', unsigned=True)
2876 ee('assert sys.stdout.isatty()==False')
2877 ee('assert sys.stdout.seekable()==False')
2878 ee('sys.stdout.close()')
2879 ee('sys.stdout.flush()')
2880 ee('assert sys.stderr.isatty()==False')
2881 ee('assert sys.stderr.seekable()==False')
2882 ee('sys.stderr.close()')
2883 ee('sys.stderr.flush()')
2884 ee('sys.stdout.attr = None')
2885 cb.append(">> OutputWrite")
2886 ee('assert sys.stdout.writable()==True')
2887 ee('assert sys.stdout.readable()==False')
2888 ee('assert sys.stderr.writable()==True')
2889 ee('assert sys.stderr.readable()==False')
2890 ee('assert sys.stdout.closed()==False')
2891 ee('assert sys.stderr.closed()==False')
2892 ee('assert sys.stdout.errors=="strict"')
2893 ee('assert sys.stderr.errors=="strict"')
2894 ee('assert sys.stdout.encoding==sys.stderr.encoding')
2895 ee('sys.stdout.write(None)')
2896 cb.append(">> OutputWriteLines")
2897 ee('sys.stdout.writelines(None)')
2898 ee('sys.stdout.writelines([1])')
2899 iter_test('sys.stdout.writelines(%s)')
2900 cb.append("> VimCommand")
2901 stringtochars_test('vim.command(%s)')
2902 ee('vim.command("", 2)')
2903 #! Not checked: vim->python exceptions translating: checked later
2904 cb.append("> VimToPython")
2905 #! Not checked: everything: needs errors in internal python functions
2906 cb.append("> VimEval")
2907 stringtochars_test('vim.eval(%s)')
2908 ee('vim.eval("", FailingTrue())')
2909 #! Not checked: everything: needs errors in internal python functions
2910 cb.append("> VimEvalPy")
2911 stringtochars_test('vim.bindeval(%s)')
2912 ee('vim.eval("", 2)')
2913 #! Not checked: vim->python exceptions translating: checked later
2914 cb.append("> VimStrwidth")
2915 stringtochars_test('vim.strwidth(%s)')
2916 cb.append("> VimForeachRTP")
2917 ee('vim.foreach_rtp(None)')
2918 ee('vim.foreach_rtp(NoArgsCall())')
2919 ee('vim.foreach_rtp(FailingCall())')
2920 ee('vim.foreach_rtp(int, 2)')
2921 cb.append('> import')
2922 old_rtp = vim.options['rtp']
2923 vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
2924 ee('import xxx_no_such_module_xxx')
2925 ee('import failing_import')
2926 ee('import failing')
2927 vim.options['rtp'] = old_rtp
2928 del old_rtp
2929 cb.append("> Options")
2930 cb.append(">> OptionsItem")
2931 ee('vim.options["abcQ"]')
2932 ee('vim.options[""]')
2933 stringtochars_test('vim.options[%s]')
2934 cb.append(">> OptionsContains")
2935 stringtochars_test('%s in vim.options')
2936 cb.append("> Dictionary")
2937 cb.append(">> DictionaryConstructor")
2938 ee('vim.Dictionary("abcI")')
2939 ##! Not checked: py_dict_alloc failure
2940 cb.append(">> DictionarySetattr")
2941 ee('del d.locked')
2942 ee('d.locked = FailingTrue()')
2943 ee('vim.vvars.locked = False')
2944 ee('d.scope = True')
2945 ee('d.xxx = True')
2946 cb.append(">> _DictionaryItem")
2947 ee('d.get("a", 2, 3)')
2948 stringtochars_test('d.get(%s)')
2949 ee('d.pop("a")')
2950 ee('dl.pop("a")')
2951 cb.append(">> DictionaryContains")
2952 ee('"" in d')
2953 ee('0 in d')
2954 cb.append(">> DictionaryIterNext")
2955 ee('for i in ned: ned["a"] = 1')
2956 del i
2957 cb.append(">> DictionaryAssItem")
2958 ee('dl["b"] = 1')
2959 stringtochars_test('d[%s] = 1')
2960 convertfrompyobject_test('d["a"] = %s')
2961 cb.append(">> DictionaryUpdate")
2962 cb.append(">>> kwargs")
2963 cb.append(">>> iter")
2964 ee('d.update(FailingMapping())')
2965 ee('d.update([FailingIterNext()])')
2966 ee('d.update([FailingIterNextN(1)])')
2967 iter_test('d.update(%s)')
2968 convertfrompyobject_test('d.update(%s)')
2969 stringtochars_test('d.update(((%s, 0),))')
2970 convertfrompyobject_test('d.update((("a", %s),))')
2971 cb.append(">> DictionaryPopItem")
2972 ee('d.popitem(1, 2)')
2973 cb.append(">> DictionaryHasKey")
2974 ee('d.has_key()')
2975 cb.append("> List")
2976 cb.append(">> ListConstructor")
2977 ee('vim.List(1, 2)')
2978 ee('vim.List(a=1)')
2979 iter_test('vim.List(%s)')
2980 convertfrompyobject_test('vim.List([%s])')
2981 cb.append(">> ListItem")
2982 ee('l[1000]')
2983 cb.append(">> ListAssItem")
2984 ee('ll[1] = 2')
2985 ee('l[1000] = 3')
2986 cb.append(">> ListAssSlice")
2987 ee('ll[1:100] = "abcJ"')
2988 iter_test('l[:] = %s')
2989 ee('nel[1:10:2] = "abcK"')
2990 cb.append(repr(tuple(nel)))
2991 ee('nel[1:10:2] = "a"')
2992 cb.append(repr(tuple(nel)))
2993 ee('nel[1:1:-1] = "a"')
2994 cb.append(repr(tuple(nel)))
2995 ee('nel[:] = FailingIterNextN(2)')
2996 cb.append(repr(tuple(nel)))
2997 convertfrompyobject_test('l[:] = [%s]')
2998 cb.append(">> ListConcatInPlace")
2999 iter_test('l.extend(%s)')
3000 convertfrompyobject_test('l.extend([%s])')
3001 cb.append(">> ListSetattr")
3002 ee('del l.locked')
3003 ee('l.locked = FailingTrue()')
3004 ee('l.xxx = True')
3005 cb.append("> Function")
3006 cb.append(">> FunctionConstructor")
3007 cb.append(">>> FunctionConstructor")
3008 ee('vim.Function("123")')
3009 ee('vim.Function("xxx_non_existent_function_xxx")')
3010 ee('vim.Function("xxx#non#existent#function#xxx")')
3011 ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
3012 ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
3013 ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
3014 cb.append(">>> FunctionNew")
3015 ee('vim.Function("tr", self="abcFuncSelf")')
3016 ee('vim.Function("tr", args=427423)')
3017 ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
3018 ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
3019 ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
3020 ee('vim.Function("tr", "")')
3021 cb.append(">> FunctionCall")
3022 convertfrompyobject_test('f(%s)')
3023 convertfrompymapping_test('fd(self=%s)')
3024 cb.append("> TabPage")
3025 cb.append(">> TabPageAttr")
3026 ee('vim.current.tabpage.xxx')
3027 cb.append("> TabList")
3028 cb.append(">> TabListItem")
3029 ee('vim.tabpages[1000]')
3030 cb.append("> Window")
3031 cb.append(">> WindowAttr")
3032 ee('vim.current.window.xxx')
3033 cb.append(">> WindowSetattr")
3034 ee('vim.current.window.buffer = 0')
3035 ee('vim.current.window.cursor = (100000000, 100000000)')
3036 ee('vim.current.window.cursor = True')
3037 number_test('vim.current.window.height = %s', unsigned=True)
3038 number_test('vim.current.window.width = %s', unsigned=True)
3039 ee('vim.current.window.xxxxxx = True')
3040 cb.append("> WinList")
3041 cb.append(">> WinListItem")
3042 ee('vim.windows[1000]')
3043 cb.append("> Buffer")
3044 cb.append(">> StringToLine (indirect)")
3045 ee('vim.current.buffer[0] = "\\na"')
3046 ee('vim.current.buffer[0] = b"\\na"')
3047 cb.append(">> SetBufferLine (indirect)")
3048 ee('vim.current.buffer[0] = True')
3049 cb.append(">> SetBufferLineList (indirect)")
3050 ee('vim.current.buffer[:] = True')
3051 ee('vim.current.buffer[:] = ["\\na", "bc"]')
3052 cb.append(">> InsertBufferLines (indirect)")
3053 ee('vim.current.buffer.append(None)')
3054 ee('vim.current.buffer.append(["\\na", "bc"])')
3055 ee('vim.current.buffer.append("\\nbc")')
3056 cb.append(">> RBItem")
3057 ee('vim.current.buffer[100000000]')
3058 cb.append(">> RBAsItem")
3059 ee('vim.current.buffer[100000000] = ""')
3060 cb.append(">> BufferAttr")
3061 ee('vim.current.buffer.xxx')
3062 cb.append(">> BufferSetattr")
3063 ee('vim.current.buffer.name = True')
3064 ee('vim.current.buffer.xxx = True')
3065 cb.append(">> BufferMark")
3066 ee('vim.current.buffer.mark(0)')
3067 ee('vim.current.buffer.mark("abcM")')
3068 ee('vim.current.buffer.mark("!")')
3069 cb.append(">> BufferRange")
3070 ee('vim.current.buffer.range(1, 2, 3)')
3071 cb.append("> BufMap")
3072 cb.append(">> BufMapItem")
3073 ee('vim.buffers[100000000]')
3074 number_test('vim.buffers[%s]', natural=True)
3075 cb.append("> Current")
3076 cb.append(">> CurrentGetattr")
3077 ee('vim.current.xxx')
3078 cb.append(">> CurrentSetattr")
3079 ee('vim.current.line = True')
3080 ee('vim.current.buffer = True')
3081 ee('vim.current.window = True')
3082 ee('vim.current.tabpage = True')
3083 ee('vim.current.xxx = True')
3084 del d
3085 del ned
3086 del dl
3087 del l
3088 del ll
3089 del nel
3090 del f
3091 del fd
3092 del fdel
3093 del subexpr_test
3094 del stringtochars_test
3095 del Mapping
3096 del convertfrompyobject_test
3097 del convertfrompymapping_test
3098 del iter_test
3099 del number_test
3100 del FailingTrue
3101 del FailingIter
3102 del FailingIterNext
3103 del FailingIterNextN
3104 del FailingMapping
3105 del FailingMappingKey
3106 del FailingList
3107 del NoArgsCall
3108 del FailingCall
3109 del FailingNumber
3110 EOF
3111 delfunction F
3112
3113 let expected =<< trim END
3114 > Output
3115 >> OutputSetattr
3116 del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError('cannot delete OutputObject attributes',))
3117 >>> Testing NumberToLong using sys.stdout.softspace = %s
3118 sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3119 sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3120 sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3121 <<< Finished
3122 >>> Testing NumberToLong using sys.stderr.softspace = %s
3123 sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3124 sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3125 sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3126 <<< Finished
3127 assert sys.stdout.isatty()==False:NOT FAILED
3128 assert sys.stdout.seekable()==False:NOT FAILED
3129 sys.stdout.close():NOT FAILED
3130 sys.stdout.flush():NOT FAILED
3131 assert sys.stderr.isatty()==False:NOT FAILED
3132 assert sys.stderr.seekable()==False:NOT FAILED
3133 sys.stderr.close():NOT FAILED
3134 sys.stderr.flush():NOT FAILED
3135 sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
3136 >> OutputWrite
3137 assert sys.stdout.writable()==True:NOT FAILED
3138 assert sys.stdout.readable()==False:NOT FAILED
3139 assert sys.stderr.writable()==True:NOT FAILED
3140 assert sys.stderr.readable()==False:NOT FAILED
3141 assert sys.stdout.closed()==False:NOT FAILED
3142 assert sys.stderr.closed()==False:NOT FAILED
3143 assert sys.stdout.errors=="strict":NOT FAILED
3144 assert sys.stderr.errors=="strict":NOT FAILED
3145 assert sys.stdout.encoding==sys.stderr.encoding:NOT FAILED
3146 sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
3147 >> OutputWriteLines
3148 sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3149 sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
3150 >>> Testing *Iter* using sys.stdout.writelines(%s)
3151 sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3152 sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3153 <<< Finished
3154 > VimCommand
3155 >>> Testing StringToChars using vim.command(%s)
3156 vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3157 vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3158 vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3159 <<< Finished
3160 vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
3161 > VimToPython
3162 > VimEval
3163 >>> Testing StringToChars using vim.eval(%s)
3164 vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3165 vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3166 vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3167 <<< Finished
3168 vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3169 > VimEvalPy
3170 >>> Testing StringToChars using vim.bindeval(%s)
3171 vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3172 vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3173 vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3174 <<< Finished
3175 vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3176 > VimStrwidth
3177 >>> Testing StringToChars using vim.strwidth(%s)
3178 vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3179 vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3180 vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3181 <<< Finished
3182 > VimForeachRTP
3183 vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
3184 vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
3185 vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
3186 vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
3187 > import
3188 import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
3189 import failing_import:(<class 'ImportError'>, ImportError())
3190 import failing:(<class 'NotImplementedError'>, NotImplementedError())
3191 > Options
3192 >> OptionsItem
3193 vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
3194 vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3195 >>> Testing StringToChars using vim.options[%s]
3196 vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3197 vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3198 vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3199 <<< Finished
3200 >> OptionsContains
3201 >>> Testing StringToChars using %s in vim.options
3202 1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3203 b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3204 "\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3205 <<< Finished
3206 > Dictionary
3207 >> DictionaryConstructor
3208 vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
3209 >> DictionarySetattr
3210 del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
3211 d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3212 vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
3213 d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
3214 d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3215 >> _DictionaryItem
3216 d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
3217 >>> Testing StringToChars using d.get(%s)
3218 d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3219 d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3220 d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3221 <<< Finished
3222 d.pop("a"):(<class 'KeyError'>, KeyError('a',))
3223 dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
3224 >> DictionaryContains
3225 "" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3226 0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3227 >> DictionaryIterNext
3228 for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
3229 >> DictionaryAssItem
3230 dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
3231 >>> Testing StringToChars using d[%s] = 1
3232 d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3233 d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3234 d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3235 <<< Finished
3236 >>> Testing StringToChars using d["a"] = {%s : 1}
3237 d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3238 d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3239 d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3240 <<< Finished
3241 >>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
3242 d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3243 d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3244 d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3245 <<< Finished
3246 >>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
3247 d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3248 d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3249 d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3250 <<< Finished
3251 >>> Testing *Iter* using d["a"] = {"abcF" : %s}
3252 d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3253 d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
3254 <<< Finished
3255 >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
3256 d["a"] = {"abcF" : None}:NOT FAILED
3257 d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3258 d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3259 d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3260 d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3261 d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
3262 <<< Finished
3263 >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
3264 d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3265 d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3266 d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3267 <<< Finished
3268 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
3269 d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3270 d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3271 d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3272 <<< Finished
3273 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
3274 d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3275 d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3276 d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3277 <<< Finished
3278 >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
3279 d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3280 d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3281 <<< Finished
3282 >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
3283 d["a"] = Mapping({"abcG" : None}):NOT FAILED
3284 d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3285 d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3286 d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3287 d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3288 d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3289 <<< Finished
3290 >>> Testing *Iter* using d["a"] = %s
3291 d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3292 d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3293 <<< Finished
3294 >>> Testing ConvertFromPyObject using d["a"] = %s
3295 d["a"] = None:NOT FAILED
3296 d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3297 d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3298 d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
3299 d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3300 d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
3301 <<< Finished
3302 >> DictionaryUpdate
3303 >>> kwargs
3304 >>> iter
3305 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3306 d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3307 d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3308 >>> Testing *Iter* using d.update(%s)
3309 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3310 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3311 <<< Finished
3312 >>> Testing StringToChars using d.update({%s : 1})
3313 d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3314 d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3315 d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3316 <<< Finished
3317 >>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
3318 d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3319 d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3320 d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3321 <<< Finished
3322 >>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
3323 d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3324 d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3325 d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3326 <<< Finished
3327 >>> Testing *Iter* using d.update({"abcF" : %s})
3328 d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3329 d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3330 <<< Finished
3331 >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
3332 d.update({"abcF" : None}):NOT FAILED
3333 d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3334 d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3335 d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3336 d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3337 d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3338 <<< Finished
3339 >>> Testing StringToChars using d.update(Mapping({%s : 1}))
3340 d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3341 d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3342 d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3343 <<< Finished
3344 >>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
3345 d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3346 d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3347 d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3348 <<< Finished
3349 >>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
3350 d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3351 d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3352 d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3353 <<< Finished
3354 >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
3355 d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3356 d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3357 <<< Finished
3358 >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
3359 d.update(Mapping({"abcG" : None})):NOT FAILED
3360 d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3361 d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3362 d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3363 d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3364 d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3365 <<< Finished
3366 >>> Testing *Iter* using d.update(%s)
3367 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3368 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3369 <<< Finished
3370 >>> Testing ConvertFromPyObject using d.update(%s)
3371 d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3372 d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3373 d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3374 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3375 d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3376 d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
3377 <<< Finished
3378 >>> Testing StringToChars using d.update(((%s, 0),))
3379 d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3380 d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3381 d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3382 <<< Finished
3383 >>> Testing StringToChars using d.update((("a", {%s : 1}),))
3384 d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3385 d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3386 d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3387 <<< Finished
3388 >>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
3389 d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3390 d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3391 d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3392 <<< Finished
3393 >>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
3394 d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3395 d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3396 d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3397 <<< Finished
3398 >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
3399 d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3400 d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3401 <<< Finished
3402 >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
3403 d.update((("a", {"abcF" : None}),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3404 d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3405 d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3406 d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3407 d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3408 d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3409 <<< Finished
3410 >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
3411 d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3412 d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3413 d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3414 <<< Finished
3415 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
3416 d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3417 d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3418 d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3419 <<< Finished
3420 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
3421 d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3422 d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3423 d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3424 <<< Finished
3425 >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
3426 d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3427 d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3428 <<< Finished
3429 >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
3430 d.update((("a", Mapping({"abcG" : None})),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3431 d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3432 d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3433 d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3434 d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3435 d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3436 <<< Finished
3437 >>> Testing *Iter* using d.update((("a", %s),))
3438 d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3439 d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3440 <<< Finished
3441 >>> Testing ConvertFromPyObject using d.update((("a", %s),))
3442 d.update((("a", None),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3443 d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3444 d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3445 d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3446 d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3447 d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3448 <<< Finished
3449 >> DictionaryPopItem
3450 d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
3451 >> DictionaryHasKey
3452 d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
3453 > List
3454 >> ListConstructor
3455 vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
3456 vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
3457 >>> Testing *Iter* using vim.List(%s)
3458 vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3459 vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3460 <<< Finished
3461 >>> Testing StringToChars using vim.List([{%s : 1}])
3462 vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3463 vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3464 vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3465 <<< Finished
3466 >>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
3467 vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3468 vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3469 vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3470 <<< Finished
3471 >>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
3472 vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3473 vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3474 vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3475 <<< Finished
3476 >>> Testing *Iter* using vim.List([{"abcF" : %s}])
3477 vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3478 vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3479 <<< Finished
3480 >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
3481 vim.List([{"abcF" : None}]):NOT FAILED
3482 vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3483 vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3484 vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3485 vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3486 vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3487 <<< Finished
3488 >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
3489 vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3490 vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3491 vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3492 <<< Finished
3493 >>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
3494 vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3495 vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3496 vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3497 <<< Finished
3498 >>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
3499 vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3500 vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3501 vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3502 <<< Finished
3503 >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
3504 vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3505 vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3506 <<< Finished
3507 >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
3508 vim.List([Mapping({"abcG" : None})]):NOT FAILED
3509 vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3510 vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3511 vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3512 vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3513 vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3514 <<< Finished
3515 >>> Testing *Iter* using vim.List([%s])
3516 vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3517 vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3518 <<< Finished
3519 >>> Testing ConvertFromPyObject using vim.List([%s])
3520 vim.List([None]):NOT FAILED
3521 vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3522 vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3523 vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3524 vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3525 vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3526 <<< Finished
3527 >> ListItem
3528 l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
3529 >> ListAssItem
3530 ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
3531 l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
3532 >> ListAssSlice
3533 ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
3534 >>> Testing *Iter* using l[:] = %s
3535 l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
3536 l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3537 <<< Finished
3538 nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 2 to extended slice',))
3539 (b'a', b'b', b'c', b'O')
3540 nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
3541 (b'a', b'b', b'c', b'O')
3542 nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 0 to extended slice',))
3543 (b'a', b'b', b'c', b'O')
3544 nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3545 (b'a', b'b', b'c', b'O')
3546 >>> Testing StringToChars using l[:] = [{%s : 1}]
3547 l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3548 l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3549 l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3550 <<< Finished
3551 >>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
3552 l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3553 l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3554 l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3555 <<< Finished
3556 >>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
3557 l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3558 l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3559 l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3560 <<< Finished
3561 >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
3562 l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3563 l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3564 <<< Finished
3565 >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
3566 l[:] = [{"abcF" : None}]:NOT FAILED
3567 l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3568 l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3569 l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3570 l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3571 l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3572 <<< Finished
3573 >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
3574 l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3575 l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3576 l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3577 <<< Finished
3578 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
3579 l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3580 l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3581 l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3582 <<< Finished
3583 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
3584 l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3585 l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3586 l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3587 <<< Finished
3588 >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
3589 l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3590 l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3591 <<< Finished
3592 >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
3593 l[:] = [Mapping({"abcG" : None})]:NOT FAILED
3594 l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3595 l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3596 l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3597 l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3598 l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3599 <<< Finished
3600 >>> Testing *Iter* using l[:] = [%s]
3601 l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3602 l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3603 <<< Finished
3604 >>> Testing ConvertFromPyObject using l[:] = [%s]
3605 l[:] = [None]:NOT FAILED
3606 l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3607 l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3608 l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3609 l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3610 l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3611 <<< Finished
3612 >> ListConcatInPlace
3613 >>> Testing *Iter* using l.extend(%s)
3614 l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3615 l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3616 <<< Finished
3617 >>> Testing StringToChars using l.extend([{%s : 1}])
3618 l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3619 l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3620 l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3621 <<< Finished
3622 >>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
3623 l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3624 l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3625 l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3626 <<< Finished
3627 >>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
3628 l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3629 l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3630 l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3631 <<< Finished
3632 >>> Testing *Iter* using l.extend([{"abcF" : %s}])
3633 l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3634 l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3635 <<< Finished
3636 >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
3637 l.extend([{"abcF" : None}]):NOT FAILED
3638 l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3639 l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3640 l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3641 l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3642 l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3643 <<< Finished
3644 >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
3645 l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3646 l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3647 l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3648 <<< Finished
3649 >>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
3650 l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3651 l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3652 l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3653 <<< Finished
3654 >>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
3655 l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3656 l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3657 l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3658 <<< Finished
3659 >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
3660 l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3661 l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3662 <<< Finished
3663 >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
3664 l.extend([Mapping({"abcG" : None})]):NOT FAILED
3665 l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3666 l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3667 l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3668 l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3669 l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3670 <<< Finished
3671 >>> Testing *Iter* using l.extend([%s])
3672 l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3673 l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3674 <<< Finished
3675 >>> Testing ConvertFromPyObject using l.extend([%s])
3676 l.extend([None]):NOT FAILED
3677 l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3678 l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3679 l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3680 l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3681 l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3682 <<< Finished
3683 >> ListSetattr
3684 del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
3685 l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3686 l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3687 > Function
3688 >> FunctionConstructor
3689 >>> FunctionConstructor
3690 vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
3691 vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
3692 vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
3693 vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
3694 vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
3695 vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
3696 >>> FunctionNew
3697 vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
3698 vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to a Vim list',))
3699 vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3700 vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3701 vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3702 vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3703 >> FunctionCall
3704 >>> Testing StringToChars using f({%s : 1})
3705 f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3706 f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3707 f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3708 <<< Finished
3709 >>> Testing StringToChars using f({"abcF" : {%s : 1}})
3710 f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3711 f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3712 f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3713 <<< Finished
3714 >>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
3715 f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3716 f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3717 f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3718 <<< Finished
3719 >>> Testing *Iter* using f({"abcF" : %s})
3720 f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3721 f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3722 <<< Finished
3723 >>> Testing ConvertFromPyObject using f({"abcF" : %s})
3724 f({"abcF" : None}):NOT FAILED
3725 f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3726 f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3727 f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3728 f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3729 f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3730 <<< Finished
3731 >>> Testing StringToChars using f(Mapping({%s : 1}))
3732 f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3733 f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3734 f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3735 <<< Finished
3736 >>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
3737 f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3738 f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3739 f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3740 <<< Finished
3741 >>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
3742 f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3743 f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3744 f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3745 <<< Finished
3746 >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
3747 f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3748 f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3749 <<< Finished
3750 >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
3751 f(Mapping({"abcG" : None})):NOT FAILED
3752 f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3753 f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3754 f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3755 f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3756 f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3757 <<< Finished
3758 >>> Testing *Iter* using f(%s)
3759 f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3760 f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3761 <<< Finished
3762 >>> Testing ConvertFromPyObject using f(%s)
3763 f(None):NOT FAILED
3764 f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3765 f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3766 f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3767 f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3768 f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
3769 <<< Finished
3770 >>> Testing StringToChars using fd(self={%s : 1})
3771 fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3772 fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3773 fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3774 <<< Finished
3775 >>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
3776 fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3777 fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3778 fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3779 <<< Finished
3780 >>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
3781 fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3782 fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3783 fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3784 <<< Finished
3785 >>> Testing *Iter* using fd(self={"abcF" : %s})
3786 fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3787 fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3788 <<< Finished
3789 >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
3790 fd(self={"abcF" : None}):NOT FAILED
3791 fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3792 fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3793 fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3794 fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3795 fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3796 <<< Finished
3797 >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
3798 fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3799 fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3800 fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3801 <<< Finished
3802 >>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
3803 fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3804 fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3805 fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3806 <<< Finished
3807 >>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
3808 fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3809 fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3810 fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3811 <<< Finished
3812 >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
3813 fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3814 fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3815 <<< Finished
3816 >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
3817 fd(self=Mapping({"abcG" : None})):NOT FAILED
3818 fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3819 fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3820 fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3821 fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3822 fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3823 <<< Finished
3824 >>> Testing *Iter* using fd(self=%s)
3825 fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim dictionary',))
3826 fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to a Vim dictionary',))
3827 <<< Finished
3828 >>> Testing ConvertFromPyObject using fd(self=%s)
3829 fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to a Vim dictionary',))
3830 fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3831 fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3832 fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3833 fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3834 fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to a Vim dictionary',))
3835 <<< Finished
3836 >>> Testing ConvertFromPyMapping using fd(self=%s)
3837 fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
3838 <<< Finished
3839 > TabPage
3840 >> TabPageAttr
3841 vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
3842 > TabList
3843 >> TabListItem
3844 vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
3845 > Window
3846 >> WindowAttr
3847 vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
3848 >> WindowSetattr
3849 vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
3850 vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
3851 vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
3852 >>> Testing NumberToLong using vim.current.window.height = %s
3853 vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3854 vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3855 vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3856 <<< Finished
3857 >>> Testing NumberToLong using vim.current.window.width = %s
3858 vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3859 vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3860 vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3861 <<< Finished
3862 vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
3863 > WinList
3864 >> WinListItem
3865 vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
3866 > Buffer
3867 >> StringToLine (indirect)
3868 vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3869 vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3870 >> SetBufferLine (indirect)
3871 vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3872 >> SetBufferLineList (indirect)
3873 vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3874 vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
3875 >> InsertBufferLines (indirect)
3876 vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3877 vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
3878 vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
3879 >> RBItem
3880 vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
3881 >> RBAsItem
3882 vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
3883 >> BufferAttr
3884 vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
3885 >> BufferSetattr
3886 vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
3887 vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3888 >> BufferMark
3889 vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3890 vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
3891 vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
3892 >> BufferRange
3893 vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
3894 > BufMap
3895 >> BufMapItem
3896 vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
3897 >>> Testing NumberToLong using vim.buffers[%s]
3898 vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3899 vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3900 vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3901 vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3902 <<< Finished
3903 > Current
3904 >> CurrentGetattr
3905 vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
3906 >> CurrentSetattr
3907 vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3908 vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
3909 vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
3910 vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
3911 vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3912 END
3913
Bram Moolenaar68a48ee2020-10-27 19:59:10 +01003914 let actual = getline(2, '$')
3915 let n_expected = len(expected)
3916 let n_actual = len(actual)
3917 call assert_equal(n_expected, n_actual, 'number of lines to compare')
3918
3919 " Compare line by line so the errors are easier to understand. Missing lines
3920 " are compared with an empty string.
3921 for i in range(n_expected > n_actual ? n_expected : n_actual)
3922 call assert_equal(i >= n_expected ? '' : expected[i], i >= n_actual ? '' : actual[i])
3923 endfor
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02003924 close!
3925endfunc
3926
3927" Test import
3928func Test_python3_import()
3929 new
3930 py3 cb = vim.current.buffer
3931
3932 py3 << trim EOF
3933 sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
3934 sys.path.append(os.path.join(os.getcwd(), 'python_after'))
3935 vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
3936 l = []
3937 def callback(path):
3938 l.append(os.path.relpath(path))
3939 vim.foreach_rtp(callback)
3940 cb.append(repr(l))
3941 del l
3942 def callback(path):
3943 return os.path.relpath(path)
3944 cb.append(repr(vim.foreach_rtp(callback)))
3945 del callback
3946 from module import dir as d
3947 from modulex import ddir
3948 cb.append(d + ',' + ddir)
3949 import before
3950 cb.append(before.dir)
3951 import after
3952 cb.append(after.dir)
3953 import topmodule as tm
3954 import topmodule.submodule as tms
3955 import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
3956 cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
3957 cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
3958 cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
3959
3960 del before
3961 del after
3962 del d
3963 del ddir
3964 del tm
3965 del tms
3966 del tmsss
3967 EOF
3968
3969 let expected =<< trim END
3970 ['.']
3971 '.'
3972 3,xx
3973 before
3974 after
3975 pythonx/topmodule/__init__.py
3976 pythonx/topmodule/submodule/__init__.py
3977 pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
3978 END
3979 call assert_equal(expected, getline(2, '$'))
3980 close!
Bram Moolenaarab589462020-07-06 21:03:06 +02003981
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01003982 " Try to import a non-existing module with a dot (.)
Bram Moolenaarab589462020-07-06 21:03:06 +02003983 call AssertException(['py3 import a.b.c'], "No module named 'a'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02003984endfunc
3985
3986" Test exceptions
3987func Test_python3_exception()
3988 func Exe(e)
3989 execute a:e
3990 endfunc
3991
3992 new
3993 py3 cb = vim.current.buffer
3994
3995 py3 << trim EOF
3996 Exe = vim.bindeval('function("Exe")')
3997 ee('vim.command("throw \'abcN\'")')
3998 ee('Exe("throw \'def\'")')
3999 ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
4000 ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
4001 ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
4002 ee('vim.eval("xxx_unknown_function_xxx()")')
4003 ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
4004 del Exe
4005 EOF
4006 delfunction Exe
4007
4008 let expected =<< trim END
4009 vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
4010 Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
4011 vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
4012 vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
4013 vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
4014 vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
4015 vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
4016 END
4017 call assert_equal(expected, getline(2, '$'))
4018 close!
4019endfunc
4020
4021" Regression: interrupting vim.command propagates to next vim.command
4022func Test_python3_keyboard_interrupt()
4023 new
4024 py3 cb = vim.current.buffer
4025 py3 << trim EOF
4026 def test_keyboard_interrupt():
4027 try:
4028 vim.command('while 1 | endwhile')
4029 except KeyboardInterrupt:
4030 cb.append('Caught KeyboardInterrupt')
4031 except Exception:
4032 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
4033 else:
4034 cb.append('!!!!!!!! No exception')
4035 try:
4036 vim.command('$ put =\'Running :put\'')
4037 except KeyboardInterrupt:
4038 cb.append('!!!!!!!! Caught KeyboardInterrupt')
4039 except Exception:
4040 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
4041 else:
4042 cb.append('No exception')
4043 EOF
4044
4045 debuggreedy
4046 call inputsave()
4047 call feedkeys("s\ns\ns\ns\nq\n")
4048 redir => output
4049 debug silent! py3 test_keyboard_interrupt()
4050 redir END
4051 0 debuggreedy
4052 call inputrestore()
4053 py3 del test_keyboard_interrupt
4054
4055 let expected =<< trim END
4056 Caught KeyboardInterrupt
4057 Running :put
4058 No exception
4059 END
4060 call assert_equal(expected, getline(2, '$'))
4061 call assert_equal('', output)
4062 close!
4063endfunc
4064
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004065" Regression: Iterator for a Vim object should hold a reference.
4066func Test_python3_iter_ref()
4067 let g:list_iter_ref_count_increase = -1
4068 let g:dict_iter_ref_count_increase = -1
4069 let g:bufmap_iter_ref_count_increase = -1
4070 let g:options_iter_ref_count_increase = -1
4071
4072 py3 << trim EOF
4073 import sys
4074 import vim
4075
4076 def test_python3_iter_ref():
4077 create_list = vim.Function('Create_vim_list')
4078 v = create_list()
4079 base_ref_count = sys.getrefcount(v)
4080 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004081 vim.vars['list_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004082
4083 create_dict = vim.Function('Create_vim_dict')
4084 v = create_dict()
4085 base_ref_count = sys.getrefcount(v)
4086 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004087 vim.vars['dict_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004088
4089 v = vim.buffers
4090 base_ref_count = sys.getrefcount(v)
4091 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004092 vim.vars['bufmap_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004093
4094 v = vim.options
4095 base_ref_count = sys.getrefcount(v)
4096 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004097 vim.vars['options_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004098
4099 test_python3_iter_ref()
4100 EOF
4101
4102 call assert_equal(1, g:list_iter_ref_count_increase)
4103 call assert_equal(1, g:dict_iter_ref_count_increase)
Boris Staletic83a06702024-10-14 20:28:39 +02004104 if py3eval('sys.version_info[:2] < (3, 13)')
4105 call assert_equal(1, g:bufmap_iter_ref_count_increase)
4106 else
4107 call assert_equal(0, g:bufmap_iter_ref_count_increase)
4108 endif
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004109 call assert_equal(1, g:options_iter_ref_count_increase)
4110endfunc
4111
Bram Moolenaar2e2f52a2020-12-21 16:03:02 +01004112func Test_python3_non_utf8_string()
4113 smap <Esc>@ <A-@>
4114 py3 vim.command('redir => _tmp_smaps | smap | redir END')
4115 py3 vim.eval('_tmp_smaps').splitlines()
4116 sunmap <Esc>@
4117endfunc
4118
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004119func Test_python3_fold_hidden_buffer()
4120 CheckFeature folding
4121
4122 set fdm=expr fde=Fde(v:lnum)
4123 let b:regex = '^'
4124 func Fde(lnum)
4125 let ld = [{}]
4126 let lines = bufnr('%')->getbufline(1, '$')
4127 let was_import = 0
4128 for lnum in range(1, len(lines))
4129 let line = lines[lnum]
4130 call add(ld, {'a': b:regex})
4131 let ld[lnum].foldexpr = was_import ? 1 : '>1'
4132 let was_import = 1
4133 endfor
4134 return ld[a:lnum].foldexpr
4135 endfunc
4136
4137 call setline(1, repeat([''], 15) + repeat(['from'], 3))
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004138 eval repeat(['x'], 17)->writefile('Xa.txt', 'D')
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004139 split Xa.txt
4140 py3 import vim
4141 py3 b = vim.current.buffer
4142 py3 aaa = b[:]
4143 hide
4144 py3 b[:] = aaa
4145
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004146 set fdm& fde&
4147 delfunc Fde
4148 bwipe! Xa.txt
4149endfunc
4150
Bram Moolenaar37233f62022-05-22 12:23:48 +01004151" Test to catch regression fix #10437.
4152func Test_python3_hidden_buf_mod_does_not_mess_up_display()
4153 CheckRunVimInTerminal
4154
4155 let testfile = 'Xtest.vim'
4156 let lines =<< trim END
4157 set hidden number
4158 new
4159 hide
4160 sil call setline(1, repeat(['aaa'], &lines) + ['bbbbbb'])
4161 fu Func()
4162 python3 << EOF
4163 import vim
4164 b = vim.buffers[2]
4165 b[:] = ['', '']
4166 EOF
4167 endfu
4168 norm! Gzb
4169 call feedkeys(":call Func()\r", 'n')
4170 END
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004171 call writefile(lines, testfile, 'D')
Bram Moolenaar37233f62022-05-22 12:23:48 +01004172
4173 let rows = 10
4174 let bufnr = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
4175 call TermWait(bufnr, 100)
4176 call assert_equal('run', job_status(term_getjob(bufnr)))
4177 let g:test_is_flaky = 0
4178 call WaitForAssert({-> assert_match('^ 3 aaa$', term_getline(bufnr, 1))})
4179 call WaitForAssert({-> assert_match('^ 11 bbbbbb$', term_getline(bufnr, rows - 1))})
4180
4181 call term_sendkeys(bufnr, ":qall!\<CR>")
4182 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(bufnr)))})
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004183
Bram Moolenaar37233f62022-05-22 12:23:48 +01004184 exe bufnr . 'bwipe!'
Bram Moolenaar37233f62022-05-22 12:23:48 +01004185endfunc
4186
Bram Moolenaar1363a302020-04-12 13:50:26 +02004187" vim: shiftwidth=2 sts=2 expandtab