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