blob: 0885c96988fbedb4ec037f7e97bc98399df6c6b4 [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')
2594 if path != b'src':
2595 # 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:
2603 cb.append(str(fnamemodify('.', ':p:h:t')))
2604 cb.append(vim.eval('@%').replace(os.path.sep, '/'))
2605 del path
2606 os.chdir('testdir')
2607 cb.append(str(fnamemodify('.', ':p:h:t')))
2608 cb.append(vim.eval('@%'))
2609 del fnamemodify
2610 EOF
2611 call assert_equal(["b'testdir'", 'Xfile', "b'src'", 'testdir/Xfile',
2612 \"b'testdir'", 'Xfile'], getline(2, '$'))
2613 close!
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02002614 call AssertException(["py3 vim.chdir(None)"], "Vim(py3):TypeError:")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002615endfunc
2616
2617" Test errors
2618func Test_python3_errors()
2619 func F() dict
2620 endfunc
2621
2622 func D()
2623 endfunc
2624
2625 new
2626 py3 cb = vim.current.buffer
2627
2628 py3 << trim EOF
2629 d = vim.Dictionary()
2630 ned = vim.Dictionary(foo='bar', baz='abcD')
2631 dl = vim.Dictionary(a=1)
2632 dl.locked = True
2633 l = vim.List()
2634 ll = vim.List('abcE')
2635 ll.locked = True
2636 nel = vim.List('abcO')
2637 f = vim.Function('string')
2638 fd = vim.Function('F')
2639 fdel = vim.Function('D')
2640 vim.command('delfunction D')
2641
2642 def subexpr_test(expr, name, subexprs):
2643 cb.append('>>> Testing %s using %s' % (name, expr))
2644 for subexpr in subexprs:
2645 ee(expr % subexpr)
2646 cb.append('<<< Finished')
2647
2648 def stringtochars_test(expr):
2649 return subexpr_test(expr, 'StringToChars', (
2650 '1', # Fail type checks
2651 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
2652 '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
2653 ))
2654
2655 class Mapping(object):
2656 def __init__(self, d):
2657 self.d = d
2658
2659 def __getitem__(self, key):
2660 return self.d[key]
2661
2662 def keys(self):
2663 return self.d.keys()
2664
2665 def items(self):
2666 return self.d.items()
2667
2668 def convertfrompyobject_test(expr, recurse=True):
2669 # pydict_to_tv
2670 stringtochars_test(expr % '{%s : 1}')
2671 if recurse:
2672 convertfrompyobject_test(expr % '{"abcF" : %s}', False)
2673 # pymap_to_tv
2674 stringtochars_test(expr % 'Mapping({%s : 1})')
2675 if recurse:
2676 convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
2677 # pyseq_to_tv
2678 iter_test(expr)
2679 return subexpr_test(expr, 'ConvertFromPyObject', (
2680 'None', # Not conversible
2681 '{b"": 1}', # Empty key not allowed
2682 '{"": 1}', # Same, but with unicode object
2683 'FailingMapping()', #
2684 'FailingMappingKey()', #
2685 'FailingNumber()', #
2686 ))
2687
2688 def convertfrompymapping_test(expr):
2689 convertfrompyobject_test(expr)
2690 return subexpr_test(expr, 'ConvertFromPyMapping', (
2691 '[]',
2692 ))
2693
2694 def iter_test(expr):
2695 return subexpr_test(expr, '*Iter*', (
2696 'FailingIter()',
2697 'FailingIterNext()',
2698 ))
2699
2700 def number_test(expr, natural=False, unsigned=False):
2701 if natural:
2702 unsigned = True
2703 return subexpr_test(expr, 'NumberToLong', (
2704 '[]',
2705 'None',
2706 ) + (('-1',) if unsigned else ())
2707 + (('0',) if natural else ()))
2708
2709 class FailingTrue(object):
2710 def __bool__(self):
2711 raise NotImplementedError('bool')
2712
2713 class FailingIter(object):
2714 def __iter__(self):
2715 raise NotImplementedError('iter')
2716
2717 class FailingIterNext(object):
2718 def __iter__(self):
2719 return self
2720
2721 def __next__(self):
2722 raise NotImplementedError('next')
2723
2724 class FailingIterNextN(object):
2725 def __init__(self, n):
2726 self.n = n
2727
2728 def __iter__(self):
2729 return self
2730
2731 def __next__(self):
2732 if self.n:
2733 self.n -= 1
2734 return 1
2735 else:
2736 raise NotImplementedError('next N')
2737
2738 class FailingMappingKey(object):
2739 def __getitem__(self, item):
2740 raise NotImplementedError('getitem:mappingkey')
2741
2742 def keys(self):
2743 return list("abcH")
2744
2745 class FailingMapping(object):
2746 def __getitem__(self):
2747 raise NotImplementedError('getitem:mapping')
2748
2749 def keys(self):
2750 raise NotImplementedError('keys')
2751
2752 class FailingList(list):
2753 def __getitem__(self, idx):
2754 if i == 2:
2755 raise NotImplementedError('getitem:list')
2756 else:
2757 return super(FailingList, self).__getitem__(idx)
2758
2759 class NoArgsCall(object):
2760 def __call__(self):
2761 pass
2762
2763 class FailingCall(object):
2764 def __call__(self, path):
2765 raise NotImplementedError('call')
2766
2767 class FailingNumber(object):
2768 def __int__(self):
2769 raise NotImplementedError('int')
2770
2771 cb.append("> Output")
2772 cb.append(">> OutputSetattr")
2773 ee('del sys.stdout.softspace')
2774 number_test('sys.stdout.softspace = %s', unsigned=True)
2775 number_test('sys.stderr.softspace = %s', unsigned=True)
2776 ee('assert sys.stdout.isatty()==False')
2777 ee('assert sys.stdout.seekable()==False')
2778 ee('sys.stdout.close()')
2779 ee('sys.stdout.flush()')
2780 ee('assert sys.stderr.isatty()==False')
2781 ee('assert sys.stderr.seekable()==False')
2782 ee('sys.stderr.close()')
2783 ee('sys.stderr.flush()')
2784 ee('sys.stdout.attr = None')
2785 cb.append(">> OutputWrite")
2786 ee('assert sys.stdout.writable()==True')
2787 ee('assert sys.stdout.readable()==False')
2788 ee('assert sys.stderr.writable()==True')
2789 ee('assert sys.stderr.readable()==False')
2790 ee('assert sys.stdout.closed()==False')
2791 ee('assert sys.stderr.closed()==False')
2792 ee('assert sys.stdout.errors=="strict"')
2793 ee('assert sys.stderr.errors=="strict"')
2794 ee('assert sys.stdout.encoding==sys.stderr.encoding')
2795 ee('sys.stdout.write(None)')
2796 cb.append(">> OutputWriteLines")
2797 ee('sys.stdout.writelines(None)')
2798 ee('sys.stdout.writelines([1])')
2799 iter_test('sys.stdout.writelines(%s)')
2800 cb.append("> VimCommand")
2801 stringtochars_test('vim.command(%s)')
2802 ee('vim.command("", 2)')
2803 #! Not checked: vim->python exceptions translating: checked later
2804 cb.append("> VimToPython")
2805 #! Not checked: everything: needs errors in internal python functions
2806 cb.append("> VimEval")
2807 stringtochars_test('vim.eval(%s)')
2808 ee('vim.eval("", FailingTrue())')
2809 #! Not checked: everything: needs errors in internal python functions
2810 cb.append("> VimEvalPy")
2811 stringtochars_test('vim.bindeval(%s)')
2812 ee('vim.eval("", 2)')
2813 #! Not checked: vim->python exceptions translating: checked later
2814 cb.append("> VimStrwidth")
2815 stringtochars_test('vim.strwidth(%s)')
2816 cb.append("> VimForeachRTP")
2817 ee('vim.foreach_rtp(None)')
2818 ee('vim.foreach_rtp(NoArgsCall())')
2819 ee('vim.foreach_rtp(FailingCall())')
2820 ee('vim.foreach_rtp(int, 2)')
2821 cb.append('> import')
2822 old_rtp = vim.options['rtp']
2823 vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
2824 ee('import xxx_no_such_module_xxx')
2825 ee('import failing_import')
2826 ee('import failing')
2827 vim.options['rtp'] = old_rtp
2828 del old_rtp
2829 cb.append("> Options")
2830 cb.append(">> OptionsItem")
2831 ee('vim.options["abcQ"]')
2832 ee('vim.options[""]')
2833 stringtochars_test('vim.options[%s]')
2834 cb.append(">> OptionsContains")
2835 stringtochars_test('%s in vim.options')
2836 cb.append("> Dictionary")
2837 cb.append(">> DictionaryConstructor")
2838 ee('vim.Dictionary("abcI")')
2839 ##! Not checked: py_dict_alloc failure
2840 cb.append(">> DictionarySetattr")
2841 ee('del d.locked')
2842 ee('d.locked = FailingTrue()')
2843 ee('vim.vvars.locked = False')
2844 ee('d.scope = True')
2845 ee('d.xxx = True')
2846 cb.append(">> _DictionaryItem")
2847 ee('d.get("a", 2, 3)')
2848 stringtochars_test('d.get(%s)')
2849 ee('d.pop("a")')
2850 ee('dl.pop("a")')
2851 cb.append(">> DictionaryContains")
2852 ee('"" in d')
2853 ee('0 in d')
2854 cb.append(">> DictionaryIterNext")
2855 ee('for i in ned: ned["a"] = 1')
2856 del i
2857 cb.append(">> DictionaryAssItem")
2858 ee('dl["b"] = 1')
2859 stringtochars_test('d[%s] = 1')
2860 convertfrompyobject_test('d["a"] = %s')
2861 cb.append(">> DictionaryUpdate")
2862 cb.append(">>> kwargs")
2863 cb.append(">>> iter")
2864 ee('d.update(FailingMapping())')
2865 ee('d.update([FailingIterNext()])')
2866 ee('d.update([FailingIterNextN(1)])')
2867 iter_test('d.update(%s)')
2868 convertfrompyobject_test('d.update(%s)')
2869 stringtochars_test('d.update(((%s, 0),))')
2870 convertfrompyobject_test('d.update((("a", %s),))')
2871 cb.append(">> DictionaryPopItem")
2872 ee('d.popitem(1, 2)')
2873 cb.append(">> DictionaryHasKey")
2874 ee('d.has_key()')
2875 cb.append("> List")
2876 cb.append(">> ListConstructor")
2877 ee('vim.List(1, 2)')
2878 ee('vim.List(a=1)')
2879 iter_test('vim.List(%s)')
2880 convertfrompyobject_test('vim.List([%s])')
2881 cb.append(">> ListItem")
2882 ee('l[1000]')
2883 cb.append(">> ListAssItem")
2884 ee('ll[1] = 2')
2885 ee('l[1000] = 3')
2886 cb.append(">> ListAssSlice")
2887 ee('ll[1:100] = "abcJ"')
2888 iter_test('l[:] = %s')
2889 ee('nel[1:10:2] = "abcK"')
2890 cb.append(repr(tuple(nel)))
2891 ee('nel[1:10:2] = "a"')
2892 cb.append(repr(tuple(nel)))
2893 ee('nel[1:1:-1] = "a"')
2894 cb.append(repr(tuple(nel)))
2895 ee('nel[:] = FailingIterNextN(2)')
2896 cb.append(repr(tuple(nel)))
2897 convertfrompyobject_test('l[:] = [%s]')
2898 cb.append(">> ListConcatInPlace")
2899 iter_test('l.extend(%s)')
2900 convertfrompyobject_test('l.extend([%s])')
2901 cb.append(">> ListSetattr")
2902 ee('del l.locked')
2903 ee('l.locked = FailingTrue()')
2904 ee('l.xxx = True')
2905 cb.append("> Function")
2906 cb.append(">> FunctionConstructor")
2907 cb.append(">>> FunctionConstructor")
2908 ee('vim.Function("123")')
2909 ee('vim.Function("xxx_non_existent_function_xxx")')
2910 ee('vim.Function("xxx#non#existent#function#xxx")')
2911 ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
2912 ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
2913 ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
2914 cb.append(">>> FunctionNew")
2915 ee('vim.Function("tr", self="abcFuncSelf")')
2916 ee('vim.Function("tr", args=427423)')
2917 ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
2918 ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
2919 ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
2920 ee('vim.Function("tr", "")')
2921 cb.append(">> FunctionCall")
2922 convertfrompyobject_test('f(%s)')
2923 convertfrompymapping_test('fd(self=%s)')
2924 cb.append("> TabPage")
2925 cb.append(">> TabPageAttr")
2926 ee('vim.current.tabpage.xxx')
2927 cb.append("> TabList")
2928 cb.append(">> TabListItem")
2929 ee('vim.tabpages[1000]')
2930 cb.append("> Window")
2931 cb.append(">> WindowAttr")
2932 ee('vim.current.window.xxx')
2933 cb.append(">> WindowSetattr")
2934 ee('vim.current.window.buffer = 0')
2935 ee('vim.current.window.cursor = (100000000, 100000000)')
2936 ee('vim.current.window.cursor = True')
2937 number_test('vim.current.window.height = %s', unsigned=True)
2938 number_test('vim.current.window.width = %s', unsigned=True)
2939 ee('vim.current.window.xxxxxx = True')
2940 cb.append("> WinList")
2941 cb.append(">> WinListItem")
2942 ee('vim.windows[1000]')
2943 cb.append("> Buffer")
2944 cb.append(">> StringToLine (indirect)")
2945 ee('vim.current.buffer[0] = "\\na"')
2946 ee('vim.current.buffer[0] = b"\\na"')
2947 cb.append(">> SetBufferLine (indirect)")
2948 ee('vim.current.buffer[0] = True')
2949 cb.append(">> SetBufferLineList (indirect)")
2950 ee('vim.current.buffer[:] = True')
2951 ee('vim.current.buffer[:] = ["\\na", "bc"]')
2952 cb.append(">> InsertBufferLines (indirect)")
2953 ee('vim.current.buffer.append(None)')
2954 ee('vim.current.buffer.append(["\\na", "bc"])')
2955 ee('vim.current.buffer.append("\\nbc")')
2956 cb.append(">> RBItem")
2957 ee('vim.current.buffer[100000000]')
2958 cb.append(">> RBAsItem")
2959 ee('vim.current.buffer[100000000] = ""')
2960 cb.append(">> BufferAttr")
2961 ee('vim.current.buffer.xxx')
2962 cb.append(">> BufferSetattr")
2963 ee('vim.current.buffer.name = True')
2964 ee('vim.current.buffer.xxx = True')
2965 cb.append(">> BufferMark")
2966 ee('vim.current.buffer.mark(0)')
2967 ee('vim.current.buffer.mark("abcM")')
2968 ee('vim.current.buffer.mark("!")')
2969 cb.append(">> BufferRange")
2970 ee('vim.current.buffer.range(1, 2, 3)')
2971 cb.append("> BufMap")
2972 cb.append(">> BufMapItem")
2973 ee('vim.buffers[100000000]')
2974 number_test('vim.buffers[%s]', natural=True)
2975 cb.append("> Current")
2976 cb.append(">> CurrentGetattr")
2977 ee('vim.current.xxx')
2978 cb.append(">> CurrentSetattr")
2979 ee('vim.current.line = True')
2980 ee('vim.current.buffer = True')
2981 ee('vim.current.window = True')
2982 ee('vim.current.tabpage = True')
2983 ee('vim.current.xxx = True')
2984 del d
2985 del ned
2986 del dl
2987 del l
2988 del ll
2989 del nel
2990 del f
2991 del fd
2992 del fdel
2993 del subexpr_test
2994 del stringtochars_test
2995 del Mapping
2996 del convertfrompyobject_test
2997 del convertfrompymapping_test
2998 del iter_test
2999 del number_test
3000 del FailingTrue
3001 del FailingIter
3002 del FailingIterNext
3003 del FailingIterNextN
3004 del FailingMapping
3005 del FailingMappingKey
3006 del FailingList
3007 del NoArgsCall
3008 del FailingCall
3009 del FailingNumber
3010 EOF
3011 delfunction F
3012
3013 let expected =<< trim END
3014 > Output
3015 >> OutputSetattr
3016 del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError('cannot delete OutputObject attributes',))
3017 >>> Testing NumberToLong using sys.stdout.softspace = %s
3018 sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3019 sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3020 sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3021 <<< Finished
3022 >>> Testing NumberToLong using sys.stderr.softspace = %s
3023 sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3024 sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3025 sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3026 <<< Finished
3027 assert sys.stdout.isatty()==False:NOT FAILED
3028 assert sys.stdout.seekable()==False:NOT FAILED
3029 sys.stdout.close():NOT FAILED
3030 sys.stdout.flush():NOT FAILED
3031 assert sys.stderr.isatty()==False:NOT FAILED
3032 assert sys.stderr.seekable()==False:NOT FAILED
3033 sys.stderr.close():NOT FAILED
3034 sys.stderr.flush():NOT FAILED
3035 sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
3036 >> OutputWrite
3037 assert sys.stdout.writable()==True:NOT FAILED
3038 assert sys.stdout.readable()==False:NOT FAILED
3039 assert sys.stderr.writable()==True:NOT FAILED
3040 assert sys.stderr.readable()==False:NOT FAILED
3041 assert sys.stdout.closed()==False:NOT FAILED
3042 assert sys.stderr.closed()==False:NOT FAILED
3043 assert sys.stdout.errors=="strict":NOT FAILED
3044 assert sys.stderr.errors=="strict":NOT FAILED
3045 assert sys.stdout.encoding==sys.stderr.encoding:NOT FAILED
3046 sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
3047 >> OutputWriteLines
3048 sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3049 sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
3050 >>> Testing *Iter* using sys.stdout.writelines(%s)
3051 sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3052 sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3053 <<< Finished
3054 > VimCommand
3055 >>> Testing StringToChars using vim.command(%s)
3056 vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3057 vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3058 vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3059 <<< Finished
3060 vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
3061 > VimToPython
3062 > VimEval
3063 >>> Testing StringToChars using vim.eval(%s)
3064 vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3065 vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3066 vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3067 <<< Finished
3068 vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3069 > VimEvalPy
3070 >>> Testing StringToChars using vim.bindeval(%s)
3071 vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3072 vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3073 vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3074 <<< Finished
3075 vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3076 > VimStrwidth
3077 >>> Testing StringToChars using vim.strwidth(%s)
3078 vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3079 vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3080 vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3081 <<< Finished
3082 > VimForeachRTP
3083 vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
3084 vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
3085 vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
3086 vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
3087 > import
3088 import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
3089 import failing_import:(<class 'ImportError'>, ImportError())
3090 import failing:(<class 'NotImplementedError'>, NotImplementedError())
3091 > Options
3092 >> OptionsItem
3093 vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
3094 vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3095 >>> Testing StringToChars using vim.options[%s]
3096 vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3097 vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3098 vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3099 <<< Finished
3100 >> OptionsContains
3101 >>> Testing StringToChars using %s in vim.options
3102 1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3103 b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3104 "\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3105 <<< Finished
3106 > Dictionary
3107 >> DictionaryConstructor
3108 vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
3109 >> DictionarySetattr
3110 del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
3111 d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3112 vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
3113 d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
3114 d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3115 >> _DictionaryItem
3116 d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
3117 >>> Testing StringToChars using d.get(%s)
3118 d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3119 d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3120 d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3121 <<< Finished
3122 d.pop("a"):(<class 'KeyError'>, KeyError('a',))
3123 dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
3124 >> DictionaryContains
3125 "" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3126 0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3127 >> DictionaryIterNext
3128 for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
3129 >> DictionaryAssItem
3130 dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
3131 >>> Testing StringToChars using d[%s] = 1
3132 d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3133 d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3134 d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3135 <<< Finished
3136 >>> Testing StringToChars using d["a"] = {%s : 1}
3137 d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3138 d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3139 d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3140 <<< Finished
3141 >>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
3142 d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3143 d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3144 d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3145 <<< Finished
3146 >>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
3147 d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3148 d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3149 d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3150 <<< Finished
3151 >>> Testing *Iter* using d["a"] = {"abcF" : %s}
3152 d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3153 d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
3154 <<< Finished
3155 >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
3156 d["a"] = {"abcF" : None}:NOT FAILED
3157 d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3158 d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3159 d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3160 d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3161 d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
3162 <<< Finished
3163 >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
3164 d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3165 d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3166 d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3167 <<< Finished
3168 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
3169 d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3170 d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3171 d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3172 <<< Finished
3173 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
3174 d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3175 d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3176 d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3177 <<< Finished
3178 >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
3179 d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3180 d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3181 <<< Finished
3182 >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
3183 d["a"] = Mapping({"abcG" : None}):NOT FAILED
3184 d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3185 d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3186 d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3187 d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3188 d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3189 <<< Finished
3190 >>> Testing *Iter* using d["a"] = %s
3191 d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3192 d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3193 <<< Finished
3194 >>> Testing ConvertFromPyObject using d["a"] = %s
3195 d["a"] = None:NOT FAILED
3196 d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3197 d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3198 d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
3199 d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3200 d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
3201 <<< Finished
3202 >> DictionaryUpdate
3203 >>> kwargs
3204 >>> iter
3205 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3206 d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3207 d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3208 >>> Testing *Iter* using d.update(%s)
3209 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3210 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3211 <<< Finished
3212 >>> Testing StringToChars using d.update({%s : 1})
3213 d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3214 d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3215 d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3216 <<< Finished
3217 >>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
3218 d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3219 d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3220 d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3221 <<< Finished
3222 >>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
3223 d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3224 d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3225 d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3226 <<< Finished
3227 >>> Testing *Iter* using d.update({"abcF" : %s})
3228 d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3229 d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3230 <<< Finished
3231 >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
3232 d.update({"abcF" : None}):NOT FAILED
3233 d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3234 d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3235 d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3236 d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3237 d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3238 <<< Finished
3239 >>> Testing StringToChars using d.update(Mapping({%s : 1}))
3240 d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3241 d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3242 d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3243 <<< Finished
3244 >>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
3245 d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3246 d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3247 d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3248 <<< Finished
3249 >>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
3250 d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3251 d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3252 d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3253 <<< Finished
3254 >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
3255 d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3256 d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3257 <<< Finished
3258 >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
3259 d.update(Mapping({"abcG" : None})):NOT FAILED
3260 d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3261 d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3262 d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3263 d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3264 d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3265 <<< Finished
3266 >>> Testing *Iter* using d.update(%s)
3267 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3268 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3269 <<< Finished
3270 >>> Testing ConvertFromPyObject using d.update(%s)
3271 d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3272 d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3273 d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3274 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3275 d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3276 d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
3277 <<< Finished
3278 >>> Testing StringToChars using d.update(((%s, 0),))
3279 d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3280 d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3281 d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3282 <<< Finished
3283 >>> Testing StringToChars using d.update((("a", {%s : 1}),))
3284 d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3285 d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3286 d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3287 <<< Finished
3288 >>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
3289 d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3290 d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3291 d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3292 <<< Finished
3293 >>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
3294 d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3295 d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3296 d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3297 <<< Finished
3298 >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
3299 d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3300 d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3301 <<< Finished
3302 >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
3303 d.update((("a", {"abcF" : None}),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3304 d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3305 d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3306 d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3307 d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3308 d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3309 <<< Finished
3310 >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
3311 d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3312 d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3313 d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3314 <<< Finished
3315 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
3316 d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3317 d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3318 d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3319 <<< Finished
3320 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
3321 d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3322 d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3323 d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3324 <<< Finished
3325 >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
3326 d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3327 d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3328 <<< Finished
3329 >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
3330 d.update((("a", Mapping({"abcG" : None})),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3331 d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3332 d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3333 d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3334 d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3335 d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3336 <<< Finished
3337 >>> Testing *Iter* using d.update((("a", %s),))
3338 d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3339 d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3340 <<< Finished
3341 >>> Testing ConvertFromPyObject using d.update((("a", %s),))
3342 d.update((("a", None),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3343 d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3344 d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3345 d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3346 d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3347 d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3348 <<< Finished
3349 >> DictionaryPopItem
3350 d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
3351 >> DictionaryHasKey
3352 d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
3353 > List
3354 >> ListConstructor
3355 vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
3356 vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
3357 >>> Testing *Iter* using vim.List(%s)
3358 vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3359 vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3360 <<< Finished
3361 >>> Testing StringToChars using vim.List([{%s : 1}])
3362 vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3363 vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3364 vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3365 <<< Finished
3366 >>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
3367 vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3368 vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3369 vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3370 <<< Finished
3371 >>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
3372 vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3373 vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3374 vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3375 <<< Finished
3376 >>> Testing *Iter* using vim.List([{"abcF" : %s}])
3377 vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3378 vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3379 <<< Finished
3380 >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
3381 vim.List([{"abcF" : None}]):NOT FAILED
3382 vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3383 vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3384 vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3385 vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3386 vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3387 <<< Finished
3388 >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
3389 vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3390 vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3391 vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3392 <<< Finished
3393 >>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
3394 vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3395 vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3396 vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3397 <<< Finished
3398 >>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
3399 vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3400 vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3401 vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3402 <<< Finished
3403 >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
3404 vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3405 vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3406 <<< Finished
3407 >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
3408 vim.List([Mapping({"abcG" : None})]):NOT FAILED
3409 vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3410 vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3411 vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3412 vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3413 vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3414 <<< Finished
3415 >>> Testing *Iter* using vim.List([%s])
3416 vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3417 vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3418 <<< Finished
3419 >>> Testing ConvertFromPyObject using vim.List([%s])
3420 vim.List([None]):NOT FAILED
3421 vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3422 vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3423 vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3424 vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3425 vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3426 <<< Finished
3427 >> ListItem
3428 l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
3429 >> ListAssItem
3430 ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
3431 l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
3432 >> ListAssSlice
3433 ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
3434 >>> Testing *Iter* using l[:] = %s
3435 l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
3436 l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3437 <<< Finished
3438 nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 2 to extended slice',))
3439 (b'a', b'b', b'c', b'O')
3440 nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
3441 (b'a', b'b', b'c', b'O')
3442 nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 0 to extended slice',))
3443 (b'a', b'b', b'c', b'O')
3444 nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3445 (b'a', b'b', b'c', b'O')
3446 >>> Testing StringToChars using l[:] = [{%s : 1}]
3447 l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3448 l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3449 l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3450 <<< Finished
3451 >>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
3452 l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3453 l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3454 l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3455 <<< Finished
3456 >>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
3457 l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3458 l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3459 l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3460 <<< Finished
3461 >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
3462 l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3463 l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3464 <<< Finished
3465 >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
3466 l[:] = [{"abcF" : None}]:NOT FAILED
3467 l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3468 l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3469 l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3470 l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3471 l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3472 <<< Finished
3473 >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
3474 l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3475 l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3476 l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3477 <<< Finished
3478 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
3479 l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3480 l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3481 l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3482 <<< Finished
3483 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
3484 l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3485 l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3486 l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3487 <<< Finished
3488 >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
3489 l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3490 l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3491 <<< Finished
3492 >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
3493 l[:] = [Mapping({"abcG" : None})]:NOT FAILED
3494 l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3495 l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3496 l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3497 l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3498 l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3499 <<< Finished
3500 >>> Testing *Iter* using l[:] = [%s]
3501 l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3502 l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3503 <<< Finished
3504 >>> Testing ConvertFromPyObject using l[:] = [%s]
3505 l[:] = [None]:NOT FAILED
3506 l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3507 l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3508 l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3509 l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3510 l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3511 <<< Finished
3512 >> ListConcatInPlace
3513 >>> Testing *Iter* using l.extend(%s)
3514 l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3515 l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3516 <<< Finished
3517 >>> Testing StringToChars using l.extend([{%s : 1}])
3518 l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3519 l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3520 l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3521 <<< Finished
3522 >>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
3523 l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3524 l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3525 l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3526 <<< Finished
3527 >>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
3528 l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3529 l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3530 l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3531 <<< Finished
3532 >>> Testing *Iter* using l.extend([{"abcF" : %s}])
3533 l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3534 l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3535 <<< Finished
3536 >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
3537 l.extend([{"abcF" : None}]):NOT FAILED
3538 l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3539 l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3540 l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3541 l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3542 l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3543 <<< Finished
3544 >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
3545 l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3546 l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3547 l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3548 <<< Finished
3549 >>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
3550 l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3551 l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3552 l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3553 <<< Finished
3554 >>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
3555 l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3556 l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3557 l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3558 <<< Finished
3559 >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
3560 l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3561 l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3562 <<< Finished
3563 >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
3564 l.extend([Mapping({"abcG" : None})]):NOT FAILED
3565 l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3566 l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3567 l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3568 l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3569 l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3570 <<< Finished
3571 >>> Testing *Iter* using l.extend([%s])
3572 l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3573 l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3574 <<< Finished
3575 >>> Testing ConvertFromPyObject using l.extend([%s])
3576 l.extend([None]):NOT FAILED
3577 l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3578 l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3579 l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3580 l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3581 l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3582 <<< Finished
3583 >> ListSetattr
3584 del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
3585 l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3586 l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3587 > Function
3588 >> FunctionConstructor
3589 >>> FunctionConstructor
3590 vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
3591 vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
3592 vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
3593 vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
3594 vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
3595 vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
3596 >>> FunctionNew
3597 vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
3598 vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to a Vim list',))
3599 vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3600 vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3601 vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3602 vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3603 >> FunctionCall
3604 >>> Testing StringToChars using f({%s : 1})
3605 f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3606 f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3607 f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3608 <<< Finished
3609 >>> Testing StringToChars using f({"abcF" : {%s : 1}})
3610 f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3611 f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3612 f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3613 <<< Finished
3614 >>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
3615 f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3616 f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3617 f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3618 <<< Finished
3619 >>> Testing *Iter* using f({"abcF" : %s})
3620 f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3621 f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3622 <<< Finished
3623 >>> Testing ConvertFromPyObject using f({"abcF" : %s})
3624 f({"abcF" : None}):NOT FAILED
3625 f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3626 f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3627 f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3628 f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3629 f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3630 <<< Finished
3631 >>> Testing StringToChars using f(Mapping({%s : 1}))
3632 f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3633 f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3634 f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3635 <<< Finished
3636 >>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
3637 f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3638 f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3639 f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3640 <<< Finished
3641 >>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
3642 f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3643 f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3644 f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3645 <<< Finished
3646 >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
3647 f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3648 f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3649 <<< Finished
3650 >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
3651 f(Mapping({"abcG" : None})):NOT FAILED
3652 f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3653 f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3654 f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3655 f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3656 f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3657 <<< Finished
3658 >>> Testing *Iter* using f(%s)
3659 f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3660 f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3661 <<< Finished
3662 >>> Testing ConvertFromPyObject using f(%s)
3663 f(None):NOT FAILED
3664 f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3665 f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3666 f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3667 f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3668 f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
3669 <<< Finished
3670 >>> Testing StringToChars using fd(self={%s : 1})
3671 fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3672 fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3673 fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3674 <<< Finished
3675 >>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
3676 fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3677 fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3678 fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3679 <<< Finished
3680 >>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
3681 fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3682 fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3683 fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3684 <<< Finished
3685 >>> Testing *Iter* using fd(self={"abcF" : %s})
3686 fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3687 fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3688 <<< Finished
3689 >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
3690 fd(self={"abcF" : None}):NOT FAILED
3691 fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3692 fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3693 fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3694 fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3695 fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3696 <<< Finished
3697 >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
3698 fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3699 fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3700 fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3701 <<< Finished
3702 >>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
3703 fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3704 fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3705 fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3706 <<< Finished
3707 >>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
3708 fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3709 fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3710 fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3711 <<< Finished
3712 >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
3713 fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3714 fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3715 <<< Finished
3716 >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
3717 fd(self=Mapping({"abcG" : None})):NOT FAILED
3718 fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3719 fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3720 fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3721 fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3722 fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3723 <<< Finished
3724 >>> Testing *Iter* using fd(self=%s)
3725 fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim dictionary',))
3726 fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to a Vim dictionary',))
3727 <<< Finished
3728 >>> Testing ConvertFromPyObject using fd(self=%s)
3729 fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to a Vim dictionary',))
3730 fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3731 fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3732 fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3733 fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3734 fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to a Vim dictionary',))
3735 <<< Finished
3736 >>> Testing ConvertFromPyMapping using fd(self=%s)
3737 fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
3738 <<< Finished
3739 > TabPage
3740 >> TabPageAttr
3741 vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
3742 > TabList
3743 >> TabListItem
3744 vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
3745 > Window
3746 >> WindowAttr
3747 vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
3748 >> WindowSetattr
3749 vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
3750 vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
3751 vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
3752 >>> Testing NumberToLong using vim.current.window.height = %s
3753 vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3754 vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3755 vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3756 <<< Finished
3757 >>> Testing NumberToLong using vim.current.window.width = %s
3758 vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3759 vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3760 vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3761 <<< Finished
3762 vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
3763 > WinList
3764 >> WinListItem
3765 vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
3766 > Buffer
3767 >> StringToLine (indirect)
3768 vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3769 vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
3770 >> SetBufferLine (indirect)
3771 vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3772 >> SetBufferLineList (indirect)
3773 vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3774 vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
3775 >> InsertBufferLines (indirect)
3776 vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3777 vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
3778 vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
3779 >> RBItem
3780 vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
3781 >> RBAsItem
3782 vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
3783 >> BufferAttr
3784 vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
3785 >> BufferSetattr
3786 vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
3787 vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3788 >> BufferMark
3789 vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3790 vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
3791 vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
3792 >> BufferRange
3793 vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
3794 > BufMap
3795 >> BufMapItem
3796 vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
3797 >>> Testing NumberToLong using vim.buffers[%s]
3798 vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3799 vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3800 vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3801 vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
3802 <<< Finished
3803 > Current
3804 >> CurrentGetattr
3805 vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
3806 >> CurrentSetattr
3807 vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
3808 vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
3809 vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
3810 vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
3811 vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
3812 END
3813
3814 call assert_equal(expected, getline(2, '$'))
3815 close!
3816endfunc
3817
3818" Test import
3819func Test_python3_import()
3820 new
3821 py3 cb = vim.current.buffer
3822
3823 py3 << trim EOF
3824 sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
3825 sys.path.append(os.path.join(os.getcwd(), 'python_after'))
3826 vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
3827 l = []
3828 def callback(path):
3829 l.append(os.path.relpath(path))
3830 vim.foreach_rtp(callback)
3831 cb.append(repr(l))
3832 del l
3833 def callback(path):
3834 return os.path.relpath(path)
3835 cb.append(repr(vim.foreach_rtp(callback)))
3836 del callback
3837 from module import dir as d
3838 from modulex import ddir
3839 cb.append(d + ',' + ddir)
3840 import before
3841 cb.append(before.dir)
3842 import after
3843 cb.append(after.dir)
3844 import topmodule as tm
3845 import topmodule.submodule as tms
3846 import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
3847 cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
3848 cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
3849 cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
3850
3851 del before
3852 del after
3853 del d
3854 del ddir
3855 del tm
3856 del tms
3857 del tmsss
3858 EOF
3859
3860 let expected =<< trim END
3861 ['.']
3862 '.'
3863 3,xx
3864 before
3865 after
3866 pythonx/topmodule/__init__.py
3867 pythonx/topmodule/submodule/__init__.py
3868 pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
3869 END
3870 call assert_equal(expected, getline(2, '$'))
3871 close!
Bram Moolenaarab589462020-07-06 21:03:06 +02003872
3873 " Try to import a non-existing moudle with a dot (.)
3874 call AssertException(['py3 import a.b.c'], "No module named 'a'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02003875endfunc
3876
3877" Test exceptions
3878func Test_python3_exception()
3879 func Exe(e)
3880 execute a:e
3881 endfunc
3882
3883 new
3884 py3 cb = vim.current.buffer
3885
3886 py3 << trim EOF
3887 Exe = vim.bindeval('function("Exe")')
3888 ee('vim.command("throw \'abcN\'")')
3889 ee('Exe("throw \'def\'")')
3890 ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
3891 ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
3892 ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
3893 ee('vim.eval("xxx_unknown_function_xxx()")')
3894 ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
3895 del Exe
3896 EOF
3897 delfunction Exe
3898
3899 let expected =<< trim END
3900 vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
3901 Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
3902 vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
3903 vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
3904 vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
3905 vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
3906 vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
3907 END
3908 call assert_equal(expected, getline(2, '$'))
3909 close!
3910endfunc
3911
3912" Regression: interrupting vim.command propagates to next vim.command
3913func Test_python3_keyboard_interrupt()
3914 new
3915 py3 cb = vim.current.buffer
3916 py3 << trim EOF
3917 def test_keyboard_interrupt():
3918 try:
3919 vim.command('while 1 | endwhile')
3920 except KeyboardInterrupt:
3921 cb.append('Caught KeyboardInterrupt')
3922 except Exception:
3923 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
3924 else:
3925 cb.append('!!!!!!!! No exception')
3926 try:
3927 vim.command('$ put =\'Running :put\'')
3928 except KeyboardInterrupt:
3929 cb.append('!!!!!!!! Caught KeyboardInterrupt')
3930 except Exception:
3931 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
3932 else:
3933 cb.append('No exception')
3934 EOF
3935
3936 debuggreedy
3937 call inputsave()
3938 call feedkeys("s\ns\ns\ns\nq\n")
3939 redir => output
3940 debug silent! py3 test_keyboard_interrupt()
3941 redir END
3942 0 debuggreedy
3943 call inputrestore()
3944 py3 del test_keyboard_interrupt
3945
3946 let expected =<< trim END
3947 Caught KeyboardInterrupt
3948 Running :put
3949 No exception
3950 END
3951 call assert_equal(expected, getline(2, '$'))
3952 call assert_equal('', output)
3953 close!
3954endfunc
3955
Bram Moolenaar423a85a2020-08-29 12:57:16 +02003956" Regression: Iterator for a Vim object should hold a reference.
3957func Test_python3_iter_ref()
3958 let g:list_iter_ref_count_increase = -1
3959 let g:dict_iter_ref_count_increase = -1
3960 let g:bufmap_iter_ref_count_increase = -1
3961 let g:options_iter_ref_count_increase = -1
3962
3963 py3 << trim EOF
3964 import sys
3965 import vim
3966
3967 def test_python3_iter_ref():
3968 create_list = vim.Function('Create_vim_list')
3969 v = create_list()
3970 base_ref_count = sys.getrefcount(v)
3971 for el in v:
3972 vim.vars['list_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
3973
3974 create_dict = vim.Function('Create_vim_dict')
3975 v = create_dict()
3976 base_ref_count = sys.getrefcount(v)
3977 for el in v:
3978 vim.vars['dict_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
3979
3980 v = vim.buffers
3981 base_ref_count = sys.getrefcount(v)
3982 for el in v:
3983 vim.vars['bufmap_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
3984
3985 v = vim.options
3986 base_ref_count = sys.getrefcount(v)
3987 for el in v:
3988 vim.vars['options_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
3989
3990 test_python3_iter_ref()
3991 EOF
3992
3993 call assert_equal(1, g:list_iter_ref_count_increase)
3994 call assert_equal(1, g:dict_iter_ref_count_increase)
3995 call assert_equal(1, g:bufmap_iter_ref_count_increase)
3996 call assert_equal(1, g:options_iter_ref_count_increase)
3997endfunc
3998
Bram Moolenaar1363a302020-04-12 13:50:26 +02003999" vim: shiftwidth=2 sts=2 expandtab