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