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