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