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