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