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