blob: bd000ef05adabb095aab2ffb1a8525ad7faedf1e [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 +02003CheckFeature python3
Bram Moolenaara58883b2017-01-29 21:31:09 +01004
Bram Moolenaar423a85a2020-08-29 12:57:16 +02005func Create_vim_list()
6 return [1]
7endfunction
8
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01009func Create_vim_tuple()
10 return ('a', 'b')
11endfunction
12
Bram Moolenaar423a85a2020-08-29 12:57:16 +020013func Create_vim_dict()
14 return {'a': 1}
15endfunction
16
Zdenek Dohnaledd7a472021-10-06 19:39:16 +010017let s:system_error_pat = 'Vim(py3):SystemError: \(<built-in function eval> returned NULL without setting an \(error\|exception\)\|error return without exception set\)'
Bram Moolenaar423a85a2020-08-29 12:57:16 +020018
Bram Moolenaareffb0cd2020-07-03 21:17:34 +020019" This function should be called first. This sets up python functions used by
20" the other tests.
21func Test_AAA_python3_setup()
22 py3 << trim EOF
23 import vim
24 import sys
25 import re
26
Zdenek Dohnal288bf262023-08-11 23:32:23 +020027 py33_type_error_pattern = re.compile(r'^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +020028 py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
Zdenek Dohnal288bf262023-08-11 23:32:23 +020029 py39_type_error_pattern = re.compile(r'\w+\.([^(]+\(\) takes)')
30 py310_type_error_pattern = re.compile(r'takes (\d+) positional argument but (\d+) were given')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +020031
32 def emsg(ei):
33 return ei[0].__name__ + ':' + repr(ei[1].args)
34
35 def ee(expr, g=globals(), l=locals()):
36 cb = vim.current.buffer
37 try:
38 try:
39 exec(expr, g, l)
40 except Exception as e:
41 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."):
42 msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
43 elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
44 msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
45 elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
46 # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
47 msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
48 elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
49 m = py33_type_error_pattern.search(str(e))
50 if m:
51 msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
52 msg = repr((e.__class__, TypeError(msg)))
53 else:
54 msg = repr((e.__class__, e))
55 # Messages changed with Python 3.6, change new to old.
56 newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
57 oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
58 if msg.find(newmsg1) > -1:
59 msg = msg.replace(newmsg1, oldmsg1)
60 newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
61 oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
62 if msg.find(newmsg2) > -1:
63 msg = msg.replace(newmsg2, oldmsg2)
Bram Moolenaar68a48ee2020-10-27 19:59:10 +010064 # Python 3.9 reports errors like "vim.command() takes ..." instead of "command() takes ..."
65 msg = py39_type_error_pattern.sub(r'\1', msg)
K.Takata1be7e212021-11-16 13:08:56 +000066 msg = py310_type_error_pattern.sub(r'takes exactly \1 positional argument (\2 given)', msg)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +020067 elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
68 msg = repr((TypeError, TypeError('expected bytes with no null')))
69 else:
70 msg = repr((e.__class__, e))
71 # Some Python versions say can't, others cannot.
72 if msg.find('can\'t') > -1:
73 msg = msg.replace('can\'t', 'cannot')
74 # Some Python versions use single quote, some double quote
75 if msg.find('"cannot ') > -1:
76 msg = msg.replace('"cannot ', '\'cannot ')
77 if msg.find(' attributes"') > -1:
78 msg = msg.replace(' attributes"', ' attributes\'')
79 if sys.version_info >= (3, 7):
80 msg = py37_exception_repr.sub(r'\1,\2', msg)
81 cb.append(expr + ':' + msg)
82 else:
83 cb.append(expr + ':NOT FAILED')
84 except Exception as e:
85 msg = repr((e.__class__, e))
86 if sys.version_info >= (3, 7):
87 msg = py37_exception_repr.sub(r'\1,\2', msg)
88 cb.append(expr + '::' + msg)
89 EOF
90endfunc
91
Bram Moolenaara58883b2017-01-29 21:31:09 +010092func Test_py3do()
Bram Moolenaara58883b2017-01-29 21:31:09 +010093 new
zeertzjqe99f0682024-01-29 19:32:39 +010094
95 " Check deleting lines does not trigger an ml_get error.
Bram Moolenaara58883b2017-01-29 21:31:09 +010096 call setline(1, ['one', 'two', 'three'])
97 py3do vim.command("%d_")
zeertzjqe99f0682024-01-29 19:32:39 +010098 call assert_equal([''], getline(1, '$'))
99
100 call setline(1, ['one', 'two', 'three'])
101 py3do vim.command("1,2d_")
102 call assert_equal(['three'], getline(1, '$'))
103
104 call setline(1, ['one', 'two', 'three'])
105 py3do vim.command("2,3d_"); return "REPLACED"
106 call assert_equal(['REPLACED'], getline(1, '$'))
107
108 call setline(1, ['one', 'two', 'three'])
109 2,3py3do vim.command("1,2d_"); return "REPLACED"
110 call assert_equal(['three'], getline(1, '$'))
111
Bram Moolenaara58883b2017-01-29 21:31:09 +0100112 bwipe!
113
114 " Check switching to another buffer does not trigger an ml_get error.
115 new
116 let wincount = winnr('$')
117 call setline(1, ['one', 'two', 'three'])
118 py3do vim.command("new")
119 call assert_equal(wincount + 1, winnr('$'))
120 bwipe!
121 bwipe!
Bram Moolenaarab589462020-07-06 21:03:06 +0200122
123 " Try modifying a buffer with 'nomodifiable' set
124 set nomodifiable
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200125 call assert_fails('py3do toupper(line)', 'E21:')
Bram Moolenaarab589462020-07-06 21:03:06 +0200126 set modifiable
127
128 " Invalid command
129 call AssertException(['py3do non_existing_cmd'],
130 \ "Vim(py3do):NameError: name 'non_existing_cmd' is not defined")
131 call AssertException(["py3do raise Exception('test')"],
132 \ 'Vim(py3do):Exception: test')
133 call AssertException(["py3do {lambda}"],
134 \ 'Vim(py3do):SyntaxError: invalid syntax')
Bram Moolenaara58883b2017-01-29 21:31:09 +0100135endfunc
Bram Moolenaar53901442018-07-25 22:02:36 +0200136
137func Test_set_cursor()
138 " Check that setting the cursor position works.
Bram Moolenaar53901442018-07-25 22:02:36 +0200139 new
140 call setline(1, ['first line', 'second line'])
141 normal gg
142 py3do vim.current.window.cursor = (1, 5)
143 call assert_equal([1, 6], [line('.'), col('.')])
144
145 " Check that movement after setting cursor position keeps current column.
146 normal j
147 call assert_equal([2, 6], [line('.'), col('.')])
148endfunc
Bram Moolenaar9123c0b2018-12-22 18:59:06 +0100149
150func Test_vim_function()
151 " Check creating vim.Function object
Bram Moolenaar9123c0b2018-12-22 18:59:06 +0100152
153 func s:foo()
154 return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
155 endfunc
156 let name = '<SNR>' . s:foo()
157
158 try
159 py3 f = vim.bindeval('function("s:foo")')
160 call assert_equal(name, py3eval('f.name'))
161 catch
162 call assert_false(v:exception)
163 endtry
164
165 try
166 py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
Bram Moolenaar3f4f3d82019-09-04 20:05:59 +0200167 call assert_equal(name, 'f.name'->py3eval())
Bram Moolenaar9123c0b2018-12-22 18:59:06 +0100168 catch
169 call assert_false(v:exception)
170 endtry
171
Bram Moolenaarab589462020-07-06 21:03:06 +0200172 " Non-existing function attribute
173 call AssertException(["let x = py3eval('f.abc')"],
174 \ "Vim(let):AttributeError: 'vim.function' object has no attribute 'abc'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200175
Bram Moolenaar9123c0b2018-12-22 18:59:06 +0100176 py3 del f
177 delfunc s:foo
178endfunc
Bram Moolenaar14816ad2019-02-18 22:04:56 +0100179
180func Test_skipped_python3_command_does_not_affect_pyxversion()
181 set pyxversion=0
182 if 0
183 python3 import vim
184 endif
185 call assert_equal(0, &pyxversion) " This assertion would have failed with Vim 8.0.0251. (pyxversion was introduced in 8.0.0251.)
186endfunc
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100187
188func _SetUpHiddenBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100189 new
190 edit hidden
191 setlocal bufhidden=hide
192
193 enew
194 let lnum = 0
195 while lnum < 10
196 call append( 1, string( lnum ) )
197 let lnum = lnum + 1
198 endwhile
199 normal G
200
201 call assert_equal( line( '.' ), 11 )
202endfunc
203
Bram Moolenaarbfd36032019-03-30 12:33:13 +0100204func _CleanUpHiddenBuffer()
205 bwipe! hidden
206 bwipe!
207endfunc
208
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100209func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Clear()
210 call _SetUpHiddenBuffer()
211 py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = None
212 call assert_equal( line( '.' ), 11 )
Bram Moolenaarbfd36032019-03-30 12:33:13 +0100213 call _CleanUpHiddenBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100214endfunc
215
216func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_List()
217 call _SetUpHiddenBuffer()
218 py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][:] = [ 'test' ]
219 call assert_equal( line( '.' ), 11 )
Bram Moolenaarbfd36032019-03-30 12:33:13 +0100220 call _CleanUpHiddenBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100221endfunc
222
223func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_Str()
224 call _SetUpHiddenBuffer()
225 py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = 'test'
226 call assert_equal( line( '.' ), 11 )
Bram Moolenaarbfd36032019-03-30 12:33:13 +0100227 call _CleanUpHiddenBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100228endfunc
229
230func Test_Write_To_HiddenBuffer_Does_Not_Fix_Cursor_ClearLine()
231 call _SetUpHiddenBuffer()
232 py3 vim.buffers[ int( vim.eval( 'bufnr("hidden")' ) ) ][0] = None
233 call assert_equal( line( '.' ), 11 )
Bram Moolenaarbfd36032019-03-30 12:33:13 +0100234 call _CleanUpHiddenBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100235endfunc
236
237func _SetUpVisibleBuffer()
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100238 new
239 let lnum = 0
240 while lnum < 10
241 call append( 1, string( lnum ) )
242 let lnum = lnum + 1
243 endwhile
244 normal G
245 call assert_equal( line( '.' ), 11 )
246endfunc
247
248func Test_Write_To_Current_Buffer_Fixes_Cursor_Clear()
249 call _SetUpVisibleBuffer()
250
251 py3 vim.current.buffer[:] = None
252 call assert_equal( line( '.' ), 1 )
253
254 bwipe!
255endfunc
256
257func Test_Write_To_Current_Buffer_Fixes_Cursor_List()
258 call _SetUpVisibleBuffer()
259
260 py3 vim.current.buffer[:] = [ 'test' ]
261 call assert_equal( line( '.' ), 1 )
262
263 bwipe!
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200264endfunc
Bram Moolenaar63dbfd32019-03-23 17:41:59 +0100265
266func Test_Write_To_Current_Buffer_Fixes_Cursor_Str()
267 call _SetUpVisibleBuffer()
268
269 py3 vim.current.buffer[-1] = None
270 call assert_equal( line( '.' ), 10 )
271
272 bwipe!
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200273endfunc
Bram Moolenaar7f3a2842019-05-18 15:02:25 +0200274
275func Test_Catch_Exception_Message()
276 try
277 py3 raise RuntimeError( 'TEST' )
278 catch /.*/
279 call assert_match( '^Vim(.*):RuntimeError: TEST$', v:exception )
280 endtry
281endfunc
Bram Moolenaar556684f2019-12-31 21:59:01 +0100282
283func Test_unicode()
284 " this crashed Vim once
Bram Moolenaar2466aea2020-01-01 17:09:11 +0100285 if &tenc != ''
286 throw "Skipped: 'termencoding' is not empty"
287 endif
Bram Moolenaar4b7cdca2020-01-01 16:18:38 +0100288
Bram Moolenaar556684f2019-12-31 21:59:01 +0100289 set encoding=utf32
290 py3 print('hello')
Bram Moolenaar4b7cdca2020-01-01 16:18:38 +0100291
Bram Moolenaar955f4e62020-01-01 17:44:56 +0100292 if !has('win32')
293 set encoding=debug
294 py3 print('hello')
Bram Moolenaar4b7cdca2020-01-01 16:18:38 +0100295
Bram Moolenaar7fc47852020-01-02 16:38:07 +0100296 set encoding=euc-tw
297 py3 print('hello')
298 endif
Bram Moolenaar4b7cdca2020-01-01 16:18:38 +0100299
Bram Moolenaar556684f2019-12-31 21:59:01 +0100300 set encoding=utf8
301endfunc
Bram Moolenaar904edab2020-01-19 13:57:54 +0100302
Bram Moolenaar026270c2020-02-23 15:10:16 +0100303" Test vim.eval() with various types.
zeertzjq50732c72024-11-09 18:30:10 +0100304func Test_python3_vim_eval()
Bram Moolenaar026270c2020-02-23 15:10:16 +0100305 call assert_equal("\n8", execute('py3 print(vim.eval("3+5"))'))
Bram Moolenaar73e28dc2022-09-17 21:08:33 +0100306 call assert_equal("\n3.140000", execute('py3 print(vim.eval("1.01+2.13"))'))
307 call assert_equal("\n0.000000", execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
308 call assert_equal("\n0.000000", execute('py3 print(vim.eval("0.0/(1.0/0.0)"))'))
309 call assert_equal("\n-0.000000", execute('py3 print(vim.eval("0.0/(-1.0/0.0)"))'))
310 " Commented out: output of infinity and nan depend on platforms.
311 " call assert_equal("\ninf", execute('py3 print(vim.eval("1.0/0.0"))'))
312 " call assert_equal("\n-inf", execute('py3 print(vim.eval("-1.0/0.0"))'))
313 " call assert_equal("\n-nan", execute('py3 print(vim.eval("0.0/0.0"))'))
Bram Moolenaar026270c2020-02-23 15:10:16 +0100314 call assert_equal("\nabc", execute('py3 print(vim.eval("\"abc\""))'))
315 call assert_equal("\n['1', '2']", execute('py3 print(vim.eval("[1, 2]"))'))
316 call assert_equal("\n{'1': '2'}", execute('py3 print(vim.eval("{1:2}"))'))
317 call assert_equal("\nTrue", execute('py3 print(vim.eval("v:true"))'))
318 call assert_equal("\nFalse", execute('py3 print(vim.eval("v:false"))'))
319 call assert_equal("\nNone", execute('py3 print(vim.eval("v:null"))'))
320 call assert_equal("\nNone", execute('py3 print(vim.eval("v:none"))'))
321 call assert_equal("\nb'\\xab\\x12'", execute('py3 print(vim.eval("0zab12"))'))
322
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200323 call assert_fails('py3 vim.eval("1+")', 'E15: Invalid expression')
Bram Moolenaar026270c2020-02-23 15:10:16 +0100324endfunc
325
Bram Moolenaar904edab2020-01-19 13:57:54 +0100326" Test range objects, see :help python-range
Bram Moolenaar50985eb2020-01-27 22:09:39 +0100327func Test_python3_range()
Bram Moolenaar904edab2020-01-19 13:57:54 +0100328 new
329 py3 b = vim.current.buffer
330
331 call setline(1, range(1, 6))
332 py3 r = b.range(2, 4)
333 call assert_equal(6, py3eval('len(b)'))
334 call assert_equal(3, py3eval('len(r)'))
335 call assert_equal('3', py3eval('b[2]'))
336 call assert_equal('4', py3eval('r[2]'))
337
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200338 call assert_fails('py3 r[3] = "x"', ['Traceback', 'IndexError: line number out of range'])
339 call assert_fails('py3 x = r[3]', ['Traceback', 'IndexError: line number out of range'])
340 call assert_fails('py3 r["a"] = "x"', ['Traceback', 'TypeError: index must be int or slice, not str'])
341 call assert_fails('py3 x = r["a"]', ['Traceback', 'TypeError: index must be int or slice, not str'])
Bram Moolenaar904edab2020-01-19 13:57:54 +0100342
343 py3 del r[:]
344 call assert_equal(['1', '5', '6'], getline(1, '$'))
345
346 %d | call setline(1, range(1, 6))
347 py3 r = b.range(2, 5)
348 py3 del r[2]
349 call assert_equal(['1', '2', '3', '5', '6'], getline(1, '$'))
350
351 %d | call setline(1, range(1, 6))
352 py3 r = b.range(2, 4)
353 py3 vim.command("%d,%dnorm Ax" % (r.start + 1, r.end + 1))
354 call assert_equal(['1', '2x', '3x', '4x', '5', '6'], getline(1, '$'))
355
356 %d | call setline(1, range(1, 4))
357 py3 r = b.range(2, 3)
358 py3 r.append(['a', 'b'])
359 call assert_equal(['1', '2', '3', 'a', 'b', '4'], getline(1, '$'))
360 py3 r.append(['c', 'd'], 0)
361 call assert_equal(['1', 'c', 'd', '2', '3', 'a', 'b', '4'], getline(1, '$'))
362
363 %d | call setline(1, range(1, 5))
364 py3 r = b.range(2, 4)
365 py3 r.append('a')
366 call assert_equal(['1', '2', '3', '4', 'a', '5'], getline(1, '$'))
367 py3 r.append('b', 1)
368 call assert_equal(['1', '2', 'b', '3', '4', 'a', '5'], getline(1, '$'))
369
370 bwipe!
371endfunc
Bram Moolenaar1363a302020-04-12 13:50:26 +0200372
373" Test for resetting options with local values to global values
374func Test_python3_opt_reset_local_to_global()
375 new
376
377 py3 curbuf = vim.current.buffer
378 py3 curwin = vim.current.window
379
380 " List of buffer-local options. Each list item has [option name, global
381 " value, buffer-local value, buffer-local value after reset] to use in the
382 " test.
383 let bopts = [
384 \ ['autoread', 1, 0, -1],
385 \ ['equalprg', 'geprg', 'leprg', ''],
386 \ ['keywordprg', 'gkprg', 'lkprg', ''],
387 \ ['path', 'gpath', 'lpath', ''],
388 \ ['backupcopy', 'yes', 'no', ''],
389 \ ['tags', 'gtags', 'ltags', ''],
390 \ ['tagcase', 'ignore', 'match', ''],
391 \ ['define', 'gdef', 'ldef', ''],
392 \ ['include', 'ginc', 'linc', ''],
393 \ ['dict', 'gdict', 'ldict', ''],
394 \ ['thesaurus', 'gtsr', 'ltsr', ''],
Yegappan Lakshmanan5284b232023-03-04 19:57:32 +0000395 \ ['thesaurusfunc', 'Gtsrfu', 'Ltsrfu', ''],
Bram Moolenaar1363a302020-04-12 13:50:26 +0200396 \ ['formatprg', 'gfprg', 'lfprg', ''],
397 \ ['errorformat', '%f:%l:%m', '%s-%l-%m', ''],
398 \ ['grepprg', 'ggprg', 'lgprg', ''],
399 \ ['makeprg', 'gmprg', 'lmprg', ''],
Bram Moolenaar1363a302020-04-12 13:50:26 +0200400 \ ['cryptmethod', 'blowfish2', 'zip', ''],
401 \ ['lispwords', 'abc', 'xyz', ''],
402 \ ['makeencoding', 'utf-8', 'latin1', ''],
403 \ ['undolevels', 100, 200, -123456]]
Bram Moolenaarddf53122022-05-27 20:23:20 +0100404 if has('balloon_eval')
405 call add(bopts, ['balloonexpr', 'gbexpr', 'lbexpr', ''])
406 endif
Bram Moolenaar1363a302020-04-12 13:50:26 +0200407
408 " Set the global and buffer-local option values and then clear the
409 " buffer-local option value.
410 for opt in bopts
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200411 py3 << trim END
412 pyopt = vim.bindeval("opt")
413 vim.options[pyopt[0]] = pyopt[1]
414 curbuf.options[pyopt[0]] = pyopt[2]
415 END
Bram Moolenaar1363a302020-04-12 13:50:26 +0200416 exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
417 exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
418 exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
419 py3 del curbuf.options[pyopt[0]]
420 exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
421 exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
422 exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
423 exe "set " .. opt[0] .. "&"
424 endfor
425
426 " Set the global and window-local option values and then clear the
427 " window-local option value.
428 let wopts = [
Yegappan Lakshmanan5284b232023-03-04 19:57:32 +0000429 \ ['fillchars', 'fold:>', 'fold:+', ''],
430 \ ['listchars', 'tab:>>', 'tab:--', ''],
Bram Moolenaar1363a302020-04-12 13:50:26 +0200431 \ ['scrolloff', 5, 10, -1],
Yegappan Lakshmanan5284b232023-03-04 19:57:32 +0000432 \ ['showbreak', '>>', '++', ''],
Bram Moolenaar1363a302020-04-12 13:50:26 +0200433 \ ['sidescrolloff', 6, 12, -1],
Yegappan Lakshmanan5284b232023-03-04 19:57:32 +0000434 \ ['statusline', '%<%f', '%<%F', ''],
435 \ ['virtualedit', 'block', 'insert', '']]
Bram Moolenaar1363a302020-04-12 13:50:26 +0200436 for opt in wopts
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200437 py3 << trim
438 pyopt = vim.bindeval("opt")
439 vim.options[pyopt[0]] = pyopt[1]
440 curwin.options[pyopt[0]] = pyopt[2]
441 .
Bram Moolenaar1363a302020-04-12 13:50:26 +0200442 exe "call assert_equal(opt[2], &" .. opt[0] .. ")"
443 exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
444 exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")"
445 py3 del curwin.options[pyopt[0]]
446 exe "call assert_equal(opt[1], &" .. opt[0] .. ")"
447 exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")"
448 exe "call assert_equal(opt[3], &l:" .. opt[0] .. ")"
449 exe "set " .. opt[0] .. "&"
450 endfor
451
452 close!
453endfunc
454
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200455" Test for various heredoc syntax
456func Test_python3_heredoc()
457 python3 << END
458s='A'
459END
460 python3 <<
461s+='B'
462.
463 python3 << trim END
464 s+='C'
465 END
466 python3 << trim
467 s+='D'
468 .
Bram Moolenaar6ab09532020-05-01 14:10:13 +0200469 python3 << trim eof
470 s+='E'
471 eof
zeertzjq449c2e52025-02-03 18:56:16 +0100472 python3 << trimm
473s+='F'
474trimm
475 call assert_equal('ABCDEF', pyxeval('s'))
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200476endfunc
477
Bram Moolenaarab589462020-07-06 21:03:06 +0200478" Test for the buffer range object
479func Test_python3_range2()
480 new
481 call setline(1, ['one', 'two', 'three'])
482 py3 b = vim.current.buffer
483 py3 r = b.range(1, 3)
484 call assert_equal(0, py3eval('r.start'))
485 call assert_equal(2, py3eval('r.end'))
486 call assert_equal('one', py3eval('r[0]'))
487 call assert_equal('one', py3eval('r[-3]'))
488 call AssertException(["let x = py3eval('r[-4]')"],
489 \ 'Vim(let):IndexError: line number out of range')
490 call assert_equal(['two', 'three'], py3eval('r[1:]'))
491 py3 r[0] = 'green'
492 call assert_equal(['green', 'two', 'three'], getline(1, '$'))
493 py3 r[0:2] = ['red', 'blue']
494 call assert_equal(['red', 'blue', 'three'], getline(1, '$'))
495
496 " try different invalid start/end index for the range slice
497 %d
498 call setline(1, ['one', 'two', 'three'])
499 py3 r[-10:1] = ["a"]
500 py3 r[10:12] = ["b"]
501 py3 r[-10:-9] = ["c"]
502 py3 r[1:0] = ["d"]
503 call assert_equal(['c', 'd', 'a', 'two', 'three', 'b'], getline(1, '$'))
504
Bram Moolenaarbb790dc2020-07-07 20:12:54 +0200505 " The following code used to trigger an ml_get error
506 %d
507 let x = py3eval('r[:]')
Bram Moolenaarab589462020-07-06 21:03:06 +0200508
509 " Non-existing range attribute
510 call AssertException(["let x = py3eval('r.abc')"],
511 \ "Vim(let):AttributeError: 'vim.range' object has no attribute 'abc'")
512
513 close!
514endfunc
515
516" Test for the python tabpage object
517func Test_python3_tabpage()
518 tabnew
519 py3 t = vim.tabpages[1]
520 py3 wl = t.windows
521 tabclose
522 " Accessing a closed tabpage
523 call AssertException(["let n = py3eval('t.number')"],
524 \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
525 call AssertException(["let n = py3eval('len(wl)')"],
526 \ 'Vim(let):vim.error: attempt to refer to deleted tab page')
527 call AssertException(["py3 w = wl[0]"],
528 \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
529 call AssertException(["py3 vim.current.tabpage = t"],
530 \ 'Vim(py3):vim.error: attempt to refer to deleted tab page')
531 call assert_match('<tabpage object (deleted)', py3eval('repr(t)'))
532 %bw!
533endfunc
534
535" Test for the python window object
536func Test_python3_window()
537 " Test for setting the window height
538 10new
539 py3 vim.current.window.height = 5
540 call assert_equal(5, winheight(0))
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +0200541 py3 vim.current.window.height = 3.2
542 call assert_equal(3, winheight(0))
Bram Moolenaarab589462020-07-06 21:03:06 +0200543
544 " Test for setting the window width
545 10vnew
546 py3 vim.current.window.width = 6
547 call assert_equal(6, winwidth(0))
548
549 " Try accessing a closed window
550 py3 w = vim.current.window
551 py3 wopts = w.options
552 close
553 " Access the attributes of a closed window
554 call AssertException(["let n = py3eval('w.number')"],
555 \ 'Vim(let):vim.error: attempt to refer to deleted window')
556 call AssertException(["py3 w.height = 5"],
557 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
558 call AssertException(["py3 vim.current.window = w"],
559 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
560 " Try to set one of the options of the closed window
Bram Moolenaarbb790dc2020-07-07 20:12:54 +0200561 " The following caused ASAN failure
562 call AssertException(["py3 wopts['list'] = False"],
563 \ 'Vim(py3):vim.error: attempt to refer to deleted window')
Bram Moolenaarab589462020-07-06 21:03:06 +0200564 call assert_match('<window object (deleted)', py3eval("repr(w)"))
565 %bw!
566endfunc
567
Bram Moolenaar6c87bbb2022-12-10 11:17:11 +0000568" This was causing trouble because "curbuf" was not matching curwin->w_buffer
569func Test_python3_window_set_height()
570 enew!
571 call setline(1, ['aaa', 'bbb', 'ccc'])
572 call cursor(2, 1)
573 set foldmethod=expr
574 new
575 wincmd w
576 python3 vim.windows[0].height = 5
577 call assert_equal(5, winheight(1))
578
579 call feedkeys('j', 'xt')
580 call assert_equal(3, getpos('.')[1])
581
582 bwipe!
583 bwipe!
584endfunc
585
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200586" Test for the python List object
587func Test_python3_list()
Bram Moolenaarab589462020-07-06 21:03:06 +0200588 " Try to convert a null List
589 call AssertException(["py3 t = vim.eval('test_null_list()')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100590 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200591
592 " Try to convert a List with a null List item
593 call AssertException(["py3 t = vim.eval('[test_null_list()]')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100594 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200595
Bram Moolenaar64ffa9b2020-11-04 12:23:06 +0100596 " Try to bind a null List variable (works because an empty list is used)
Bram Moolenaarab589462020-07-06 21:03:06 +0200597 let cmds =<< trim END
598 let l = test_null_list()
599 py3 ll = vim.bindeval('l')
600 END
Bram Moolenaar64ffa9b2020-11-04 12:23:06 +0100601 call AssertException(cmds, '')
Bram Moolenaarab589462020-07-06 21:03:06 +0200602
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200603 let l = []
604 py3 l = vim.bindeval('l')
605 py3 f = vim.bindeval('function("strlen")')
606 " Extending List directly with different types
607 py3 l += [1, "as'd", [1, 2, f, {'a': 1}]]
608 call assert_equal([1, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
609 call assert_equal([1, 2, function("strlen"), {'a': 1}], l[-1])
610 call assert_fails('echo l[-4]', 'E684:')
611
612 " List assignment
613 py3 l[0] = 0
614 call assert_equal([0, "as'd", [1, 2, function("strlen"), {'a': 1}]], l)
615 py3 l[-2] = f
616 call assert_equal([0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]], l)
Bram Moolenaarab589462020-07-06 21:03:06 +0200617
618 " appending to a list
619 let l = [1, 2]
620 py3 ll = vim.bindeval('l')
621 py3 ll[2] = 8
622 call assert_equal([1, 2, 8], l)
623
Bram Moolenaar21578272021-02-21 19:12:47 +0100624 " iterating over list from Python
625 py3 print([x for x in vim.Function("getline")(1, 2)])
626
Bram Moolenaarab589462020-07-06 21:03:06 +0200627 " Using dict as an index
628 call AssertException(['py3 ll[{}] = 10'],
629 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
630endfunc
631
Yegappan Lakshmanan038be272025-03-26 18:46:21 +0100632" Test for the python Tuple object
633func Test_python3_tuple()
634 " Try to convert a null tuple
635 call AssertException(["py3 l = vim.eval('test_null_tuple()')"],
636 \ s:system_error_pat)
637
638 " Try to convert a Tuple with a null Tuple item
639 call AssertException(["py3 t = vim.eval('(test_null_tuple(),)')"],
640 \ s:system_error_pat)
641
642 " Try to convert a List with a null Tuple item
643 call AssertException(["py3 t = vim.eval('[test_null_tuple()]')"],
644 \ s:system_error_pat)
645
646 " Try to convert a Tuple with a null List item
647 call AssertException(["py3 t = vim.eval('(test_null_list(),)')"],
648 \ s:system_error_pat)
649
650 " Try to bind a null Tuple variable (works because an empty tuple is used)
651 let cmds =<< trim END
652 let t = test_null_tuple()
653 py3 tt = vim.bindeval('t')
654 END
655 call AssertException(cmds, '')
656
657 " Creating a tuple using different iterators
658 py3 t1 = vim.Tuple(['abc', 20, 1.2, (4, 5)])
659 call assert_equal(('abc', 20, 1.2, (4, 5)), py3eval('t1'))
660 py3 t2 = vim.Tuple('abc')
661 call assert_equal(('a', 'b', 'c'), py3eval('t2'))
662 py3 t3 = vim.Tuple({'color': 'red', 'model': 'ford'})
663 call assert_equal(('color', 'model'), py3eval('t3'))
664 py3 t4 = vim.Tuple()
665 call assert_equal((), py3eval('t4'))
666 py3 t5 = vim.Tuple(x**2 for x in range(5))
667 call assert_equal((0, 1, 4, 9, 16), py3eval('t5'))
668 py3 t6 = vim.Tuple(('abc', 20, 1.2, (4, 5)))
669 call assert_equal(('abc', 20, 1.2, (4, 5)), py3eval('t6'))
670
671 " Convert between Vim tuple/list and python tuple/list
672 py3 t = vim.Tuple(vim.bindeval("('a', ('b',), ['c'], {'s': 'd'})"))
673 call assert_equal(('a', ('b',), ['c'], {'s': 'd'}), py3eval('t'))
674 call assert_equal(['a', ('b',), ['c'], {'s': 'd'}], py3eval('list(t)'))
675 call assert_equal(('a', ('b',), ['c'], {'s': 'd'}), py3eval('tuple(t)'))
676
677 py3 l = vim.List(vim.bindeval("['e', ('f',), ['g'], {'s': 'h'}]"))
678 call assert_equal(('e', ('f',), ['g'], {'s': 'h'}), py3eval('tuple(l)'))
679
680 " Tuple assignment
681 py3 tt = vim.bindeval('("a", "b")')
682 call AssertException(['py3 tt[0] = 10'],
683 \ "Vim(py3):TypeError: 'vim.tuple' object does not support item assignment")
684 py3 tt = vim.bindeval('("a", "b")')
685 call AssertException(['py3 tt[0:1] = (10, 20)'],
686 \ "Vim(py3):TypeError: 'vim.tuple' object does not support item assignment")
687
688 " iterating over tuple from Python
689 py3 print([x for x in vim.bindeval("('a', 'b')")])
690
691 " modifying a list item within a tuple
692 let t = ('a', ['b', 'c'], 'd')
693 py3 vim.bindeval('t')[1][1] = 'x'
694 call assert_equal(('a', ['b', 'x'], 'd'), t)
695
696 " length of a tuple
697 let t = ()
698 py3 p_t = vim.bindeval('t')
699 call assert_equal(0, py3eval('len(p_t)'))
700 let t = ('a', )
701 py3 p_t = vim.bindeval('t')
702 call assert_equal(1, py3eval('len(p_t)'))
703 let t = ('a', 'b', 'c')
704 py3 p_t = vim.bindeval('t')
705 call assert_equal(3, py3eval('len(p_t)'))
706
707 " membership test
708 let t = ('a', 'b', 'c')
709 py3 p_t = vim.bindeval('t')
710 call assert_true(py3eval("b'c' in p_t"))
711 call assert_true(py3eval("b'd' not in p_t"))
712
713 py3 x = vim.eval('("a", (2), [3], {})')
714 call assert_equal(('a', '2', ['3'], {}), py3eval('x'))
715
716 " Using a keyword argument for a tuple
717 call AssertException(['py3 x = vim.Tuple(a=1)'],
718 \ 'Vim(py3):TypeError: tuple constructor does not accept keyword arguments')
719
720 " Using dict as an index
721 call AssertException(['py3 x = tt[{}]'],
722 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
723 call AssertException(['py3 x = tt["abc"]'],
724 \ 'Vim(py3):TypeError: index must be int or slice, not str')
725
726 call AssertException(['py3 del tt.locked'],
727 \ 'Vim(py3):AttributeError: cannot delete vim.Tuple attributes')
728
729 call AssertException(['py3 tt.foobar = 1'],
730 \ 'Vim(py3):AttributeError: cannot set attribute foobar')
731endfunc
732
Bram Moolenaarab589462020-07-06 21:03:06 +0200733" Test for the python Dict object
734func Test_python3_dict()
735 " Try to convert a null Dict
736 call AssertException(["py3 t = vim.eval('test_null_dict()')"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100737 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200738
739 " Try to convert a Dict with a null List value
740 call AssertException(["py3 t = vim.eval(\"{'a' : test_null_list()}\")"],
Bram Moolenaar07761a32020-12-22 12:50:10 +0100741 \ s:system_error_pat)
Bram Moolenaarab589462020-07-06 21:03:06 +0200742
743 " Try to convert a Dict with a null string key
744 py3 t = vim.eval("{test_null_string() : 10}")
745 call assert_fails("let d = py3eval('t')", 'E859:')
746
747 " Dict length
748 let d = {'a' : 10, 'b' : 20}
749 py3 d = vim.bindeval('d')
750 call assert_equal(2, py3eval('len(d)'))
751
Dominique Pelle923dce22021-11-21 11:36:04 +0000752 " Deleting a non-existing key
Bram Moolenaarab589462020-07-06 21:03:06 +0200753 call AssertException(["py3 del d['c']"], "Vim(py3):KeyError: 'c'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200754endfunc
755
756" Extending Dictionary directly with different types
757func Test_python3_dict_extend()
758 let d = {}
759 func d.f()
760 return 1
761 endfunc
762
763 py3 f = vim.bindeval('function("strlen")')
764 py3 << trim EOF
765 d = vim.bindeval('d')
766 d['1'] = 'asd'
767 d.update() # Must not do anything, including throwing errors
768 d.update(b = [1, 2, f])
769 d.update((('-1', {'a': 1}),))
770 d.update({'0': -1})
771 dk = d.keys()
772 dv = d.values()
773 di = d.items()
774 dk.sort(key=repr)
775 dv.sort(key=repr)
776 di.sort(key=repr)
777 EOF
778
Bram Moolenaarab589462020-07-06 21:03:06 +0200779 " Try extending a locked dictionary
780 lockvar d
781 call AssertException(["py3 d.update({'b' : 20})"],
782 \ 'Vim(py3):vim.error: dictionary is locked')
783 unlockvar d
784
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200785 call assert_equal(1, py3eval("d['f'](self={})"))
786 call assert_equal("[b'-1', b'0', b'1', b'b', b'f']", py3eval('repr(dk)'))
787 call assert_equal("[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd']", substitute(py3eval('repr(dv)'),'0x\x\+','','g'))
788 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'))
789 call assert_equal(['0', '1', 'b', 'f', '-1'], keys(d))
790 call assert_equal("[-1, 'asd', [1, 2, function('strlen')], function('1'), {'a': 1}]", string(values(d)))
791 py3 del dk
792 py3 del di
793 py3 del dv
794endfunc
795
796func Test_python3_list_del_items()
797 " removing items with del
798 let l = [0, function("strlen"), [1, 2, function("strlen"), {'a': 1}]]
799 py3 l = vim.bindeval('l')
800 py3 del l[2]
801 call assert_equal("[0, function('strlen')]", string(l))
802
803 let l = range(8)
804 py3 l = vim.bindeval('l')
805 py3 del l[:3]
806 py3 del l[1:]
807 call assert_equal([3], l)
808
809 " removing items out of range: silently skip items that don't exist
810
811 " The following two ranges delete nothing as they match empty list:
812 let l = [0, 1, 2, 3]
813 py3 l = vim.bindeval('l')
814 py3 del l[2:1]
815 call assert_equal([0, 1, 2, 3], l)
816 py3 del l[2:2]
817 call assert_equal([0, 1, 2, 3], l)
818 py3 del l[2:3]
819 call assert_equal([0, 1, 3], l)
820
821 let l = [0, 1, 2, 3]
822 py3 l = vim.bindeval('l')
823 py3 del l[2:4]
824 call assert_equal([0, 1], l)
825
826 let l = [0, 1, 2, 3]
827 py3 l = vim.bindeval('l')
828 py3 del l[2:5]
829 call assert_equal([0, 1], l)
830
831 let l = [0, 1, 2, 3]
832 py3 l = vim.bindeval('l')
833 py3 del l[2:6]
834 call assert_equal([0, 1], l)
835
836 " The following two ranges delete nothing as they match empty list:
837 let l = [0, 1, 2, 3]
838 py3 l = vim.bindeval('l')
839 py3 del l[-1:2]
840 call assert_equal([0, 1, 2, 3], l)
841 py3 del l[-2:2]
842 call assert_equal([0, 1, 2, 3], l)
843 py3 del l[-3:2]
844 call assert_equal([0, 2, 3], l)
845
846 let l = [0, 1, 2, 3]
847 py3 l = vim.bindeval('l')
848 py3 del l[-4:2]
849 call assert_equal([2, 3], l)
850
851 let l = [0, 1, 2, 3]
852 py3 l = vim.bindeval('l')
853 py3 del l[-5:2]
854 call assert_equal([2, 3], l)
855
856 let l = [0, 1, 2, 3]
857 py3 l = vim.bindeval('l')
858 py3 del l[-6:2]
859 call assert_equal([2, 3], l)
860
861 let l = [0, 1, 2, 3]
862 py3 l = vim.bindeval('l')
863 py3 del l[::2]
864 call assert_equal([1, 3], l)
865
866 let l = [0, 1, 2, 3]
867 py3 l = vim.bindeval('l')
868 py3 del l[3:0:-2]
869 call assert_equal([0, 2], l)
870
871 let l = [0, 1, 2, 3]
872 py3 l = vim.bindeval('l')
873 py3 del l[2:4:-2]
874 let l = [0, 1, 2, 3]
875endfunc
876
877func Test_python3_dict_del_items()
878 let d = eval("{'0' : -1, '1' : 'asd', 'b' : [1, 2, function('strlen')], 'f' : function('min'), '-1' : {'a': 1}}")
879 py3 d = vim.bindeval('d')
880 py3 del d['-1']
881 py3 del d['f']
882 call assert_equal([1, 2, function('strlen')], py3eval('d.get(''b'', 1)'))
883 call assert_equal([1, 2, function('strlen')], py3eval('d.pop(''b'')'))
884 call assert_equal(1, py3eval('d.get(''b'', 1)'))
885 call assert_equal('asd', py3eval('d.pop(''1'', 2)'))
886 call assert_equal(2, py3eval('d.pop(''1'', 2)'))
887 call assert_equal('True', py3eval('repr(d.has_key(''0''))'))
888 call assert_equal('False', py3eval('repr(d.has_key(''1''))'))
889 call assert_equal('True', py3eval('repr(''0'' in d)'))
890 call assert_equal('False', py3eval('repr(''1'' in d)'))
891 call assert_equal("[b'0']", py3eval('repr(list(iter(d)))'))
892 call assert_equal({'0' : -1}, d)
893 call assert_equal("(b'0', -1)", py3eval('repr(d.popitem())'))
894 call assert_equal('None', py3eval('repr(d.get(''0''))'))
895 call assert_equal('[]', py3eval('repr(list(iter(d)))'))
896endfunc
897
898" Slice assignment to a list
899func Test_python3_slice_assignment()
900 let l = [0, 1, 2, 3]
901 py3 l = vim.bindeval('l')
902 py3 l[0:0] = ['a']
903 call assert_equal(['a', 0, 1, 2, 3], l)
904
905 let l = [0, 1, 2, 3]
906 py3 l = vim.bindeval('l')
907 py3 l[1:2] = ['b']
908 call assert_equal([0, 'b', 2, 3], l)
909
910 let l = [0, 1, 2, 3]
911 py3 l = vim.bindeval('l')
912 py3 l[2:4] = ['c']
913 call assert_equal([0, 1, 'c'], l)
914
915 let l = [0, 1, 2, 3]
916 py3 l = vim.bindeval('l')
917 py3 l[4:4] = ['d']
918 call assert_equal([0, 1, 2, 3, 'd'], l)
919
920 let l = [0, 1, 2, 3]
921 py3 l = vim.bindeval('l')
922 py3 l[-1:2] = ['e']
923 call assert_equal([0, 1, 2, 'e', 3], l)
924
925 let l = [0, 1, 2, 3]
926 py3 l = vim.bindeval('l')
927 py3 l[-10:2] = ['f']
928 call assert_equal(['f', 2, 3], l)
929
930 let l = [0, 1, 2, 3]
931 py3 l = vim.bindeval('l')
932 py3 l[2:-10] = ['g']
933 call assert_equal([0, 1, 'g', 2, 3], l)
934
935 let l = []
936 py3 l = vim.bindeval('l')
937 py3 l[0:0] = ['h']
938 call assert_equal(['h'], l)
939
940 let l = range(8)
941 py3 l = vim.bindeval('l')
942 py3 l[2:6:2] = [10, 20]
943 call assert_equal([0, 1, 10, 3, 20, 5, 6, 7], l)
944
945 let l = range(8)
946 py3 l = vim.bindeval('l')
947 py3 l[6:2:-2] = [10, 20]
948 call assert_equal([0, 1, 2, 3, 20, 5, 10, 7], l)
949
950 let l = range(8)
951 py3 l = vim.bindeval('l')
952 py3 l[6:2] = ()
953 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
954
955 let l = range(8)
956 py3 l = vim.bindeval('l')
957 py3 l[6:2:1] = ()
958 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
959
960 let l = range(8)
961 py3 l = vim.bindeval('l')
962 py3 l[2:2:1] = ()
963 call assert_equal([0, 1, 2, 3, 4, 5, 6, 7], l)
Bram Moolenaar0ab55d62020-07-07 20:50:39 +0200964
965 call AssertException(["py3 x = l[10:11:0]"],
966 \ "Vim(py3):ValueError: slice step cannot be zero")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200967endfunc
968
969" Locked variables
970func Test_python3_lockedvar()
971 new
972 py3 cb = vim.current.buffer
973 let l = [0, 1, 2, 3]
974 py3 l = vim.bindeval('l')
975 lockvar! l
976 py3 << trim EOF
977 try:
978 l[2]='i'
979 except vim.error:
980 cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
981 EOF
982 call assert_equal(['', "l[2] threw vim.error: error:('list is locked',)"],
983 \ getline(1, '$'))
Bram Moolenaarab589462020-07-06 21:03:06 +0200984
985 " Try to concatenate a locked list
986 call AssertException(['py3 l += [4, 5]'], 'Vim(py3):vim.error: list is locked')
987
Bram Moolenaareffb0cd2020-07-03 21:17:34 +0200988 call assert_equal([0, 1, 2, 3], l)
989 unlockvar! l
990 close!
991endfunc
992
993" Test for calling a function
994func Test_python3_function_call()
995 func New(...)
996 return ['NewStart'] + a:000 + ['NewEnd']
997 endfunc
998
999 func DictNew(...) dict
1000 return ['DictNewStart'] + a:000 + ['DictNewEnd', self]
1001 endfunc
1002
1003 new
1004 let l = [function('New'), function('DictNew')]
1005 py3 l = vim.bindeval('l')
1006 py3 l.extend(list(l[0](1, 2, 3)))
1007 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'], l)
1008 py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
1009 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}], l)
1010 py3 l += [[l[0].name]]
1011 call assert_equal([function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, ['New']], l)
1012 py3 ee('l[1](1, 2, 3)')
1013 call assert_equal("l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',))", getline(2))
1014 %d
1015 py3 f = l[0]
1016 delfunction New
1017 py3 ee('f(1, 2, 3)')
1018 call assert_equal("f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',))", getline(2))
1019 close!
1020 delfunction DictNew
1021endfunc
1022
1023func Test_python3_float()
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001024 let l = [0.0]
1025 py3 l = vim.bindeval('l')
1026 py3 l.extend([0.0])
1027 call assert_equal([0.0, 0.0], l)
1028endfunc
1029
1030" Test for Dict key errors
1031func Test_python3_dict_key_error()
1032 let messages = []
1033 py3 << trim EOF
1034 import sys
1035 d = vim.bindeval('{}')
1036 m = vim.bindeval('messages')
1037 def em(expr, g=globals(), l=locals()):
1038 try:
1039 exec(expr, g, l)
1040 except Exception as e:
1041 if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
1042 m.extend([TypeError.__name__])
1043 else:
1044 m.extend([e.__class__.__name__])
1045
1046 em('d["abc1"]')
1047 em('d["abc1"]="\\0"')
1048 em('d["abc1"]=vim')
1049 em('d[""]=1')
1050 em('d["a\\0b"]=1')
1051 em('d[b"a\\0b"]=1')
1052 em('d.pop("abc1")')
1053 em('d.popitem()')
1054 del em
1055 del m
1056 EOF
1057
1058 call assert_equal(['KeyError', 'TypeError', 'TypeError', 'ValueError',
1059 \ 'TypeError', 'TypeError', 'KeyError', 'KeyError'], messages)
1060 unlet messages
1061endfunc
1062
1063" Test for locked and scope attributes
1064func Test_python3_lock_scope_attr()
1065 let d = {} | let dl = {} | lockvar dl
1066 let res = []
1067 for s in split("d dl v: g:")
1068 let name = tr(s, ':', 's')
1069 execute 'py3 ' .. name .. ' = vim.bindeval("' .. s .. '")'
1070 call add(res, s .. ' : ' .. join(map(['locked', 'scope'],
1071 \ 'v:val .. ":" .. py3eval(name .. "." .. v:val)'), ';'))
1072 endfor
1073 call assert_equal(['d : locked:0;scope:0', 'dl : locked:1;scope:0',
1074 \ 'v: : locked:2;scope:1', 'g: : locked:0;scope:2'], res)
1075
1076 silent! let d.abc2 = 1
1077 silent! let dl.abc3 = 1
1078 py3 d.locked = True
1079 py3 dl.locked = False
1080 silent! let d.def = 1
1081 silent! let dl.def = 1
1082 call assert_equal({'abc2': 1}, d)
1083 call assert_equal({'def': 1}, dl)
1084 unlet d dl
1085
1086 let l = [] | let ll = [] | lockvar ll
1087 let res = []
1088 for s in split("l ll")
1089 let name = tr(s, ':', 's')
1090 execute 'py3 ' .. name .. '=vim.bindeval("' .. s .. '")'
1091 call add(res, s .. ' : locked:' .. py3eval(name .. '.locked'))
1092 endfor
1093 call assert_equal(['l : locked:0', 'll : locked:1'], res)
1094
1095 silent! call extend(l, [0])
1096 silent! call extend(ll, [0])
1097 py3 l.locked = True
1098 py3 ll.locked = False
1099 silent! call extend(l, [1])
1100 silent! call extend(ll, [1])
1101 call assert_equal([0], l)
1102 call assert_equal([1], ll)
1103 unlet l ll
Bram Moolenaarab589462020-07-06 21:03:06 +02001104
1105 " Try changing an attribute of a fixed list
1106 py3 a = vim.bindeval('v:argv')
1107 call AssertException(['py3 a.locked = 0'],
1108 \ 'Vim(py3):TypeError: cannot modify fixed list')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001109endfunc
1110
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001111" Test for locking/unlocking a tuple
1112func Test_tuple_lock()
1113 let t = (1, 2, 3)
1114 py3 t = vim.bindeval('t')
1115 py3 t.locked = True
1116 call assert_equal(1, islocked('t'))
1117 py3 t.locked = False
1118 call assert_equal(0, islocked('t'))
1119endfunc
1120
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001121" Test for py3eval()
1122func Test_python3_pyeval()
1123 let l = py3eval('[0, 1, 2]')
1124 call assert_equal([0, 1, 2], l)
1125
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001126 let t = py3eval('("a", "b", "c")')
1127 call assert_equal(("a", "b", "c"), t)
1128
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001129 let d = py3eval('{"a": "b", "c": 1, "d": ["e"]}')
1130 call assert_equal([['a', 'b'], ['c', 1], ['d', ['e']]], sort(items(d)))
1131
1132 let v:errmsg = ''
1133 call assert_equal(v:none, py3eval('None'))
1134 call assert_equal('', v:errmsg)
1135
Bram Moolenaarab589462020-07-06 21:03:06 +02001136 py3 v = vim.eval('test_null_function()')
1137 call assert_equal(v:none, py3eval('v'))
1138
Bram Moolenaar73e28dc2022-09-17 21:08:33 +01001139 call assert_equal(0.0, py3eval('0.0'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001140
Bram Moolenaarab589462020-07-06 21:03:06 +02001141 " Evaluate an invalid values
1142 call AssertException(['let v = py3eval(''"\0"'')'], 'E859:')
1143 call AssertException(['let v = py3eval(''{"\0" : 1}'')'], 'E859:')
1144 call AssertException(['let v = py3eval("undefined_name")'],
1145 \ "Vim(let):NameError: name 'undefined_name' is not defined")
1146 call AssertException(['let v = py3eval("vim")'], 'E859:')
1147endfunc
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001148
Ben Jacksonea19e782024-11-06 21:50:05 +01001149" Test for py3eval with locals
1150func Test_python3_pyeval_locals()
1151 let str = 'a string'
1152 let num = 0xbadb33f
1153 let d = {'a': 1, 'b': 2, 'c': str}
1154 let l = [ str, num, d ]
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001155 let t = ( str, num, d )
Ben Jacksonea19e782024-11-06 21:50:05 +01001156
1157 let locals = #{
1158 \ s: str,
1159 \ n: num,
1160 \ d: d,
1161 \ l: l,
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001162 \ t: t,
Ben Jacksonea19e782024-11-06 21:50:05 +01001163 \ }
1164
1165 " check basics
1166 call assert_equal('a string', py3eval('s', locals))
1167 call assert_equal(0xbadb33f, py3eval('n', locals))
1168 call assert_equal(d, py3eval('d', locals))
1169 call assert_equal(l, py3eval('l', locals))
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001170 call assert_equal(t, py3eval('t', locals))
Ben Jacksonea19e782024-11-06 21:50:05 +01001171 call assert_equal('a,b,c', py3eval('b",".join(l)', {'l': ['a', 'b', 'c']}))
1172 call assert_equal('hello', 's'->py3eval({'s': 'hello'}))
1173 call assert_equal('a,b,c', 'b",".join(l)'->py3eval({'l': ['a', 'b', 'c']}))
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001174 call assert_equal('a-b-c', 'b"-".join(t)'->py3eval({'t': ('a', 'b', 'c')}))
Ben Jacksonea19e782024-11-06 21:50:05 +01001175
1176 py3 << trim EOF
1177 def __UpdateDict(d, upd):
1178 d.update(upd)
1179 return d
1180
1181 def __ExtendList(l, *args):
1182 l.extend(*args)
1183 return l
1184 EOF
1185
1186 " check assign to dict member works like bindeval
1187 call assert_equal(3, py3eval('__UpdateDict( d, {"c": 3} )["c"]', locals))
1188 call assert_equal(3, d['c'])
1189
1190 " check append lo list
1191 call assert_equal(4, py3eval('len(__ExtendList(l, ["new item"]))', locals))
1192 call assert_equal("new item", l[-1])
1193
1194 " check calling a function
1195 let StrLen = function('strlen')
1196 call assert_equal(3, py3eval('f("abc")', {'f': StrLen}))
1197endfunc
1198
Bram Moolenaarab589462020-07-06 21:03:06 +02001199" Test for vim.bindeval()
1200func Test_python3_vim_bindeval()
1201 " Float
1202 let f = 3.14
1203 py3 f = vim.bindeval('f')
1204 call assert_equal(3.14, py3eval('f'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001205
Bram Moolenaarab589462020-07-06 21:03:06 +02001206 " Blob
1207 let b = 0z12
1208 py3 b = vim.bindeval('b')
1209 call assert_equal("\x12", py3eval('b'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001210
Bram Moolenaarab589462020-07-06 21:03:06 +02001211 " Bool
1212 call assert_equal(1, py3eval("vim.bindeval('v:true')"))
1213 call assert_equal(0, py3eval("vim.bindeval('v:false')"))
1214 call assert_equal(v:none, py3eval("vim.bindeval('v:null')"))
1215 call assert_equal(v:none, py3eval("vim.bindeval('v:none')"))
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02001216
1217 " channel/job
Dominique Pelle56c9fd02021-05-19 00:16:14 +02001218 if has('channel')
1219 call assert_equal(v:none, py3eval("vim.bindeval('test_null_channel()')"))
1220 endif
1221 if has('job')
1222 call assert_equal(v:none, py3eval("vim.bindeval('test_null_job()')"))
1223 endif
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001224endfunc
1225
1226" threading
1227" Running py3do command (Test_pydo) before this test, stops the python thread
1228" from running. So this test should be run before the pydo test
Bram Moolenaarab589462020-07-06 21:03:06 +02001229func Test_aaa_python3_threading()
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001230 let l = [0]
1231 py3 l = vim.bindeval('l')
1232 py3 << trim EOF
1233 import threading
1234 import time
1235
1236 class T(threading.Thread):
1237 def __init__(self):
1238 threading.Thread.__init__(self)
1239 self.t = 0
1240 self.running = True
1241
1242 def run(self):
1243 while self.running:
1244 self.t += 1
1245 time.sleep(0.1)
1246
1247 t = T()
1248 del T
1249 t.start()
1250 EOF
1251
1252 sleep 1
1253 py3 t.running = False
1254 py3 t.join()
1255
1256 " Check if the background thread is working. Count should be 10, but on a
1257 " busy system (AppVeyor) it can be much lower.
1258 py3 l[0] = t.t > 4
1259 py3 del time
1260 py3 del threading
1261 py3 del t
1262 call assert_equal([1], l)
1263endfunc
1264
1265" settrace
1266func Test_python3_settrace()
1267 let l = []
1268 py3 l = vim.bindeval('l')
1269 py3 << trim EOF
1270 import sys
1271
1272 def traceit(frame, event, arg):
1273 global l
1274 if event == "line":
1275 l += [frame.f_lineno]
1276 return traceit
1277
1278 def trace_main():
1279 for i in range(5):
1280 pass
1281 EOF
1282 py3 sys.settrace(traceit)
1283 py3 trace_main()
1284 py3 sys.settrace(None)
1285 py3 del traceit
1286 py3 del trace_main
1287 call assert_equal([1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1], l)
1288endfunc
1289
1290" Slice
1291func Test_python3_list_slice()
1292 py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
1293 py3 l = ll[:4]
1294 call assert_equal([0, 1, 2, 3], py3eval('l'))
1295 py3 l = ll[2:]
1296 call assert_equal([2, 3, 4, 5], py3eval('l'))
1297 py3 l = ll[:-4]
1298 call assert_equal([0, 1], py3eval('l'))
1299 py3 l = ll[-2:]
1300 call assert_equal([4, 5], py3eval('l'))
1301 py3 l = ll[2:4]
1302 call assert_equal([2, 3], py3eval('l'))
1303 py3 l = ll[4:2]
1304 call assert_equal([], py3eval('l'))
1305 py3 l = ll[-4:-2]
1306 call assert_equal([2, 3], py3eval('l'))
1307 py3 l = ll[-2:-4]
1308 call assert_equal([], py3eval('l'))
1309 py3 l = ll[:]
1310 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1311 py3 l = ll[0:6]
1312 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1313 py3 l = ll[-10:10]
1314 call assert_equal([0, 1, 2, 3, 4, 5], py3eval('l'))
1315 py3 l = ll[4:2:-1]
1316 call assert_equal([4, 3], py3eval('l'))
1317 py3 l = ll[::2]
1318 call assert_equal([0, 2, 4], py3eval('l'))
1319 py3 l = ll[4:2:1]
1320 call assert_equal([], py3eval('l'))
Bram Moolenaarab589462020-07-06 21:03:06 +02001321
1322 " Error case: Use an invalid index
1323 call AssertException(['py3 ll[-10] = 5'], 'Vim(py3):vim.error: internal error:')
1324
1325 " Use a step value of 0
1326 call AssertException(['py3 ll[0:3:0] = [1, 2, 3]'],
1327 \ 'Vim(py3):ValueError: slice step cannot be zero')
1328
1329 " Error case: Invalid slice type
1330 call AssertException(["py3 x = ll['abc']"],
1331 \ "Vim(py3):TypeError: index must be int or slice, not str")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001332 py3 del l
Bram Moolenaarab589462020-07-06 21:03:06 +02001333
1334 " Error case: List with a null list item
1335 let l = [test_null_list()]
1336 py3 ll = vim.bindeval('l')
1337 call AssertException(["py3 x = ll[:]"],
Bram Moolenaar07761a32020-12-22 12:50:10 +01001338 \ s:system_error_pat)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001339endfunc
1340
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01001341" Slice
1342func Test_python3_tuple_slice()
1343 py3 tt = vim.bindeval('(0, 1, 2, 3, 4, 5)')
1344 py3 t = tt[:4]
1345 call assert_equal((0, 1, 2, 3), py3eval('t'))
1346 py3 t = tt[2:]
1347 call assert_equal((2, 3, 4, 5), py3eval('t'))
1348 py3 t = tt[:-4]
1349 call assert_equal((0, 1), py3eval('t'))
1350 py3 t = tt[-2:]
1351 call assert_equal((4, 5), py3eval('t'))
1352 py3 t = tt[2:4]
1353 call assert_equal((2, 3), py3eval('t'))
1354 py3 t = tt[4:2]
1355 call assert_equal((), py3eval('t'))
1356 py3 t = tt[-4:-2]
1357 call assert_equal((2, 3), py3eval('t'))
1358 py3 t = tt[-2:-4]
1359 call assert_equal((), py3eval('t'))
1360 py3 t = tt[:]
1361 call assert_equal((0, 1, 2, 3, 4, 5), py3eval('t'))
1362 py3 t = tt[0:6]
1363 call assert_equal((0, 1, 2, 3, 4, 5), py3eval('t'))
1364 py3 t = tt[-10:10]
1365 call assert_equal((0, 1, 2, 3, 4, 5), py3eval('t'))
1366 py3 t = tt[4:2:-1]
1367 call assert_equal((4, 3), py3eval('t'))
1368 py3 t = tt[::2]
1369 call assert_equal((0, 2, 4), py3eval('t'))
1370 py3 t = tt[4:2:1]
1371 call assert_equal((), py3eval('t'))
1372
1373 " Error case: Use an invalid index
1374 call AssertException(['py3 x = tt[-10]'], 'Vim(py3):IndexError: tuple index out of range')
1375
1376 " Use a step value of 0
1377 call AssertException(['py3 x = tt[0:3:0]'],
1378 \ 'Vim(py3):ValueError: slice step cannot be zero')
1379
1380 " Error case: Invalid slice type
1381 call AssertException(["py3 x = tt['abc']"],
1382 \ "Vim(py3):TypeError: index must be int or slice, not str")
1383
1384 " Error case: List with a null tuple item
1385 let t = (test_null_tuple(),)
1386 py3 tt = vim.bindeval('t')
1387 call AssertException(["py3 x = tt[:]"], s:system_error_pat)
1388endfunc
1389
1390func Test_python3_pytuple_to_vimtuple()
1391 let t = py3eval("('a', 'b')")
1392 call assert_equal(('a', 'b'), t)
1393 let t = py3eval("()")
1394 call assert_equal((), t)
1395 let t = py3eval("('x',)")
1396 call assert_equal(('x',), t)
1397 let t = py3eval("((1, 2), (), (3, 4))")
1398 call assert_equal(((1, 2), (), (3, 4)), t)
1399 let t = py3eval("((1, 2), {'a': 10}, [5, 6])")
1400 call assert_equal(((1, 2), {'a': 10}, [5, 6]), t)
1401
1402 " Invalid python tuple
1403 py3 << trim END
1404 class FailingIter(object):
1405 def __iter__(self):
1406 raise NotImplementedError('iter')
1407 END
1408 call assert_fails('call py3eval("(1, FailingIter, 2)")',
1409 \ 'E859: Failed to convert returned python object to a Vim value')
1410
1411 py3 del FailingIter
1412endfunc
1413
1414" Test for tuple garbage collection
1415func Test_python3_tuple_garbage_collect()
1416 let t = (1, (2, 3), [4, 5], {'a': 6})
1417 py3 py_t = vim.bindeval('t')
1418 let save_testing = v:testing
1419 let v:testing = 1
1420 call test_garbagecollect_now()
1421 let v:testing = save_testing
1422
1423 let new_t = py3eval('py_t')
1424 call assert_equal((1, (2, 3), [4, 5], {'a': 6}), new_t)
1425endfunc
1426
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001427" Vars
1428func Test_python3_vars()
1429 let g:foo = 'bac'
1430 let w:abc3 = 'def'
1431 let b:baz = 'bar'
1432 let t:bar = 'jkl'
1433 try
1434 throw "Abc"
1435 catch /Abc/
1436 call assert_equal('Abc', py3eval('vim.vvars[''exception'']'))
1437 endtry
1438 call assert_equal('bac', py3eval('vim.vars[''foo'']'))
1439 call assert_equal('def', py3eval('vim.current.window.vars[''abc3'']'))
1440 call assert_equal('bar', py3eval('vim.current.buffer.vars[''baz'']'))
1441 call assert_equal('jkl', py3eval('vim.current.tabpage.vars[''bar'']'))
1442endfunc
1443
1444" Options
1445" paste: boolean, global
1446" previewheight number, global
1447" operatorfunc: string, global
1448" number: boolean, window-local
1449" numberwidth: number, window-local
1450" colorcolumn: string, window-local
1451" statusline: string, window-local/global
1452" autoindent: boolean, buffer-local
1453" shiftwidth: number, buffer-local
1454" omnifunc: string, buffer-local
1455" preserveindent: boolean, buffer-local/global
1456" path: string, buffer-local/global
1457func Test_python3_opts()
1458 let g:res = []
1459 let g:bufs = [bufnr('%')]
1460 new
1461 let g:bufs += [bufnr('%')]
1462 vnew
1463 let g:bufs += [bufnr('%')]
1464 wincmd j
1465 vnew
1466 let g:bufs += [bufnr('%')]
1467 wincmd l
1468
1469 func RecVars(opt)
1470 let gval = string(eval('&g:' .. a:opt))
1471 let wvals = join(map(range(1, 4),
1472 \ 'v:val .. ":" .. string(getwinvar(v:val, "&" .. a:opt))'))
1473 let bvals = join(map(copy(g:bufs),
1474 \ 'v:val .. ":" .. string(getbufvar(v:val, "&" .. a:opt))'))
1475 call add(g:res, ' G: ' .. gval)
1476 call add(g:res, ' W: ' .. wvals)
1477 call add(g:res, ' B: ' .. wvals)
1478 endfunc
1479
1480 py3 << trim EOF
1481 def e(s, g=globals(), l=locals()):
1482 try:
1483 exec(s, g, l)
1484 except Exception as e:
1485 vim.command('return ' + repr(e.__class__.__name__))
1486
1487 def ev(s, g=globals(), l=locals()):
1488 try:
1489 return eval(s, g, l)
1490 except Exception as e:
1491 vim.command('let exc=' + repr(e.__class__.__name__))
1492 return 0
1493 EOF
1494
1495 func E(s)
1496 python3 e(vim.eval('a:s'))
1497 endfunc
1498
1499 func Ev(s)
1500 let r = py3eval('ev(vim.eval("a:s"))')
1501 if exists('exc')
1502 throw exc
1503 endif
1504 return r
1505 endfunc
1506
1507 py3 gopts1 = vim.options
1508 py3 wopts1 = vim.windows[2].options
1509 py3 wopts2 = vim.windows[0].options
1510 py3 wopts3 = vim.windows[1].options
1511 py3 bopts1 = vim.buffers[vim.bindeval("g:bufs")[2]].options
1512 py3 bopts2 = vim.buffers[vim.bindeval("g:bufs")[1]].options
1513 py3 bopts3 = vim.buffers[vim.bindeval("g:bufs")[0]].options
1514 call add(g:res, 'wopts iters equal: ' ..
1515 \ py3eval('list(wopts1) == list(wopts2)'))
1516 call add(g:res, 'bopts iters equal: ' ..
1517 \ py3eval('list(bopts1) == list(bopts2)'))
1518 py3 gset = set(iter(gopts1))
1519 py3 wset = set(iter(wopts1))
1520 py3 bset = set(iter(bopts1))
1521
1522 set path=.,..,,
1523 let lst = []
1524 let lst += [['paste', 1, 0, 1, 2, 1, 1, 0]]
1525 let lst += [['previewheight', 5, 1, 6, 'a', 0, 1, 0]]
1526 let lst += [['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0]]
1527 let lst += [['number', 0, 1, 1, 0, 1, 0, 1]]
1528 let lst += [['numberwidth', 2, 3, 5, -100, 0, 0, 1]]
1529 let lst += [['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1]]
1530 let lst += [['statusline', '1', '2', '4', 0, 0, 1, 1]]
1531 let lst += [['autoindent', 0, 1, 1, 2, 1, 0, 2]]
1532 let lst += [['shiftwidth', 0, 2, 1, 3, 0, 0, 2]]
1533 let lst += [['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2]]
1534 let lst += [['preserveindent', 0, 1, 1, 2, 1, 1, 2]]
1535 let lst += [['path', '.,,', ',,', '.', 0, 0, 1, 2]]
1536 for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
1537 py3 oname = vim.eval('oname')
1538 py3 oval1 = vim.bindeval('oval1')
1539 py3 oval2 = vim.bindeval('oval2')
1540 py3 oval3 = vim.bindeval('oval3')
1541 if invval is 0 || invval is 1
1542 py3 invval = bool(vim.bindeval('invval'))
1543 else
1544 py3 invval = vim.bindeval('invval')
1545 endif
1546 if bool
1547 py3 oval1 = bool(oval1)
1548 py3 oval2 = bool(oval2)
1549 py3 oval3 = bool(oval3)
1550 endif
1551 call add(g:res, '>>> ' .. oname)
1552 call add(g:res, ' g/w/b:' .. py3eval('oname in gset') .. '/' ..
1553 \ py3eval('oname in wset') .. '/' .. py3eval('oname in bset'))
1554 call add(g:res, ' g/w/b (in):' .. py3eval('oname in gopts1') .. '/' ..
1555 \ py3eval('oname in wopts1') .. '/' .. py3eval('oname in bopts1'))
1556 for v in ['gopts1', 'wopts1', 'bopts1']
1557 try
1558 call add(g:res, ' p/' .. v .. ': ' .. Ev('repr(' .. v .. '[''' .. oname .. '''])'))
1559 catch
1560 call add(g:res, ' p/' .. v .. '! ' .. v:exception)
1561 endtry
1562 let r = E(v .. '[''' .. oname .. ''']=invval')
1563 if r isnot 0
1564 call add(g:res, ' inv: ' .. string(invval) .. '! ' .. r)
1565 endif
1566 for vv in (v is# 'gopts1' ? [v] : [v, v[:-2] .. '2', v[:-2] .. '3'])
1567 let val = substitute(vv, '^.opts', 'oval', '')
1568 let r = E(vv .. '[''' .. oname .. ''']=' .. val)
1569 if r isnot 0
1570 call add(g:res, ' ' .. vv .. '! ' .. r)
1571 endif
1572 endfor
1573 endfor
1574 call RecVars(oname)
1575 for v in ['wopts3', 'bopts3']
1576 let r = E('del ' .. v .. '["' .. oname .. '"]')
1577 if r isnot 0
1578 call add(g:res, ' del ' .. v .. '! ' .. r)
1579 endif
1580 endfor
1581 call RecVars(oname)
1582 endfor
1583 delfunction RecVars
1584 delfunction E
1585 delfunction Ev
1586 py3 del ev
1587 py3 del e
1588 only
1589 for buf in g:bufs[1:]
1590 execute 'bwipeout!' buf
1591 endfor
1592 py3 del gopts1
1593 py3 del wopts1
1594 py3 del wopts2
1595 py3 del wopts3
1596 py3 del bopts1
1597 py3 del bopts2
1598 py3 del bopts3
1599 py3 del oval1
1600 py3 del oval2
1601 py3 del oval3
1602 py3 del oname
1603 py3 del invval
1604
1605 let expected =<< trim END
1606 wopts iters equal: 1
1607 bopts iters equal: 1
1608 >>> paste
1609 g/w/b:1/0/0
1610 g/w/b (in):1/0/0
1611 p/gopts1: False
1612 p/wopts1! KeyError
1613 inv: 2! KeyError
1614 wopts1! KeyError
1615 wopts2! KeyError
1616 wopts3! KeyError
1617 p/bopts1! KeyError
1618 inv: 2! KeyError
1619 bopts1! KeyError
1620 bopts2! KeyError
1621 bopts3! KeyError
1622 G: 1
1623 W: 1:1 2:1 3:1 4:1
1624 B: 1:1 2:1 3:1 4:1
1625 del wopts3! KeyError
1626 del bopts3! KeyError
1627 G: 1
1628 W: 1:1 2:1 3:1 4:1
1629 B: 1:1 2:1 3:1 4:1
1630 >>> previewheight
1631 g/w/b:1/0/0
1632 g/w/b (in):1/0/0
1633 p/gopts1: 12
1634 inv: 'a'! TypeError
1635 p/wopts1! KeyError
1636 inv: 'a'! KeyError
1637 wopts1! KeyError
1638 wopts2! KeyError
1639 wopts3! KeyError
1640 p/bopts1! KeyError
1641 inv: 'a'! KeyError
1642 bopts1! KeyError
1643 bopts2! KeyError
1644 bopts3! KeyError
1645 G: 5
1646 W: 1:5 2:5 3:5 4:5
1647 B: 1:5 2:5 3:5 4:5
1648 del wopts3! KeyError
1649 del bopts3! KeyError
1650 G: 5
1651 W: 1:5 2:5 3:5 4:5
1652 B: 1:5 2:5 3:5 4:5
1653 >>> operatorfunc
1654 g/w/b:1/0/0
1655 g/w/b (in):1/0/0
1656 p/gopts1: b''
1657 inv: 2! TypeError
1658 p/wopts1! KeyError
1659 inv: 2! KeyError
1660 wopts1! KeyError
1661 wopts2! KeyError
1662 wopts3! KeyError
1663 p/bopts1! KeyError
1664 inv: 2! KeyError
1665 bopts1! KeyError
1666 bopts2! KeyError
1667 bopts3! KeyError
1668 G: 'A'
1669 W: 1:'A' 2:'A' 3:'A' 4:'A'
1670 B: 1:'A' 2:'A' 3:'A' 4:'A'
1671 del wopts3! KeyError
1672 del bopts3! KeyError
1673 G: 'A'
1674 W: 1:'A' 2:'A' 3:'A' 4:'A'
1675 B: 1:'A' 2:'A' 3:'A' 4:'A'
1676 >>> number
1677 g/w/b:0/1/0
1678 g/w/b (in):0/1/0
1679 p/gopts1! KeyError
1680 inv: 0! KeyError
1681 gopts1! KeyError
1682 p/wopts1: False
1683 p/bopts1! KeyError
1684 inv: 0! KeyError
1685 bopts1! KeyError
1686 bopts2! KeyError
1687 bopts3! KeyError
1688 G: 0
1689 W: 1:1 2:1 3:0 4:0
1690 B: 1:1 2:1 3:0 4:0
1691 del wopts3! ValueError
1692 del bopts3! KeyError
1693 G: 0
1694 W: 1:1 2:1 3:0 4:0
1695 B: 1:1 2:1 3:0 4:0
1696 >>> numberwidth
1697 g/w/b:0/1/0
1698 g/w/b (in):0/1/0
1699 p/gopts1! KeyError
1700 inv: -100! KeyError
1701 gopts1! KeyError
1702 p/wopts1: 4
1703 inv: -100! error
1704 p/bopts1! KeyError
1705 inv: -100! KeyError
1706 bopts1! KeyError
1707 bopts2! KeyError
1708 bopts3! KeyError
1709 G: 4
1710 W: 1:3 2:5 3:2 4:4
1711 B: 1:3 2:5 3:2 4:4
1712 del wopts3! ValueError
1713 del bopts3! KeyError
1714 G: 4
1715 W: 1:3 2:5 3:2 4:4
1716 B: 1:3 2:5 3:2 4:4
1717 >>> colorcolumn
1718 g/w/b:0/1/0
1719 g/w/b (in):0/1/0
1720 p/gopts1! KeyError
1721 inv: 'abc4'! KeyError
1722 gopts1! KeyError
1723 p/wopts1: b''
1724 inv: 'abc4'! error
1725 p/bopts1! KeyError
1726 inv: 'abc4'! KeyError
1727 bopts1! KeyError
1728 bopts2! KeyError
1729 bopts3! KeyError
1730 G: ''
1731 W: 1:'+2' 2:'+3' 3:'+1' 4:''
1732 B: 1:'+2' 2:'+3' 3:'+1' 4:''
1733 del wopts3! ValueError
1734 del bopts3! KeyError
1735 G: ''
1736 W: 1:'+2' 2:'+3' 3:'+1' 4:''
1737 B: 1:'+2' 2:'+3' 3:'+1' 4:''
1738 >>> statusline
1739 g/w/b:1/1/0
1740 g/w/b (in):1/1/0
1741 p/gopts1: b''
1742 inv: 0! TypeError
1743 p/wopts1: None
1744 inv: 0! TypeError
1745 p/bopts1! KeyError
1746 inv: 0! KeyError
1747 bopts1! KeyError
1748 bopts2! KeyError
1749 bopts3! KeyError
1750 G: '1'
1751 W: 1:'2' 2:'4' 3:'1' 4:'1'
1752 B: 1:'2' 2:'4' 3:'1' 4:'1'
1753 del bopts3! KeyError
1754 G: '1'
1755 W: 1:'2' 2:'1' 3:'1' 4:'1'
1756 B: 1:'2' 2:'1' 3:'1' 4:'1'
1757 >>> autoindent
1758 g/w/b:0/0/1
1759 g/w/b (in):0/0/1
1760 p/gopts1! KeyError
1761 inv: 2! KeyError
1762 gopts1! KeyError
1763 p/wopts1! KeyError
1764 inv: 2! KeyError
1765 wopts1! KeyError
1766 wopts2! KeyError
1767 wopts3! KeyError
1768 p/bopts1: False
1769 G: 0
1770 W: 1:0 2:1 3:0 4:1
1771 B: 1:0 2:1 3:0 4:1
1772 del wopts3! KeyError
1773 del bopts3! ValueError
1774 G: 0
1775 W: 1:0 2:1 3:0 4:1
1776 B: 1:0 2:1 3:0 4:1
1777 >>> shiftwidth
1778 g/w/b:0/0/1
1779 g/w/b (in):0/0/1
1780 p/gopts1! KeyError
1781 inv: 3! KeyError
1782 gopts1! KeyError
1783 p/wopts1! KeyError
1784 inv: 3! KeyError
1785 wopts1! KeyError
1786 wopts2! KeyError
1787 wopts3! KeyError
1788 p/bopts1: 8
1789 G: 8
1790 W: 1:0 2:2 3:8 4:1
1791 B: 1:0 2:2 3:8 4:1
1792 del wopts3! KeyError
1793 del bopts3! ValueError
1794 G: 8
1795 W: 1:0 2:2 3:8 4:1
1796 B: 1:0 2:2 3:8 4:1
1797 >>> omnifunc
1798 g/w/b:0/0/1
1799 g/w/b (in):0/0/1
1800 p/gopts1! KeyError
1801 inv: 1! KeyError
1802 gopts1! KeyError
1803 p/wopts1! KeyError
1804 inv: 1! KeyError
1805 wopts1! KeyError
1806 wopts2! KeyError
1807 wopts3! KeyError
1808 p/bopts1: b''
1809 inv: 1! TypeError
1810 G: ''
1811 W: 1:'A' 2:'B' 3:'' 4:'C'
1812 B: 1:'A' 2:'B' 3:'' 4:'C'
1813 del wopts3! KeyError
1814 del bopts3! ValueError
1815 G: ''
1816 W: 1:'A' 2:'B' 3:'' 4:'C'
1817 B: 1:'A' 2:'B' 3:'' 4:'C'
1818 >>> preserveindent
1819 g/w/b:0/0/1
1820 g/w/b (in):0/0/1
1821 p/gopts1! KeyError
1822 inv: 2! KeyError
1823 gopts1! KeyError
1824 p/wopts1! KeyError
1825 inv: 2! KeyError
1826 wopts1! KeyError
1827 wopts2! KeyError
1828 wopts3! KeyError
1829 p/bopts1: False
1830 G: 0
1831 W: 1:0 2:1 3:0 4:1
1832 B: 1:0 2:1 3:0 4:1
1833 del wopts3! KeyError
1834 del bopts3! ValueError
1835 G: 0
1836 W: 1:0 2:1 3:0 4:1
1837 B: 1:0 2:1 3:0 4:1
1838 >>> path
1839 g/w/b:1/0/1
1840 g/w/b (in):1/0/1
1841 p/gopts1: b'.,..,,'
1842 inv: 0! TypeError
1843 p/wopts1! KeyError
1844 inv: 0! KeyError
1845 wopts1! KeyError
1846 wopts2! KeyError
1847 wopts3! KeyError
1848 p/bopts1: None
1849 inv: 0! TypeError
1850 G: '.,,'
1851 W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1852 B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
1853 del wopts3! KeyError
1854 G: '.,,'
1855 W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1856 B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
1857 END
1858
1859 call assert_equal(expected, g:res)
1860 unlet g:res
Bram Moolenaarab589462020-07-06 21:03:06 +02001861
1862 call assert_equal(0, py3eval("'' in vim.options"))
1863
1864 " use an empty key to index vim.options
1865 call AssertException(["let v = py3eval(\"vim.options['']\")"],
1866 \ 'Vim(let):ValueError: empty keys are not allowed')
1867 call AssertException(["py3 vim.current.window.options[''] = 0"],
1868 \ 'Vim(py3):ValueError: empty keys are not allowed')
1869 call AssertException(["py3 vim.current.window.options[{}] = 0"],
1870 \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got dict')
1871
1872 " set one of the number options to a very large number
1873 let cmd = ["py3 vim.options['previewheight'] = 9999999999999999"]
1874 call AssertException(cmd, "Vim(py3):OverflowError:")
1875
1876 " unset a global-local string option
1877 call AssertException(["py3 del vim.options['errorformat']"],
1878 \ 'Vim(py3):ValueError: unable to unset global option errorformat')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001879endfunc
1880
1881" Test for vim.buffer object
1882func Test_python3_buffer()
1883 new
1884 call setline(1, "Hello\nWorld")
1885 call assert_fails("let x = py3eval('vim.current.buffer[0]')", 'E859:')
1886 %bw!
1887
1888 edit Xfile1
1889 let bnr1 = bufnr()
1890 py3 cb = vim.current.buffer
1891 vnew Xfile2
1892 let bnr2 = bufnr()
1893 call setline(1, ['First line', 'Second line', 'Third line'])
1894 py3 b = vim.current.buffer
1895 wincmd w
1896
Bram Moolenaarab589462020-07-06 21:03:06 +02001897 " Test for getting lines from the buffer using a slice
1898 call assert_equal(['First line'], py3eval('b[-10:1]'))
1899 call assert_equal(['Third line'], py3eval('b[2:10]'))
1900 call assert_equal([], py3eval('b[2:0]'))
1901 call assert_equal([], py3eval('b[10:12]'))
1902 call assert_equal([], py3eval('b[-10:-8]'))
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02001903 call AssertException(["py3 x = b[0:3:0]"],
1904 \ 'Vim(py3):ValueError: slice step cannot be zero')
1905 call AssertException(["py3 b[0:3:0] = 'abc'"],
1906 \ 'Vim(py3):ValueError: slice step cannot be zero')
1907 call AssertException(["py3 x = b[{}]"],
1908 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1909 call AssertException(["py3 b[{}] = 'abc'"],
1910 \ 'Vim(py3):TypeError: index must be int or slice, not dict')
1911
1912 " Test for getting lines using a range
1913 call AssertException(["py3 x = b.range(0,3)[0:2:0]"],
1914 \ "Vim(py3):ValueError: slice step cannot be zero")
1915 call AssertException(["py3 b.range(0,3)[0:2:0] = 'abc'"],
1916 \ "Vim(py3):ValueError: slice step cannot be zero")
Bram Moolenaarab589462020-07-06 21:03:06 +02001917
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001918 " Tests BufferAppend and BufferItem
1919 py3 cb.append(b[0])
1920 call assert_equal(['First line'], getbufline(bnr1, 2))
1921 %d
1922
Bram Moolenaarab589462020-07-06 21:03:06 +02001923 " Try to append using out-of-range line number
1924 call AssertException(["py3 b.append('abc', 10)"],
1925 \ 'Vim(py3):IndexError: line number out of range')
1926
1927 " Append a non-string item
1928 call AssertException(["py3 b.append([22])"],
1929 \ 'Vim(py3):TypeError: expected bytes() or str() instance, but got int')
1930
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02001931 " Tests BufferSlice and BufferAssSlice
1932 py3 cb.append('abc5') # Will be overwritten
1933 py3 cb[-1:] = b[:-2]
1934 call assert_equal(['First line'], getbufline(bnr1, 2))
1935 %d
1936
1937 " Test BufferLength and BufferAssSlice
1938 py3 cb.append('def') # Will not be overwritten
1939 py3 cb[len(cb):] = b[:]
1940 call assert_equal(['def', 'First line', 'Second line', 'Third line'],
1941 \ getbufline(bnr1, 2, '$'))
1942 %d
1943
1944 " Test BufferAssItem and BufferMark
1945 call setbufline(bnr1, 1, ['one', 'two', 'three'])
1946 call cursor(1, 3)
1947 normal ma
1948 py3 cb.append('ghi') # Will be overwritten
1949 py3 cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
1950 call assert_equal(['(3, 2)'], getbufline(bnr1, 4))
1951 %d
1952
1953 " Test BufferRepr
1954 py3 cb.append(repr(cb) + repr(b))
1955 call assert_equal(['<buffer Xfile1><buffer Xfile2>'], getbufline(bnr1, 2))
1956 %d
1957
1958 " Modify foreign buffer
1959 py3 << trim EOF
1960 b.append('foo')
1961 b[0]='bar'
1962 b[0:0]=['baz']
1963 vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
1964 EOF
1965 call assert_equal(['baz', 'bar', 'Second line', 'Third line', 'foo'],
1966 \ getbufline(bnr2, 1, '$'))
1967 %d
1968
1969 " Test assigning to name property
1970 augroup BUFS
1971 autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
1972 autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
1973 augroup END
1974 py3 << trim EOF
1975 import os
1976 old_name = cb.name
1977 cb.name = 'foo'
1978 cb.append(cb.name[-11:].replace(os.path.sep, '/'))
1979 b.name = 'bar'
1980 cb.append(b.name[-11:].replace(os.path.sep, '/'))
1981 cb.name = old_name
1982 cb.append(cb.name[-14:].replace(os.path.sep, '/'))
1983 del old_name
1984 EOF
1985 call assert_equal([bnr1 .. ':BufFilePre:' .. bnr1,
1986 \ bnr1 .. ':BufFilePost:' .. bnr1,
1987 \ 'testdir/foo',
1988 \ bnr2 .. ':BufFilePre:' .. bnr2,
1989 \ bnr2 .. ':BufFilePost:' .. bnr2,
1990 \ 'testdir/bar',
1991 \ bnr1 .. ':BufFilePre:' .. bnr1,
1992 \ bnr1 .. ':BufFilePost:' .. bnr1,
1993 \ 'testdir/Xfile1'], getbufline(bnr1, 2, '$'))
1994 %d
1995
1996 " Test CheckBuffer
1997 py3 << trim EOF
1998 for _b in vim.buffers:
1999 if _b is not cb:
2000 vim.command('bwipeout! ' + str(_b.number))
2001 del _b
2002 cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
2003 EOF
2004 call assert_equal('valid: b:False, cb:True', getline(2))
2005 %d
2006
2007 py3 << trim EOF
2008 for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
2009 try:
2010 exec(expr)
2011 except vim.error:
2012 pass
2013 else:
2014 # Usually a SEGV here
2015 # Should not happen in any case
2016 cb.append('No exception for ' + expr)
2017 vim.command('cd .')
2018 del b
2019 EOF
2020 call assert_equal([''], getline(1, '$'))
2021
Bram Moolenaarab589462020-07-06 21:03:06 +02002022 " Delete all the lines in a buffer
2023 call setline(1, ['a', 'b', 'c'])
2024 py3 vim.current.buffer[:] = []
2025 call assert_equal([''], getline(1, '$'))
2026
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02002027 " Test for buffer marks
2028 call assert_equal(v:none, py3eval("vim.current.buffer.mark('r')"))
2029
Bram Moolenaarab589462020-07-06 21:03:06 +02002030 " Test for modifying a 'nomodifiable' buffer
2031 setlocal nomodifiable
2032 call AssertException(["py3 vim.current.buffer[0] = 'abc'"],
2033 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2034 call AssertException(["py3 vim.current.buffer[0] = None"],
2035 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2036 call AssertException(["py3 vim.current.buffer[:] = None"],
2037 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2038 call AssertException(["py3 vim.current.buffer[:] = []"],
2039 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2040 call AssertException(["py3 vim.current.buffer.append('abc')"],
2041 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2042 call AssertException(["py3 vim.current.buffer.append([])"],
2043 \ "Vim(py3):vim.error: Vim:E21: Cannot make changes, 'modifiable' is off")
2044 setlocal modifiable
2045
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002046 augroup BUFS
2047 autocmd!
2048 augroup END
2049 augroup! BUFS
2050 %bw!
Bram Moolenaarab589462020-07-06 21:03:06 +02002051
2052 " Range object for a deleted buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002053 new Xp3buffile
Bram Moolenaarab589462020-07-06 21:03:06 +02002054 call setline(1, ['one', 'two', 'three'])
2055 py3 b = vim.current.buffer
2056 py3 r = vim.current.buffer.range(0, 2)
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002057 call assert_equal('<range Xp3buffile (0:2)>', py3eval('repr(r)'))
Bram Moolenaarab589462020-07-06 21:03:06 +02002058 %bw!
2059 call AssertException(['py3 r[:] = []'],
2060 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2061 call assert_match('<buffer object (deleted)', py3eval('repr(b)'))
2062 call assert_match('<range object (for deleted buffer)', py3eval('repr(r)'))
2063 call AssertException(["let n = py3eval('len(r)')"],
2064 \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
2065 call AssertException(["py3 r.append('abc')"],
2066 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2067
2068 " object for a deleted buffer
2069 call AssertException(["py3 b[0] = 'one'"],
2070 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2071 call AssertException(["py3 b.append('one')"],
2072 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2073 call AssertException(["let n = py3eval('len(b)')"],
2074 \ 'Vim(let):vim.error: attempt to refer to deleted buffer')
2075 call AssertException(["py3 pos = b.mark('a')"],
2076 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2077 call AssertException(["py3 vim.current.buffer = b"],
2078 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
2079 call AssertException(["py3 rn = b.range(0, 2)"],
2080 \ 'Vim(py3):vim.error: attempt to refer to deleted buffer')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002081endfunc
2082
2083" Test vim.buffers object
2084func Test_python3_buffers()
2085 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002086 edit Xp3buffile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002087 py3 cb = vim.current.buffer
2088 set hidden
2089 edit a
2090 buffer #
2091 edit b
2092 buffer #
2093 edit c
2094 buffer #
2095 py3 << trim EOF
2096 # Check GCing iterator that was not fully exhausted
2097 i = iter(vim.buffers)
2098 cb.append('i:' + str(next(i)))
2099 # and also check creating more than one iterator at a time
2100 i2 = iter(vim.buffers)
2101 cb.append('i2:' + str(next(i2)))
2102 cb.append('i:' + str(next(i)))
2103 # The following should trigger GC and not cause any problems
2104 del i
2105 del i2
2106 i3 = iter(vim.buffers)
2107 cb.append('i3:' + str(next(i3)))
2108 del i3
2109 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002110 call assert_equal(['i:<buffer Xp3buffile>',
2111 \ 'i2:<buffer Xp3buffile>', 'i:<buffer a>', 'i3:<buffer Xp3buffile>'],
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002112 \ getline(2, '$'))
2113 %d
2114
2115 py3 << trim EOF
2116 prevnum = 0
2117 for b in vim.buffers:
2118 # Check buffer order
2119 if prevnum >= b.number:
2120 cb.append('!!! Buffer numbers not in strictly ascending order')
2121 # Check indexing: vim.buffers[number].number == number
2122 cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + \
2123 '=' + repr(b))
2124 prevnum = b.number
2125 del prevnum
2126
2127 cb.append(str(len(vim.buffers)))
2128 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002129 call assert_equal([bufnr('Xp3buffile') .. ':<buffer Xp3buffile>=<buffer Xp3buffile>',
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002130 \ bufnr('a') .. ':<buffer a>=<buffer a>',
2131 \ bufnr('b') .. ':<buffer b>=<buffer b>',
2132 \ bufnr('c') .. ':<buffer c>=<buffer c>', '4'], getline(2, '$'))
2133 %d
2134
2135 py3 << trim EOF
2136 bnums = list(map(lambda b: b.number, vim.buffers))[1:]
2137
2138 # Test wiping out buffer with existing iterator
2139 i4 = iter(vim.buffers)
2140 cb.append('i4:' + str(next(i4)))
2141 vim.command('bwipeout! ' + str(bnums.pop(0)))
2142 try:
2143 next(i4)
2144 except vim.error:
2145 pass
2146 else:
2147 cb.append('!!!! No vim.error')
2148 i4 = iter(vim.buffers)
2149 vim.command('bwipeout! ' + str(bnums.pop(-1)))
2150 vim.command('bwipeout! ' + str(bnums.pop(-1)))
2151 cb.append('i4:' + str(next(i4)))
2152 try:
2153 next(i4)
2154 except StopIteration:
2155 cb.append('StopIteration')
2156 del i4
2157 del bnums
2158 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002159 call assert_equal(['i4:<buffer Xp3buffile>',
2160 \ 'i4:<buffer Xp3buffile>', 'StopIteration'], getline(2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002161 %bw!
2162endfunc
2163
2164" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
2165func Test_python3_tabpage_window()
2166 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002167 edit Xp3buffile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002168 py3 cb = vim.current.buffer
2169 tabnew 0
2170 tabnew 1
2171 vnew a.1
2172 tabnew 2
2173 vnew a.2
2174 vnew b.2
2175 vnew c.2
2176
2177 py3 << trim EOF
2178 cb.append('Number of tabs: ' + str(len(vim.tabpages)))
2179 cb.append('Current tab pages:')
2180 def W(w):
2181 if '(unknown)' in repr(w):
2182 return '<window object (unknown)>'
2183 else:
2184 return repr(w)
2185
2186 def Cursor(w, start=len(cb)):
2187 if w.buffer is cb:
2188 return repr((start - w.cursor[0], w.cursor[1]))
2189 else:
2190 return repr(w.cursor)
2191
2192 for t in vim.tabpages:
2193 cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + \
2194 str(len(t.windows)) + ' windows, current is ' + W(t.window))
2195 cb.append(' Windows:')
2196 for w in t.windows:
2197 cb.append(' ' + W(w) + '(' + str(w.number) + ')' + \
2198 ': displays buffer ' + repr(w.buffer) + \
2199 '; cursor is at ' + Cursor(w))
2200 # Other values depend on the size of the terminal, so they are checked
2201 # partly:
2202 for attr in ('height', 'row', 'width', 'col'):
2203 try:
2204 aval = getattr(w, attr)
2205 if type(aval) is not int:
2206 raise TypeError
2207 if aval < 0:
2208 raise ValueError
2209 except Exception as e:
2210 cb.append('!!!!!! Error while getting attribute ' + attr + \
2211 ': ' + e.__class__.__name__)
2212 del aval
2213 del attr
2214 w.cursor = (len(w.buffer), 0)
2215 del W
2216 del Cursor
2217 cb.append('Number of windows in current tab page: ' + \
2218 str(len(vim.windows)))
2219 if list(vim.windows) != list(vim.current.tabpage.windows):
2220 cb.append('!!!!!! Windows differ')
2221 EOF
2222
2223 let expected =<< trim END
2224 Number of tabs: 4
2225 Current tab pages:
2226 <tabpage 0>(1): 1 windows, current is <window object (unknown)>
2227 Windows:
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002228 <window object (unknown)>(1): displays buffer <buffer Xp3buffile>; cursor is at (2, 0)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002229 <tabpage 1>(2): 1 windows, current is <window object (unknown)>
2230 Windows:
2231 <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
2232 <tabpage 2>(3): 2 windows, current is <window object (unknown)>
2233 Windows:
2234 <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
2235 <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
2236 <tabpage 3>(4): 4 windows, current is <window 0>
2237 Windows:
2238 <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
2239 <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
2240 <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
2241 <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
2242 Number of windows in current tab page: 4
2243 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002244 call assert_equal(expected, getbufline(bufnr('Xp3buffile'), 2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002245 %bw!
2246endfunc
2247
2248" Test vim.current
2249func Test_python3_vim_current()
2250 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002251 edit Xpy3cfile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002252 py3 cb = vim.current.buffer
2253 tabnew 0
2254 tabnew 1
2255 vnew a.1
2256 tabnew 2
2257 vnew a.2
2258 vnew b.2
2259 vnew c.2
2260
2261 py3 << trim EOF
2262 def H(o):
2263 return repr(o)
2264 cb.append('Current tab page: ' + repr(vim.current.tabpage))
2265 cb.append('Current window: ' + repr(vim.current.window) + ': ' + \
2266 H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
2267 cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + \
2268 H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ \
2269 ' is ' + H(vim.current.tabpage.window.buffer))
2270 del H
2271 EOF
2272 let expected =<< trim END
2273 Current tab page: <tabpage 3>
2274 Current window: <window 0>: <window 0> is <window 0>
2275 Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
2276 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002277 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
2278 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002279
2280 " Assigning: fails
2281 py3 << trim EOF
2282 try:
2283 vim.current.window = vim.tabpages[0].window
2284 except ValueError:
2285 cb.append('ValueError at assigning foreign tab window')
2286
2287 for attr in ('window', 'tabpage', 'buffer'):
2288 try:
2289 setattr(vim.current, attr, None)
2290 except TypeError:
2291 cb.append('Type error at assigning None to vim.current.' + attr)
2292 del attr
2293 EOF
2294
2295 let expected =<< trim END
2296 ValueError at assigning foreign tab window
2297 Type error at assigning None to vim.current.window
2298 Type error at assigning None to vim.current.tabpage
2299 Type error at assigning None to vim.current.buffer
2300 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002301 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
2302 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002303
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002304 call setbufline(bufnr('Xpy3cfile'), 1, 'python interface')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002305 py3 << trim EOF
2306 # Assigning: success
2307 vim.current.tabpage = vim.tabpages[-2]
2308 vim.current.buffer = cb
2309 vim.current.window = vim.windows[0]
2310 vim.current.window.cursor = (len(vim.current.buffer), 0)
2311 cb.append('Current tab page: ' + repr(vim.current.tabpage))
2312 cb.append('Current window: ' + repr(vim.current.window))
2313 cb.append('Current buffer: ' + repr(vim.current.buffer))
2314 cb.append('Current line: ' + repr(vim.current.line))
2315 EOF
2316
2317 let expected =<< trim END
2318 Current tab page: <tabpage 2>
2319 Current window: <window 0>
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002320 Current buffer: <buffer Xpy3cfile>
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002321 Current line: 'python interface'
2322 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002323 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
Bram Moolenaarab589462020-07-06 21:03:06 +02002324 py3 vim.current.line = 'one line'
2325 call assert_equal('one line', getline('.'))
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002326 call deletebufline(bufnr('Xpy3cfile'), 1, '$')
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002327
2328 py3 << trim EOF
2329 ws = list(vim.windows)
2330 ts = list(vim.tabpages)
2331 for b in vim.buffers:
2332 if b is not cb:
2333 vim.command('bwipeout! ' + str(b.number))
2334 del b
2335 cb.append('w.valid: ' + repr([w.valid for w in ws]))
2336 cb.append('t.valid: ' + repr([t.valid for t in ts]))
2337 del w
2338 del t
2339 del ts
2340 del ws
2341 EOF
2342 let expected =<< trim END
2343 w.valid: [True, False]
2344 t.valid: [True, False, True, False]
2345 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002346 call assert_equal(expected, getbufline(bufnr('Xpy3cfile'), 2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002347 %bw!
2348endfunc
2349
2350" Test types
2351func Test_python3_types()
2352 %d
2353 py3 cb = vim.current.buffer
2354 py3 << trim EOF
2355 for expr, attr in (
2356 ('vim.vars', 'Dictionary'),
2357 ('vim.options', 'Options'),
2358 ('vim.bindeval("{}")', 'Dictionary'),
2359 ('vim.bindeval("[]")', 'List'),
2360 ('vim.bindeval("function(\'tr\')")', 'Function'),
2361 ('vim.current.buffer', 'Buffer'),
2362 ('vim.current.range', 'Range'),
2363 ('vim.current.window', 'Window'),
2364 ('vim.current.tabpage', 'TabPage'),
2365 ):
2366 cb.append(expr + ':' + attr + ':' + \
2367 repr(type(eval(expr)) is getattr(vim, attr)))
2368 del expr
2369 del attr
2370 EOF
2371 let expected =<< trim END
2372 vim.vars:Dictionary:True
2373 vim.options:Options:True
2374 vim.bindeval("{}"):Dictionary:True
2375 vim.bindeval("[]"):List:True
2376 vim.bindeval("function('tr')"):Function:True
2377 vim.current.buffer:Buffer:True
2378 vim.current.range:Range:True
2379 vim.current.window:Window:True
2380 vim.current.tabpage:TabPage:True
2381 END
2382 call assert_equal(expected, getline(2, '$'))
2383endfunc
2384
2385" Test __dir__() method
2386func Test_python3_dir_method()
2387 %d
2388 py3 cb = vim.current.buffer
2389 py3 << trim EOF
2390 for name, o in (
2391 ('current', vim.current),
2392 ('buffer', vim.current.buffer),
2393 ('window', vim.current.window),
2394 ('tabpage', vim.current.tabpage),
2395 ('range', vim.current.range),
2396 ('dictionary', vim.bindeval('{}')),
2397 ('list', vim.bindeval('[]')),
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01002398 ('tuple', vim.bindeval('()')),
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002399 ('function', vim.bindeval('function("tr")')),
2400 ('output', sys.stdout),
2401 ):
2402 cb.append(name + ':' + ','.join(dir(o)))
2403 del name
2404 del o
2405 EOF
2406 let expected =<< trim END
2407 current:__dir__,buffer,line,range,tabpage,window
2408 buffer:__dir__,append,mark,name,number,options,range,valid,vars
2409 window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
2410 tabpage:__dir__,number,valid,vars,window,windows
2411 range:__dir__,append,end,start
2412 dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
2413 list:__dir__,extend,locked
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01002414 tuple:__dir__,locked
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002415 function:__dir__,args,auto_rebind,self,softspace
2416 output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
2417 END
2418 call assert_equal(expected, getline(2, '$'))
2419endfunc
2420
2421" Test vim.*.__new__
2422func Test_python3_new()
2423 call assert_equal({}, py3eval('vim.Dictionary({})'))
2424 call assert_equal({'a': 1}, py3eval('vim.Dictionary(a=1)'))
2425 call assert_equal({'a': 1}, py3eval('vim.Dictionary(((''a'', 1),))'))
2426 call assert_equal([], py3eval('vim.List()'))
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01002427 call assert_equal((), py3eval('vim.Tuple()'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002428 call assert_equal(['a', 'b', 'c', '7'], py3eval('vim.List(iter(''abc7''))'))
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01002429 call assert_equal(('a', 'b', 'c', '7'), py3eval('vim.Tuple(iter(''abc7''))'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002430 call assert_equal(function('tr'), py3eval('vim.Function(''tr'')'))
2431 call assert_equal(function('tr', [123, 3, 4]),
2432 \ py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
2433 call assert_equal(function('tr'), py3eval('vim.Function(''tr'', args=[])'))
2434 call assert_equal(function('tr', {}),
2435 \ py3eval('vim.Function(''tr'', self={})'))
2436 call assert_equal(function('tr', [123, 3, 4], {}),
2437 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
2438 call assert_equal(function('tr'),
2439 \ py3eval('vim.Function(''tr'', auto_rebind=False)'))
2440 call assert_equal(function('tr', [123, 3, 4]),
2441 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
2442 call assert_equal(function('tr'),
2443 \ py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
2444 call assert_equal(function('tr', {}),
2445 \ py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
2446 call assert_equal(function('tr', [123, 3, 4], {}),
2447 \ py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
2448endfunc
2449
2450" Test vim.Function
2451func Test_python3_vim_func()
Bram Moolenaarab589462020-07-06 21:03:06 +02002452 func Args(...)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002453 return a:000
2454 endfunc
2455
Bram Moolenaarab589462020-07-06 21:03:06 +02002456 func SelfArgs(...) dict
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002457 return [a:000, self]
2458 endfunc
2459
2460 " The following four lines should not crash
2461 let Pt = function('tr', [[]], {'l': []})
2462 py3 Pt = vim.bindeval('Pt')
2463 unlet Pt
2464 py3 del Pt
2465
Bram Moolenaarab589462020-07-06 21:03:06 +02002466 call assert_equal(3, py3eval('vim.strwidth("a\tb")'))
2467
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002468 %bw!
2469 py3 cb = vim.current.buffer
2470 py3 << trim EOF
2471 def ecall(out_prefix, func, *args, **kwargs):
2472 line = out_prefix + ': '
2473 try:
2474 ret = func(*args, **kwargs)
2475 except Exception:
2476 line += '!exception: ' + emsg(sys.exc_info())
2477 else:
2478 line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
2479 cb.append(line)
2480 a = vim.Function('Args')
2481 pa1 = vim.Function('Args', args=['abcArgsPA1'])
2482 pa2 = vim.Function('Args', args=[])
2483 pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
2484 pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
2485 cb.append('a: ' + repr(a))
2486 cb.append('pa1: ' + repr(pa1))
2487 cb.append('pa2: ' + repr(pa2))
2488 cb.append('pa3: ' + repr(pa3))
2489 cb.append('pa4: ' + repr(pa4))
2490 sa = vim.Function('SelfArgs')
2491 psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
2492 psa2 = vim.Function('SelfArgs', args=[])
2493 psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
2494 psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
2495 psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
2496 psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
2497 psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
2498 psa8 = vim.Function('SelfArgs', auto_rebind=False)
2499 psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
2500 psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
2501 psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
2502 psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
2503 cb.append('sa: ' + repr(sa))
2504 cb.append('psa1: ' + repr(psa1))
2505 cb.append('psa2: ' + repr(psa2))
2506 cb.append('psa3: ' + repr(psa3))
2507 cb.append('psa4: ' + repr(psa4))
2508 cb.append('psa5: ' + repr(psa5))
2509 cb.append('psa6: ' + repr(psa6))
2510 cb.append('psa7: ' + repr(psa7))
2511 cb.append('psa8: ' + repr(psa8))
2512 cb.append('psa9: ' + repr(psa9))
2513 cb.append('psaA: ' + repr(psaA))
2514 cb.append('psaB: ' + repr(psaB))
2515 cb.append('psaC: ' + repr(psaC))
2516
2517 psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
2518 psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
2519 psar.self['rec'] = psar
2520 psar.self['self'] = psar.self
2521 psar.self['args'] = psar.args
2522
2523 try:
2524 cb.append('psar: ' + repr(psar))
2525 except Exception:
2526 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
2527 EOF
2528
2529 let expected =<< trim END
2530 a: <vim.Function 'Args'>
2531 pa1: <vim.Function 'Args', args=['abcArgsPA1']>
2532 pa2: <vim.Function 'Args'>
2533 pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
2534 pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
2535 sa: <vim.Function 'SelfArgs'>
2536 psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
2537 psa2: <vim.Function 'SelfArgs'>
2538 psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
2539 psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
2540 psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
2541 psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
2542 psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
2543 psa8: <vim.Function 'SelfArgs'>
2544 psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
2545 psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
2546 psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
2547 psaC: <vim.Function 'SelfArgs'>
2548 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'}]}>
2549 END
2550 call assert_equal(expected, getline(2, '$'))
2551 %d
2552
2553 call assert_equal(function('Args'), py3eval('a'))
2554 call assert_equal(function('Args', ['abcArgsPA1']), py3eval('pa1'))
2555 call assert_equal(function('Args'), py3eval('pa2'))
2556 call assert_equal(function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}), py3eval('pa3'))
2557 call assert_equal(function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}), py3eval('pa4'))
2558 call assert_equal(function('SelfArgs'), py3eval('sa'))
2559 call assert_equal(function('SelfArgs', ['abcArgsPSA1']), py3eval('psa1'))
2560 call assert_equal(function('SelfArgs'), py3eval('psa2'))
2561 call assert_equal(function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}), py3eval('psa3'))
2562 call assert_equal(function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}), py3eval('psa4'))
2563 call assert_equal(function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}), py3eval('psa5'))
2564 call assert_equal(function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}), py3eval('psa6'))
2565 call assert_equal(function('SelfArgs', ['abcArgsPSA7']), py3eval('psa7'))
2566 call assert_equal(function('SelfArgs'), py3eval('psa8'))
2567 call assert_equal(function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}), py3eval('psa9'))
2568 call assert_equal(function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}), py3eval('psaA'))
2569 call assert_equal(function('SelfArgs', ['abcArgsPSAB']), py3eval('psaB'))
2570 call assert_equal(function('SelfArgs'), py3eval('psaC'))
2571
2572 let res = []
2573 for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7',
2574 \ 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
2575 let d = {'f': py3eval(v)}
2576 call add(res, 'd.' .. v .. '(): ' .. string(d.f()))
2577 endfor
2578
2579 let expected =<< trim END
2580 d.sa(): [[], {'f': function('SelfArgs')}]
2581 d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
2582 d.psa2(): [[], {'f': function('SelfArgs')}]
2583 d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2584 d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2585 d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
2586 d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
2587 d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
2588 d.psa8(): [[], {'f': function('SelfArgs')}]
2589 d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
2590 d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
2591 d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
2592 d.psaC(): [[], {'f': function('SelfArgs')}]
2593 END
2594 call assert_equal(expected, res)
2595
2596 py3 ecall('a()', a, )
2597 py3 ecall('pa1()', pa1, )
2598 py3 ecall('pa2()', pa2, )
2599 py3 ecall('pa3()', pa3, )
2600 py3 ecall('pa4()', pa4, )
2601 py3 ecall('sa()', sa, )
2602 py3 ecall('psa1()', psa1, )
2603 py3 ecall('psa2()', psa2, )
2604 py3 ecall('psa3()', psa3, )
2605 py3 ecall('psa4()', psa4, )
2606
2607 py3 ecall('a(42, 43)', a, 42, 43)
2608 py3 ecall('pa1(42, 43)', pa1, 42, 43)
2609 py3 ecall('pa2(42, 43)', pa2, 42, 43)
2610 py3 ecall('pa3(42, 43)', pa3, 42, 43)
2611 py3 ecall('pa4(42, 43)', pa4, 42, 43)
2612 py3 ecall('sa(42, 43)', sa, 42, 43)
2613 py3 ecall('psa1(42, 43)', psa1, 42, 43)
2614 py3 ecall('psa2(42, 43)', psa2, 42, 43)
2615 py3 ecall('psa3(42, 43)', psa3, 42, 43)
2616 py3 ecall('psa4(42, 43)', psa4, 42, 43)
2617
2618 py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
2619 py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
2620 py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
2621 py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
2622 py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
2623 py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
2624 py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
2625 py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
2626 py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
2627 py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
2628
2629 py3 ecall('a(self={"20": 1})', a, self={'20': 1})
2630 py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
2631 py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
2632 py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
2633 py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
2634 py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
2635 py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
2636 py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
2637 py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
2638 py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
2639
2640 py3 << trim EOF
2641 def s(v):
2642 if v is None:
2643 return repr(v)
2644 else:
2645 return str(vim.Function('string')(v), 'utf-8')
2646
2647 cb.append('a.args: ' + s(a.args))
2648 cb.append('pa1.args: ' + s(pa1.args))
2649 cb.append('pa2.args: ' + s(pa2.args))
2650 cb.append('pa3.args: ' + s(pa3.args))
2651 cb.append('pa4.args: ' + s(pa4.args))
2652 cb.append('sa.args: ' + s(sa.args))
2653 cb.append('psa1.args: ' + s(psa1.args))
2654 cb.append('psa2.args: ' + s(psa2.args))
2655 cb.append('psa3.args: ' + s(psa3.args))
2656 cb.append('psa4.args: ' + s(psa4.args))
2657
2658 cb.append('a.self: ' + s(a.self))
2659 cb.append('pa1.self: ' + s(pa1.self))
2660 cb.append('pa2.self: ' + s(pa2.self))
2661 cb.append('pa3.self: ' + s(pa3.self))
2662 cb.append('pa4.self: ' + s(pa4.self))
2663 cb.append('sa.self: ' + s(sa.self))
2664 cb.append('psa1.self: ' + s(psa1.self))
2665 cb.append('psa2.self: ' + s(psa2.self))
2666 cb.append('psa3.self: ' + s(psa3.self))
2667 cb.append('psa4.self: ' + s(psa4.self))
2668
2669 cb.append('a.name: ' + s(a.name))
2670 cb.append('pa1.name: ' + s(pa1.name))
2671 cb.append('pa2.name: ' + s(pa2.name))
2672 cb.append('pa3.name: ' + s(pa3.name))
2673 cb.append('pa4.name: ' + s(pa4.name))
2674 cb.append('sa.name: ' + s(sa.name))
2675 cb.append('psa1.name: ' + s(psa1.name))
2676 cb.append('psa2.name: ' + s(psa2.name))
2677 cb.append('psa3.name: ' + s(psa3.name))
2678 cb.append('psa4.name: ' + s(psa4.name))
2679
2680 cb.append('a.auto_rebind: ' + s(a.auto_rebind))
2681 cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
2682 cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
2683 cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
2684 cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
2685 cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
2686 cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
2687 cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
2688 cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
2689 cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
2690 cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
2691 cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
2692 cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
2693 cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
2694 cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
2695 cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
2696 cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
2697 cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
2698
2699 del s
2700
2701 del a
2702 del pa1
2703 del pa2
2704 del pa3
2705 del pa4
2706 del sa
2707 del psa1
2708 del psa2
2709 del psa3
2710 del psa4
2711 del psa5
2712 del psa6
2713 del psa7
2714 del psa8
2715 del psa9
2716 del psaA
2717 del psaB
2718 del psaC
2719 del psar
2720
2721 del ecall
2722 EOF
2723
2724 let expected =<< trim END
2725 a(): !result: []
2726 pa1(): !result: ['abcArgsPA1']
2727 pa2(): !result: []
2728 pa3(): !result: ['abcArgsPA3']
2729 pa4(): !result: []
2730 sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2731 psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2732 psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2733 psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2734 psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2735 a(42, 43): !result: [42, 43]
2736 pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
2737 pa2(42, 43): !result: [42, 43]
2738 pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
2739 pa4(42, 43): !result: [42, 43]
2740 sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2741 psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2742 psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
2743 psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
2744 psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
2745 a(42, self={"20": 1}): !result: [42]
2746 pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
2747 pa2(42, self={"20": 1}): !result: [42]
2748 pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
2749 pa4(42, self={"20": 1}): !result: [42]
2750 sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
2751 psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
2752 psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
2753 psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
2754 psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
2755 a(self={"20": 1}): !result: []
2756 pa1(self={"20": 1}): !result: ['abcArgsPA1']
2757 pa2(self={"20": 1}): !result: []
2758 pa3(self={"20": 1}): !result: ['abcArgsPA3']
2759 pa4(self={"20": 1}): !result: []
2760 sa(self={"20": 1}): !result: [[], {'20': 1}]
2761 psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
2762 psa2(self={"20": 1}): !result: [[], {'20': 1}]
2763 psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
2764 psa4(self={"20": 1}): !result: [[], {'20': 1}]
2765 a.args: None
2766 pa1.args: ['abcArgsPA1']
2767 pa2.args: None
2768 pa3.args: ['abcArgsPA3']
2769 pa4.args: None
2770 sa.args: None
2771 psa1.args: ['abcArgsPSA1']
2772 psa2.args: None
2773 psa3.args: ['abcArgsPSA3']
2774 psa4.args: None
2775 a.self: None
2776 pa1.self: None
2777 pa2.self: None
2778 pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
2779 pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
2780 sa.self: None
2781 psa1.self: None
2782 psa2.self: None
2783 psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
2784 psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
2785 a.name: 'Args'
2786 pa1.name: 'Args'
2787 pa2.name: 'Args'
2788 pa3.name: 'Args'
2789 pa4.name: 'Args'
2790 sa.name: 'SelfArgs'
2791 psa1.name: 'SelfArgs'
2792 psa2.name: 'SelfArgs'
2793 psa3.name: 'SelfArgs'
2794 psa4.name: 'SelfArgs'
2795 a.auto_rebind: 1
2796 pa1.auto_rebind: 1
2797 pa2.auto_rebind: 1
2798 pa3.auto_rebind: 0
2799 pa4.auto_rebind: 0
2800 sa.auto_rebind: 1
2801 psa1.auto_rebind: 1
2802 psa2.auto_rebind: 1
2803 psa3.auto_rebind: 0
2804 psa4.auto_rebind: 0
2805 psa5.auto_rebind: 0
2806 psa6.auto_rebind: 0
2807 psa7.auto_rebind: 1
2808 psa8.auto_rebind: 1
2809 psa9.auto_rebind: 1
2810 psaA.auto_rebind: 1
2811 psaB.auto_rebind: 1
2812 psaC.auto_rebind: 1
2813 END
2814 call assert_equal(expected, getline(2, '$'))
2815 %bw!
2816endfunc
2817
2818" Test stdout/stderr
2819func Test_python3_stdin_stderr()
2820 let caught_writeerr = 0
2821 let caught_writelineerr = 0
2822 redir => messages
2823 py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
2824 try
2825 py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
2826 catch /abc9def/
2827 let caught_writeerr = 1
2828 endtry
2829 py3 sys.stdout.writelines(iter('abcA'))
2830 try
2831 py3 sys.stderr.writelines(iter('abcB'))
2832 catch /abcB/
2833 let caught_writelineerr = 1
2834 endtry
2835 redir END
2836 call assert_equal("\nabc8def\nabcA", messages)
2837 call assert_equal(1, caught_writeerr)
2838 call assert_equal(1, caught_writelineerr)
2839endfunc
2840
2841" Test subclassing
2842func Test_python3_subclass()
2843 new
2844 func Put(...)
2845 return a:000
2846 endfunc
2847
2848 py3 << trim EOF
2849 class DupDict(vim.Dictionary):
2850 def __setitem__(self, key, value):
2851 super(DupDict, self).__setitem__(key, value)
2852 super(DupDict, self).__setitem__('dup_' + key, value)
2853 dd = DupDict()
2854 dd['a'] = 'b'
2855
2856 class DupList(vim.List):
2857 def __getitem__(self, idx):
2858 return [super(DupList, self).__getitem__(idx)] * 2
2859
2860 dl = DupList()
2861 dl2 = DupList(iter('abcC'))
2862 dl.extend(dl2[0])
2863
2864 class DupFun(vim.Function):
2865 def __call__(self, arg):
2866 return super(DupFun, self).__call__(arg, arg)
2867
2868 df = DupFun('Put')
2869 EOF
2870
2871 call assert_equal(['a', 'dup_a'], sort(keys(py3eval('dd'))))
2872 call assert_equal(['a', 'a'], py3eval('dl'))
2873 call assert_equal(['a', 'b', 'c', 'C'], py3eval('dl2'))
2874 call assert_equal([2, 2], py3eval('df(2)'))
2875 call assert_equal(1, py3eval('dl') is# py3eval('dl'))
2876 call assert_equal(1, py3eval('dd') is# py3eval('dd'))
2877 call assert_equal(function('Put'), py3eval('df'))
2878 delfunction Put
2879 py3 << trim EOF
2880 del DupDict
2881 del DupList
2882 del DupFun
2883 del dd
2884 del dl
2885 del dl2
2886 del df
2887 EOF
2888 close!
2889endfunc
2890
2891" Test chdir
2892func Test_python3_chdir()
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002893 new Xp3cdfile
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002894 py3 cb = vim.current.buffer
2895 py3 << trim EOF
2896 import os
2897 fnamemodify = vim.Function('fnamemodify')
2898 cb.append(str(fnamemodify('.', ':p:h:t')))
2899 cb.append(vim.eval('@%'))
2900 os.chdir('..')
2901 path = fnamemodify('.', ':p:h:t')
Bram Moolenaar7d697962020-08-31 21:30:32 +02002902 if path != b'src' and path != b'src2':
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002903 # Running tests from a shadow directory, so move up another level
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002904 # This will result in @% looking like shadow/testdir/Xp3cdfile, hence the
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002905 # slicing to remove the leading path and path separator
2906 os.chdir('..')
2907 cb.append(str(fnamemodify('.', ':p:h:t')))
2908 cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
2909 os.chdir(path)
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002910 else:
Bram Moolenaar7d697962020-08-31 21:30:32 +02002911 # Also accept running from src2/testdir/ for MS-Windows CI.
2912 cb.append(str(fnamemodify('.', ':p:h:t').replace(b'src2', b'src')))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002913 cb.append(vim.eval('@%').replace(os.path.sep, '/'))
2914 del path
2915 os.chdir('testdir')
2916 cb.append(str(fnamemodify('.', ':p:h:t')))
2917 cb.append(vim.eval('@%'))
2918 del fnamemodify
2919 EOF
Bram Moolenaarb18b4962022-09-02 21:55:50 +01002920 call assert_equal(["b'testdir'", 'Xp3cdfile', "b'src'", 'testdir/Xp3cdfile',
2921 \"b'testdir'", 'Xp3cdfile'], getline(2, '$'))
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002922 close!
Bram Moolenaar0ab55d62020-07-07 20:50:39 +02002923 call AssertException(["py3 vim.chdir(None)"], "Vim(py3):TypeError:")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002924endfunc
2925
2926" Test errors
2927func Test_python3_errors()
2928 func F() dict
2929 endfunc
2930
2931 func D()
2932 endfunc
2933
2934 new
2935 py3 cb = vim.current.buffer
2936
2937 py3 << trim EOF
K.Takata1be7e212021-11-16 13:08:56 +00002938 import os
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02002939 d = vim.Dictionary()
2940 ned = vim.Dictionary(foo='bar', baz='abcD')
2941 dl = vim.Dictionary(a=1)
2942 dl.locked = True
2943 l = vim.List()
2944 ll = vim.List('abcE')
2945 ll.locked = True
2946 nel = vim.List('abcO')
2947 f = vim.Function('string')
2948 fd = vim.Function('F')
2949 fdel = vim.Function('D')
2950 vim.command('delfunction D')
2951
2952 def subexpr_test(expr, name, subexprs):
2953 cb.append('>>> Testing %s using %s' % (name, expr))
2954 for subexpr in subexprs:
2955 ee(expr % subexpr)
2956 cb.append('<<< Finished')
2957
2958 def stringtochars_test(expr):
2959 return subexpr_test(expr, 'StringToChars', (
2960 '1', # Fail type checks
2961 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
2962 '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
2963 ))
2964
2965 class Mapping(object):
2966 def __init__(self, d):
2967 self.d = d
2968
2969 def __getitem__(self, key):
2970 return self.d[key]
2971
2972 def keys(self):
2973 return self.d.keys()
2974
2975 def items(self):
2976 return self.d.items()
2977
2978 def convertfrompyobject_test(expr, recurse=True):
2979 # pydict_to_tv
2980 stringtochars_test(expr % '{%s : 1}')
2981 if recurse:
2982 convertfrompyobject_test(expr % '{"abcF" : %s}', False)
2983 # pymap_to_tv
2984 stringtochars_test(expr % 'Mapping({%s : 1})')
2985 if recurse:
2986 convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
2987 # pyseq_to_tv
2988 iter_test(expr)
2989 return subexpr_test(expr, 'ConvertFromPyObject', (
2990 'None', # Not conversible
2991 '{b"": 1}', # Empty key not allowed
2992 '{"": 1}', # Same, but with unicode object
2993 'FailingMapping()', #
2994 'FailingMappingKey()', #
2995 'FailingNumber()', #
2996 ))
2997
2998 def convertfrompymapping_test(expr):
2999 convertfrompyobject_test(expr)
3000 return subexpr_test(expr, 'ConvertFromPyMapping', (
3001 '[]',
3002 ))
3003
3004 def iter_test(expr):
3005 return subexpr_test(expr, '*Iter*', (
3006 'FailingIter()',
3007 'FailingIterNext()',
3008 ))
3009
3010 def number_test(expr, natural=False, unsigned=False):
3011 if natural:
3012 unsigned = True
3013 return subexpr_test(expr, 'NumberToLong', (
3014 '[]',
3015 'None',
3016 ) + (('-1',) if unsigned else ())
3017 + (('0',) if natural else ()))
3018
3019 class FailingTrue(object):
3020 def __bool__(self):
3021 raise NotImplementedError('bool')
3022
3023 class FailingIter(object):
3024 def __iter__(self):
3025 raise NotImplementedError('iter')
3026
3027 class FailingIterNext(object):
3028 def __iter__(self):
3029 return self
3030
3031 def __next__(self):
3032 raise NotImplementedError('next')
3033
3034 class FailingIterNextN(object):
3035 def __init__(self, n):
3036 self.n = n
3037
3038 def __iter__(self):
3039 return self
3040
3041 def __next__(self):
3042 if self.n:
3043 self.n -= 1
3044 return 1
3045 else:
3046 raise NotImplementedError('next N')
3047
3048 class FailingMappingKey(object):
3049 def __getitem__(self, item):
3050 raise NotImplementedError('getitem:mappingkey')
3051
3052 def keys(self):
3053 return list("abcH")
3054
3055 class FailingMapping(object):
3056 def __getitem__(self):
3057 raise NotImplementedError('getitem:mapping')
3058
3059 def keys(self):
3060 raise NotImplementedError('keys')
3061
3062 class FailingList(list):
3063 def __getitem__(self, idx):
3064 if i == 2:
3065 raise NotImplementedError('getitem:list')
3066 else:
3067 return super(FailingList, self).__getitem__(idx)
3068
3069 class NoArgsCall(object):
3070 def __call__(self):
3071 pass
3072
3073 class FailingCall(object):
3074 def __call__(self, path):
3075 raise NotImplementedError('call')
3076
3077 class FailingNumber(object):
3078 def __int__(self):
3079 raise NotImplementedError('int')
3080
3081 cb.append("> Output")
3082 cb.append(">> OutputSetattr")
3083 ee('del sys.stdout.softspace')
3084 number_test('sys.stdout.softspace = %s', unsigned=True)
3085 number_test('sys.stderr.softspace = %s', unsigned=True)
3086 ee('assert sys.stdout.isatty()==False')
3087 ee('assert sys.stdout.seekable()==False')
3088 ee('sys.stdout.close()')
3089 ee('sys.stdout.flush()')
3090 ee('assert sys.stderr.isatty()==False')
3091 ee('assert sys.stderr.seekable()==False')
3092 ee('sys.stderr.close()')
3093 ee('sys.stderr.flush()')
3094 ee('sys.stdout.attr = None')
3095 cb.append(">> OutputWrite")
3096 ee('assert sys.stdout.writable()==True')
3097 ee('assert sys.stdout.readable()==False')
3098 ee('assert sys.stderr.writable()==True')
3099 ee('assert sys.stderr.readable()==False')
3100 ee('assert sys.stdout.closed()==False')
3101 ee('assert sys.stderr.closed()==False')
3102 ee('assert sys.stdout.errors=="strict"')
3103 ee('assert sys.stderr.errors=="strict"')
3104 ee('assert sys.stdout.encoding==sys.stderr.encoding')
3105 ee('sys.stdout.write(None)')
3106 cb.append(">> OutputWriteLines")
3107 ee('sys.stdout.writelines(None)')
3108 ee('sys.stdout.writelines([1])')
3109 iter_test('sys.stdout.writelines(%s)')
3110 cb.append("> VimCommand")
3111 stringtochars_test('vim.command(%s)')
3112 ee('vim.command("", 2)')
3113 #! Not checked: vim->python exceptions translating: checked later
3114 cb.append("> VimToPython")
3115 #! Not checked: everything: needs errors in internal python functions
3116 cb.append("> VimEval")
3117 stringtochars_test('vim.eval(%s)')
3118 ee('vim.eval("", FailingTrue())')
3119 #! Not checked: everything: needs errors in internal python functions
3120 cb.append("> VimEvalPy")
3121 stringtochars_test('vim.bindeval(%s)')
3122 ee('vim.eval("", 2)')
3123 #! Not checked: vim->python exceptions translating: checked later
3124 cb.append("> VimStrwidth")
3125 stringtochars_test('vim.strwidth(%s)')
3126 cb.append("> VimForeachRTP")
3127 ee('vim.foreach_rtp(None)')
3128 ee('vim.foreach_rtp(NoArgsCall())')
3129 ee('vim.foreach_rtp(FailingCall())')
3130 ee('vim.foreach_rtp(int, 2)')
3131 cb.append('> import')
3132 old_rtp = vim.options['rtp']
3133 vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
3134 ee('import xxx_no_such_module_xxx')
3135 ee('import failing_import')
3136 ee('import failing')
3137 vim.options['rtp'] = old_rtp
3138 del old_rtp
3139 cb.append("> Options")
3140 cb.append(">> OptionsItem")
3141 ee('vim.options["abcQ"]')
3142 ee('vim.options[""]')
3143 stringtochars_test('vim.options[%s]')
3144 cb.append(">> OptionsContains")
3145 stringtochars_test('%s in vim.options')
3146 cb.append("> Dictionary")
3147 cb.append(">> DictionaryConstructor")
3148 ee('vim.Dictionary("abcI")')
3149 ##! Not checked: py_dict_alloc failure
3150 cb.append(">> DictionarySetattr")
3151 ee('del d.locked')
3152 ee('d.locked = FailingTrue()')
3153 ee('vim.vvars.locked = False')
3154 ee('d.scope = True')
3155 ee('d.xxx = True')
3156 cb.append(">> _DictionaryItem")
3157 ee('d.get("a", 2, 3)')
3158 stringtochars_test('d.get(%s)')
3159 ee('d.pop("a")')
3160 ee('dl.pop("a")')
3161 cb.append(">> DictionaryContains")
3162 ee('"" in d')
3163 ee('0 in d')
3164 cb.append(">> DictionaryIterNext")
3165 ee('for i in ned: ned["a"] = 1')
3166 del i
3167 cb.append(">> DictionaryAssItem")
3168 ee('dl["b"] = 1')
3169 stringtochars_test('d[%s] = 1')
3170 convertfrompyobject_test('d["a"] = %s')
3171 cb.append(">> DictionaryUpdate")
3172 cb.append(">>> kwargs")
3173 cb.append(">>> iter")
3174 ee('d.update(FailingMapping())')
3175 ee('d.update([FailingIterNext()])')
3176 ee('d.update([FailingIterNextN(1)])')
3177 iter_test('d.update(%s)')
3178 convertfrompyobject_test('d.update(%s)')
3179 stringtochars_test('d.update(((%s, 0),))')
3180 convertfrompyobject_test('d.update((("a", %s),))')
3181 cb.append(">> DictionaryPopItem")
3182 ee('d.popitem(1, 2)')
3183 cb.append(">> DictionaryHasKey")
3184 ee('d.has_key()')
3185 cb.append("> List")
3186 cb.append(">> ListConstructor")
3187 ee('vim.List(1, 2)')
3188 ee('vim.List(a=1)')
3189 iter_test('vim.List(%s)')
3190 convertfrompyobject_test('vim.List([%s])')
3191 cb.append(">> ListItem")
3192 ee('l[1000]')
3193 cb.append(">> ListAssItem")
3194 ee('ll[1] = 2')
3195 ee('l[1000] = 3')
3196 cb.append(">> ListAssSlice")
3197 ee('ll[1:100] = "abcJ"')
3198 iter_test('l[:] = %s')
3199 ee('nel[1:10:2] = "abcK"')
3200 cb.append(repr(tuple(nel)))
3201 ee('nel[1:10:2] = "a"')
3202 cb.append(repr(tuple(nel)))
3203 ee('nel[1:1:-1] = "a"')
3204 cb.append(repr(tuple(nel)))
3205 ee('nel[:] = FailingIterNextN(2)')
3206 cb.append(repr(tuple(nel)))
3207 convertfrompyobject_test('l[:] = [%s]')
3208 cb.append(">> ListConcatInPlace")
3209 iter_test('l.extend(%s)')
3210 convertfrompyobject_test('l.extend([%s])')
3211 cb.append(">> ListSetattr")
3212 ee('del l.locked')
3213 ee('l.locked = FailingTrue()')
3214 ee('l.xxx = True')
3215 cb.append("> Function")
3216 cb.append(">> FunctionConstructor")
3217 cb.append(">>> FunctionConstructor")
3218 ee('vim.Function("123")')
3219 ee('vim.Function("xxx_non_existent_function_xxx")')
3220 ee('vim.Function("xxx#non#existent#function#xxx")')
3221 ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
3222 ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
3223 ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
3224 cb.append(">>> FunctionNew")
3225 ee('vim.Function("tr", self="abcFuncSelf")')
3226 ee('vim.Function("tr", args=427423)')
3227 ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
3228 ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
3229 ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
3230 ee('vim.Function("tr", "")')
3231 cb.append(">> FunctionCall")
3232 convertfrompyobject_test('f(%s)')
3233 convertfrompymapping_test('fd(self=%s)')
3234 cb.append("> TabPage")
3235 cb.append(">> TabPageAttr")
3236 ee('vim.current.tabpage.xxx')
3237 cb.append("> TabList")
3238 cb.append(">> TabListItem")
3239 ee('vim.tabpages[1000]')
3240 cb.append("> Window")
3241 cb.append(">> WindowAttr")
3242 ee('vim.current.window.xxx')
3243 cb.append(">> WindowSetattr")
3244 ee('vim.current.window.buffer = 0')
3245 ee('vim.current.window.cursor = (100000000, 100000000)')
3246 ee('vim.current.window.cursor = True')
3247 number_test('vim.current.window.height = %s', unsigned=True)
3248 number_test('vim.current.window.width = %s', unsigned=True)
3249 ee('vim.current.window.xxxxxx = True')
3250 cb.append("> WinList")
3251 cb.append(">> WinListItem")
3252 ee('vim.windows[1000]')
3253 cb.append("> Buffer")
3254 cb.append(">> StringToLine (indirect)")
3255 ee('vim.current.buffer[0] = "\\na"')
3256 ee('vim.current.buffer[0] = b"\\na"')
3257 cb.append(">> SetBufferLine (indirect)")
3258 ee('vim.current.buffer[0] = True')
3259 cb.append(">> SetBufferLineList (indirect)")
3260 ee('vim.current.buffer[:] = True')
3261 ee('vim.current.buffer[:] = ["\\na", "bc"]')
3262 cb.append(">> InsertBufferLines (indirect)")
3263 ee('vim.current.buffer.append(None)')
3264 ee('vim.current.buffer.append(["\\na", "bc"])')
3265 ee('vim.current.buffer.append("\\nbc")')
3266 cb.append(">> RBItem")
3267 ee('vim.current.buffer[100000000]')
3268 cb.append(">> RBAsItem")
3269 ee('vim.current.buffer[100000000] = ""')
3270 cb.append(">> BufferAttr")
3271 ee('vim.current.buffer.xxx')
3272 cb.append(">> BufferSetattr")
3273 ee('vim.current.buffer.name = True')
3274 ee('vim.current.buffer.xxx = True')
3275 cb.append(">> BufferMark")
3276 ee('vim.current.buffer.mark(0)')
3277 ee('vim.current.buffer.mark("abcM")')
3278 ee('vim.current.buffer.mark("!")')
3279 cb.append(">> BufferRange")
3280 ee('vim.current.buffer.range(1, 2, 3)')
3281 cb.append("> BufMap")
3282 cb.append(">> BufMapItem")
3283 ee('vim.buffers[100000000]')
3284 number_test('vim.buffers[%s]', natural=True)
3285 cb.append("> Current")
3286 cb.append(">> CurrentGetattr")
3287 ee('vim.current.xxx')
3288 cb.append(">> CurrentSetattr")
3289 ee('vim.current.line = True')
3290 ee('vim.current.buffer = True')
3291 ee('vim.current.window = True')
3292 ee('vim.current.tabpage = True')
3293 ee('vim.current.xxx = True')
3294 del d
3295 del ned
3296 del dl
3297 del l
3298 del ll
3299 del nel
3300 del f
3301 del fd
3302 del fdel
3303 del subexpr_test
3304 del stringtochars_test
3305 del Mapping
3306 del convertfrompyobject_test
3307 del convertfrompymapping_test
3308 del iter_test
3309 del number_test
3310 del FailingTrue
3311 del FailingIter
3312 del FailingIterNext
3313 del FailingIterNextN
3314 del FailingMapping
3315 del FailingMappingKey
3316 del FailingList
3317 del NoArgsCall
3318 del FailingCall
3319 del FailingNumber
3320 EOF
3321 delfunction F
3322
3323 let expected =<< trim END
3324 > Output
3325 >> OutputSetattr
3326 del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError('cannot delete OutputObject attributes',))
3327 >>> Testing NumberToLong using sys.stdout.softspace = %s
3328 sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3329 sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3330 sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3331 <<< Finished
3332 >>> Testing NumberToLong using sys.stderr.softspace = %s
3333 sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
3334 sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
3335 sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
3336 <<< Finished
3337 assert sys.stdout.isatty()==False:NOT FAILED
3338 assert sys.stdout.seekable()==False:NOT FAILED
3339 sys.stdout.close():NOT FAILED
3340 sys.stdout.flush():NOT FAILED
3341 assert sys.stderr.isatty()==False:NOT FAILED
3342 assert sys.stderr.seekable()==False:NOT FAILED
3343 sys.stderr.close():NOT FAILED
3344 sys.stderr.flush():NOT FAILED
3345 sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
3346 >> OutputWrite
3347 assert sys.stdout.writable()==True:NOT FAILED
3348 assert sys.stdout.readable()==False:NOT FAILED
3349 assert sys.stderr.writable()==True:NOT FAILED
3350 assert sys.stderr.readable()==False:NOT FAILED
3351 assert sys.stdout.closed()==False:NOT FAILED
3352 assert sys.stderr.closed()==False:NOT FAILED
3353 assert sys.stdout.errors=="strict":NOT FAILED
3354 assert sys.stderr.errors=="strict":NOT FAILED
3355 assert sys.stdout.encoding==sys.stderr.encoding:NOT FAILED
3356 sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
3357 >> OutputWriteLines
3358 sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3359 sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
3360 >>> Testing *Iter* using sys.stdout.writelines(%s)
3361 sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3362 sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3363 <<< Finished
3364 > VimCommand
3365 >>> Testing StringToChars using vim.command(%s)
3366 vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3367 vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3368 vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3369 <<< Finished
3370 vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
3371 > VimToPython
3372 > VimEval
3373 >>> Testing StringToChars using vim.eval(%s)
3374 vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3375 vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3376 vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3377 <<< Finished
3378 vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3379 > VimEvalPy
3380 >>> Testing StringToChars using vim.bindeval(%s)
3381 vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3382 vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3383 vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3384 <<< Finished
3385 vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3386 > VimStrwidth
3387 >>> Testing StringToChars using vim.strwidth(%s)
3388 vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3389 vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3390 vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3391 <<< Finished
3392 > VimForeachRTP
3393 vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
3394 vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
3395 vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
3396 vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
3397 > import
3398 import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
3399 import failing_import:(<class 'ImportError'>, ImportError())
3400 import failing:(<class 'NotImplementedError'>, NotImplementedError())
3401 > Options
3402 >> OptionsItem
3403 vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
3404 vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3405 >>> Testing StringToChars using vim.options[%s]
3406 vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3407 vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3408 vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3409 <<< Finished
3410 >> OptionsContains
3411 >>> Testing StringToChars using %s in vim.options
3412 1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3413 b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3414 "\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3415 <<< Finished
3416 > Dictionary
3417 >> DictionaryConstructor
3418 vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
3419 >> DictionarySetattr
3420 del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
3421 d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3422 vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
3423 d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
3424 d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3425 >> _DictionaryItem
3426 d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
3427 >>> Testing StringToChars using d.get(%s)
3428 d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3429 d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3430 d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3431 <<< Finished
3432 d.pop("a"):(<class 'KeyError'>, KeyError('a',))
3433 dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
3434 >> DictionaryContains
3435 "" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3436 0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3437 >> DictionaryIterNext
3438 for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
3439 >> DictionaryAssItem
3440 dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
3441 >>> Testing StringToChars using d[%s] = 1
3442 d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3443 d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3444 d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3445 <<< Finished
3446 >>> Testing StringToChars using d["a"] = {%s : 1}
3447 d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3448 d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3449 d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3450 <<< Finished
3451 >>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
3452 d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3453 d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3454 d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3455 <<< Finished
3456 >>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
3457 d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3458 d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3459 d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3460 <<< Finished
3461 >>> Testing *Iter* using d["a"] = {"abcF" : %s}
3462 d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3463 d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
3464 <<< Finished
3465 >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
3466 d["a"] = {"abcF" : None}:NOT FAILED
3467 d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3468 d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3469 d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3470 d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3471 d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
3472 <<< Finished
3473 >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
3474 d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3475 d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3476 d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3477 <<< Finished
3478 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
3479 d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3480 d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3481 d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3482 <<< Finished
3483 >>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
3484 d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3485 d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3486 d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3487 <<< Finished
3488 >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
3489 d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3490 d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3491 <<< Finished
3492 >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
3493 d["a"] = Mapping({"abcG" : None}):NOT FAILED
3494 d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3495 d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3496 d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3497 d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3498 d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3499 <<< Finished
3500 >>> Testing *Iter* using d["a"] = %s
3501 d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3502 d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3503 <<< Finished
3504 >>> Testing ConvertFromPyObject using d["a"] = %s
3505 d["a"] = None:NOT FAILED
3506 d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3507 d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3508 d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
3509 d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3510 d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
3511 <<< Finished
3512 >> DictionaryUpdate
3513 >>> kwargs
3514 >>> iter
3515 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3516 d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3517 d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3518 >>> Testing *Iter* using d.update(%s)
3519 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3520 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3521 <<< Finished
3522 >>> Testing StringToChars using d.update({%s : 1})
3523 d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3524 d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3525 d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3526 <<< Finished
3527 >>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
3528 d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3529 d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3530 d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3531 <<< Finished
3532 >>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
3533 d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3534 d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3535 d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3536 <<< Finished
3537 >>> Testing *Iter* using d.update({"abcF" : %s})
3538 d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3539 d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3540 <<< Finished
3541 >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
3542 d.update({"abcF" : None}):NOT FAILED
3543 d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3544 d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3545 d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3546 d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3547 d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3548 <<< Finished
3549 >>> Testing StringToChars using d.update(Mapping({%s : 1}))
3550 d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3551 d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3552 d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3553 <<< Finished
3554 >>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
3555 d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3556 d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3557 d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3558 <<< Finished
3559 >>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
3560 d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3561 d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3562 d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3563 <<< Finished
3564 >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
3565 d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3566 d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3567 <<< Finished
3568 >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
3569 d.update(Mapping({"abcG" : None})):NOT FAILED
3570 d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3571 d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3572 d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3573 d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3574 d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3575 <<< Finished
3576 >>> Testing *Iter* using d.update(%s)
3577 d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3578 d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3579 <<< Finished
3580 >>> Testing ConvertFromPyObject using d.update(%s)
3581 d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
3582 d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3583 d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3584 d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3585 d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3586 d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
3587 <<< Finished
3588 >>> Testing StringToChars using d.update(((%s, 0),))
3589 d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3590 d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3591 d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3592 <<< Finished
3593 >>> Testing StringToChars using d.update((("a", {%s : 1}),))
3594 d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3595 d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3596 d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3597 <<< Finished
3598 >>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
3599 d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3600 d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3601 d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3602 <<< Finished
3603 >>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
3604 d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3605 d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3606 d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3607 <<< Finished
3608 >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
3609 d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3610 d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3611 <<< Finished
3612 >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
3613 d.update((("a", {"abcF" : None}),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3614 d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3615 d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3616 d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3617 d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3618 d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3619 <<< Finished
3620 >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
3621 d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3622 d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3623 d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3624 <<< Finished
3625 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
3626 d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3627 d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3628 d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3629 <<< Finished
3630 >>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
3631 d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3632 d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3633 d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3634 <<< Finished
3635 >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
3636 d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3637 d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3638 <<< Finished
3639 >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
3640 d.update((("a", Mapping({"abcG" : None})),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3641 d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3642 d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3643 d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3644 d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3645 d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3646 <<< Finished
3647 >>> Testing *Iter* using d.update((("a", %s),))
3648 d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3649 d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
3650 <<< Finished
3651 >>> Testing ConvertFromPyObject using d.update((("a", %s),))
3652 d.update((("a", None),)):(<class 'vim.error'>, error("failed to add key 'a' to dictionary",))
3653 d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3654 d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3655 d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3656 d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3657 d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
3658 <<< Finished
3659 >> DictionaryPopItem
3660 d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
3661 >> DictionaryHasKey
3662 d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
3663 > List
3664 >> ListConstructor
3665 vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
3666 vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
3667 >>> Testing *Iter* using vim.List(%s)
3668 vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3669 vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3670 <<< Finished
3671 >>> Testing StringToChars using vim.List([{%s : 1}])
3672 vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3673 vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3674 vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3675 <<< Finished
3676 >>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
3677 vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3678 vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3679 vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3680 <<< Finished
3681 >>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
3682 vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3683 vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3684 vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3685 <<< Finished
3686 >>> Testing *Iter* using vim.List([{"abcF" : %s}])
3687 vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3688 vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3689 <<< Finished
3690 >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
3691 vim.List([{"abcF" : None}]):NOT FAILED
3692 vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3693 vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3694 vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3695 vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3696 vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3697 <<< Finished
3698 >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
3699 vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3700 vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3701 vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3702 <<< Finished
3703 >>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
3704 vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3705 vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3706 vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3707 <<< Finished
3708 >>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
3709 vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3710 vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3711 vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3712 <<< Finished
3713 >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
3714 vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3715 vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3716 <<< Finished
3717 >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
3718 vim.List([Mapping({"abcG" : None})]):NOT FAILED
3719 vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3720 vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3721 vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3722 vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3723 vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3724 <<< Finished
3725 >>> Testing *Iter* using vim.List([%s])
3726 vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3727 vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3728 <<< Finished
3729 >>> Testing ConvertFromPyObject using vim.List([%s])
3730 vim.List([None]):NOT FAILED
3731 vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3732 vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3733 vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3734 vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3735 vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3736 <<< Finished
3737 >> ListItem
3738 l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
3739 >> ListAssItem
3740 ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
3741 l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
3742 >> ListAssSlice
3743 ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
3744 >>> Testing *Iter* using l[:] = %s
3745 l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
3746 l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
3747 <<< Finished
3748 nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 2 to extended slice',))
3749 (b'a', b'b', b'c', b'O')
3750 nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
3751 (b'a', b'b', b'c', b'O')
3752 nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater than 0 to extended slice',))
3753 (b'a', b'b', b'c', b'O')
3754 nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
3755 (b'a', b'b', b'c', b'O')
3756 >>> Testing StringToChars using l[:] = [{%s : 1}]
3757 l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3758 l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3759 l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3760 <<< Finished
3761 >>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
3762 l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3763 l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3764 l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3765 <<< Finished
3766 >>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
3767 l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3768 l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3769 l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3770 <<< Finished
3771 >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
3772 l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3773 l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3774 <<< Finished
3775 >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
3776 l[:] = [{"abcF" : None}]:NOT FAILED
3777 l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3778 l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3779 l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3780 l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3781 l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3782 <<< Finished
3783 >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
3784 l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3785 l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3786 l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3787 <<< Finished
3788 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
3789 l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3790 l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3791 l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3792 <<< Finished
3793 >>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
3794 l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3795 l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3796 l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
3797 <<< Finished
3798 >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
3799 l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3800 l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3801 <<< Finished
3802 >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
3803 l[:] = [Mapping({"abcG" : None})]:NOT FAILED
3804 l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3805 l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3806 l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3807 l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3808 l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3809 <<< Finished
3810 >>> Testing *Iter* using l[:] = [%s]
3811 l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3812 l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
3813 <<< Finished
3814 >>> Testing ConvertFromPyObject using l[:] = [%s]
3815 l[:] = [None]:NOT FAILED
3816 l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3817 l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3818 l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
3819 l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3820 l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
3821 <<< Finished
3822 >> ListConcatInPlace
3823 >>> Testing *Iter* using l.extend(%s)
3824 l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
3825 l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3826 <<< Finished
3827 >>> Testing StringToChars using l.extend([{%s : 1}])
3828 l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3829 l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3830 l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3831 <<< Finished
3832 >>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
3833 l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3834 l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3835 l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3836 <<< Finished
3837 >>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
3838 l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3839 l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3840 l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3841 <<< Finished
3842 >>> Testing *Iter* using l.extend([{"abcF" : %s}])
3843 l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3844 l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3845 <<< Finished
3846 >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
3847 l.extend([{"abcF" : None}]):NOT FAILED
3848 l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3849 l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3850 l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3851 l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3852 l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3853 <<< Finished
3854 >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
3855 l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3856 l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3857 l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3858 <<< Finished
3859 >>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
3860 l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3861 l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3862 l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3863 <<< Finished
3864 >>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
3865 l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3866 l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3867 l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3868 <<< Finished
3869 >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
3870 l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3871 l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3872 <<< Finished
3873 >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
3874 l.extend([Mapping({"abcG" : None})]):NOT FAILED
3875 l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3876 l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3877 l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3878 l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3879 l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3880 <<< Finished
3881 >>> Testing *Iter* using l.extend([%s])
3882 l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3883 l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
3884 <<< Finished
3885 >>> Testing ConvertFromPyObject using l.extend([%s])
3886 l.extend([None]):NOT FAILED
3887 l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3888 l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3889 l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3890 l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3891 l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
3892 <<< Finished
3893 >> ListSetattr
3894 del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
3895 l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
3896 l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
3897 > Function
3898 >> FunctionConstructor
3899 >>> FunctionConstructor
3900 vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
3901 vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
3902 vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
3903 vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
3904 vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
3905 vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
3906 >>> FunctionNew
3907 vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
3908 vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to a Vim list',))
3909 vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3910 vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3911 vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
3912 vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
3913 >> FunctionCall
3914 >>> Testing StringToChars using f({%s : 1})
3915 f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3916 f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3917 f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3918 <<< Finished
3919 >>> Testing StringToChars using f({"abcF" : {%s : 1}})
3920 f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3921 f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3922 f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3923 <<< Finished
3924 >>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
3925 f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3926 f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3927 f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3928 <<< Finished
3929 >>> Testing *Iter* using f({"abcF" : %s})
3930 f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3931 f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3932 <<< Finished
3933 >>> Testing ConvertFromPyObject using f({"abcF" : %s})
3934 f({"abcF" : None}):NOT FAILED
3935 f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3936 f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3937 f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3938 f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3939 f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
3940 <<< Finished
3941 >>> Testing StringToChars using f(Mapping({%s : 1}))
3942 f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3943 f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3944 f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3945 <<< Finished
3946 >>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
3947 f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3948 f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3949 f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3950 <<< Finished
3951 >>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
3952 f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3953 f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3954 f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3955 <<< Finished
3956 >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
3957 f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3958 f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
3959 <<< Finished
3960 >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
3961 f(Mapping({"abcG" : None})):NOT FAILED
3962 f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3963 f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3964 f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3965 f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3966 f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
3967 <<< Finished
3968 >>> Testing *Iter* using f(%s)
3969 f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3970 f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
3971 <<< Finished
3972 >>> Testing ConvertFromPyObject using f(%s)
3973 f(None):NOT FAILED
3974 f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3975 f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
3976 f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
3977 f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
3978 f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
3979 <<< Finished
3980 >>> Testing StringToChars using fd(self={%s : 1})
3981 fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3982 fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3983 fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3984 <<< Finished
3985 >>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
3986 fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3987 fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3988 fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3989 <<< Finished
3990 >>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
3991 fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
3992 fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3993 fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
3994 <<< Finished
3995 >>> Testing *Iter* using fd(self={"abcF" : %s})
3996 fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
3997 fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
3998 <<< Finished
3999 >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
4000 fd(self={"abcF" : None}):NOT FAILED
4001 fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4002 fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4003 fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
4004 fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
4005 fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
4006 <<< Finished
4007 >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
4008 fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
4009 fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4010 fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4011 <<< Finished
4012 >>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
4013 fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
4014 fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4015 fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4016 <<< Finished
4017 >>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
4018 fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
4019 fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4020 fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
4021 <<< Finished
4022 >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
4023 fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim structure',))
4024 fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
4025 <<< Finished
4026 >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
4027 fd(self=Mapping({"abcG" : None})):NOT FAILED
4028 fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4029 fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4030 fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
4031 fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
4032 fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
4033 <<< Finished
4034 >>> Testing *Iter* using fd(self=%s)
4035 fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to a Vim dictionary',))
4036 fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to a Vim dictionary',))
4037 <<< Finished
4038 >>> Testing ConvertFromPyObject using fd(self=%s)
4039 fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to a Vim dictionary',))
4040 fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4041 fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
4042 fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
4043 fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
4044 fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to a Vim dictionary',))
4045 <<< Finished
4046 >>> Testing ConvertFromPyMapping using fd(self=%s)
4047 fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
4048 <<< Finished
4049 > TabPage
4050 >> TabPageAttr
4051 vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
4052 > TabList
4053 >> TabListItem
4054 vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
4055 > Window
4056 >> WindowAttr
4057 vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
4058 >> WindowSetattr
4059 vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
4060 vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
4061 vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
4062 >>> Testing NumberToLong using vim.current.window.height = %s
4063 vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
4064 vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
4065 vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
4066 <<< Finished
4067 >>> Testing NumberToLong using vim.current.window.width = %s
4068 vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
4069 vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
4070 vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
4071 <<< Finished
4072 vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
4073 > WinList
4074 >> WinListItem
4075 vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
4076 > Buffer
4077 >> StringToLine (indirect)
4078 vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
4079 vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
4080 >> SetBufferLine (indirect)
4081 vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
4082 >> SetBufferLineList (indirect)
4083 vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
4084 vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
4085 >> InsertBufferLines (indirect)
4086 vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
4087 vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
4088 vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
4089 >> RBItem
4090 vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
4091 >> RBAsItem
4092 vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
4093 >> BufferAttr
4094 vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
4095 >> BufferSetattr
4096 vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
4097 vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
4098 >> BufferMark
4099 vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
4100 vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
4101 vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
4102 >> BufferRange
4103 vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
4104 > BufMap
4105 >> BufMapItem
4106 vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
4107 >>> Testing NumberToLong using vim.buffers[%s]
4108 vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
4109 vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
4110 vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
4111 vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater than zero',))
4112 <<< Finished
4113 > Current
4114 >> CurrentGetattr
4115 vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
4116 >> CurrentSetattr
4117 vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
4118 vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
4119 vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
4120 vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
4121 vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
4122 END
4123
Bram Moolenaar68a48ee2020-10-27 19:59:10 +01004124 let actual = getline(2, '$')
4125 let n_expected = len(expected)
4126 let n_actual = len(actual)
4127 call assert_equal(n_expected, n_actual, 'number of lines to compare')
4128
4129 " Compare line by line so the errors are easier to understand. Missing lines
4130 " are compared with an empty string.
4131 for i in range(n_expected > n_actual ? n_expected : n_actual)
4132 call assert_equal(i >= n_expected ? '' : expected[i], i >= n_actual ? '' : actual[i])
4133 endfor
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02004134 close!
4135endfunc
4136
4137" Test import
4138func Test_python3_import()
4139 new
4140 py3 cb = vim.current.buffer
4141
4142 py3 << trim EOF
4143 sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
4144 sys.path.append(os.path.join(os.getcwd(), 'python_after'))
4145 vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
4146 l = []
4147 def callback(path):
4148 l.append(os.path.relpath(path))
4149 vim.foreach_rtp(callback)
4150 cb.append(repr(l))
4151 del l
4152 def callback(path):
4153 return os.path.relpath(path)
4154 cb.append(repr(vim.foreach_rtp(callback)))
4155 del callback
4156 from module import dir as d
4157 from modulex import ddir
4158 cb.append(d + ',' + ddir)
4159 import before
4160 cb.append(before.dir)
4161 import after
4162 cb.append(after.dir)
4163 import topmodule as tm
4164 import topmodule.submodule as tms
4165 import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
4166 cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
4167 cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
4168 cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
4169
4170 del before
4171 del after
4172 del d
4173 del ddir
4174 del tm
4175 del tms
4176 del tmsss
4177 EOF
4178
4179 let expected =<< trim END
4180 ['.']
4181 '.'
4182 3,xx
4183 before
4184 after
4185 pythonx/topmodule/__init__.py
4186 pythonx/topmodule/submodule/__init__.py
4187 pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
4188 END
4189 call assert_equal(expected, getline(2, '$'))
4190 close!
Bram Moolenaarab589462020-07-06 21:03:06 +02004191
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01004192 " Try to import a non-existing module with a dot (.)
Bram Moolenaarab589462020-07-06 21:03:06 +02004193 call AssertException(['py3 import a.b.c'], "No module named 'a'")
Bram Moolenaareffb0cd2020-07-03 21:17:34 +02004194endfunc
4195
4196" Test exceptions
4197func Test_python3_exception()
4198 func Exe(e)
4199 execute a:e
4200 endfunc
4201
4202 new
4203 py3 cb = vim.current.buffer
4204
4205 py3 << trim EOF
4206 Exe = vim.bindeval('function("Exe")')
4207 ee('vim.command("throw \'abcN\'")')
4208 ee('Exe("throw \'def\'")')
4209 ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
4210 ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
4211 ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
4212 ee('vim.eval("xxx_unknown_function_xxx()")')
4213 ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
4214 del Exe
4215 EOF
4216 delfunction Exe
4217
4218 let expected =<< trim END
4219 vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
4220 Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
4221 vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
4222 vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
4223 vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
4224 vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
4225 vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
4226 END
4227 call assert_equal(expected, getline(2, '$'))
4228 close!
4229endfunc
4230
4231" Regression: interrupting vim.command propagates to next vim.command
4232func Test_python3_keyboard_interrupt()
4233 new
4234 py3 cb = vim.current.buffer
4235 py3 << trim EOF
4236 def test_keyboard_interrupt():
4237 try:
4238 vim.command('while 1 | endwhile')
4239 except KeyboardInterrupt:
4240 cb.append('Caught KeyboardInterrupt')
4241 except Exception:
4242 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
4243 else:
4244 cb.append('!!!!!!!! No exception')
4245 try:
4246 vim.command('$ put =\'Running :put\'')
4247 except KeyboardInterrupt:
4248 cb.append('!!!!!!!! Caught KeyboardInterrupt')
4249 except Exception:
4250 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
4251 else:
4252 cb.append('No exception')
4253 EOF
4254
4255 debuggreedy
4256 call inputsave()
4257 call feedkeys("s\ns\ns\ns\nq\n")
4258 redir => output
4259 debug silent! py3 test_keyboard_interrupt()
4260 redir END
4261 0 debuggreedy
4262 call inputrestore()
4263 py3 del test_keyboard_interrupt
4264
4265 let expected =<< trim END
4266 Caught KeyboardInterrupt
4267 Running :put
4268 No exception
4269 END
4270 call assert_equal(expected, getline(2, '$'))
4271 call assert_equal('', output)
4272 close!
4273endfunc
4274
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004275" Regression: Iterator for a Vim object should hold a reference.
4276func Test_python3_iter_ref()
4277 let g:list_iter_ref_count_increase = -1
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01004278 let g:tuple_iter_ref_count_increase = -1
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004279 let g:dict_iter_ref_count_increase = -1
4280 let g:bufmap_iter_ref_count_increase = -1
4281 let g:options_iter_ref_count_increase = -1
4282
4283 py3 << trim EOF
4284 import sys
4285 import vim
4286
4287 def test_python3_iter_ref():
4288 create_list = vim.Function('Create_vim_list')
4289 v = create_list()
4290 base_ref_count = sys.getrefcount(v)
4291 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004292 vim.vars['list_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004293
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01004294 create_tuple = vim.Function('Create_vim_tuple')
4295 v = create_tuple()
4296 base_ref_count = sys.getrefcount(v)
4297 for el in v:
4298 vim.vars['tuple_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
4299
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004300 create_dict = vim.Function('Create_vim_dict')
4301 v = create_dict()
4302 base_ref_count = sys.getrefcount(v)
4303 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004304 vim.vars['dict_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004305
4306 v = vim.buffers
4307 base_ref_count = sys.getrefcount(v)
4308 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004309 vim.vars['bufmap_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004310
4311 v = vim.options
4312 base_ref_count = sys.getrefcount(v)
4313 for el in v:
Boris Staletic83a06702024-10-14 20:28:39 +02004314 vim.vars['options_iter_ref_count_increase'] = sys.getrefcount(v) - base_ref_count
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004315
4316 test_python3_iter_ref()
4317 EOF
4318
4319 call assert_equal(1, g:list_iter_ref_count_increase)
Yegappan Lakshmanan038be272025-03-26 18:46:21 +01004320 call assert_equal(1, g:tuple_iter_ref_count_increase)
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004321 call assert_equal(1, g:dict_iter_ref_count_increase)
Boris Staletic83a06702024-10-14 20:28:39 +02004322 if py3eval('sys.version_info[:2] < (3, 13)')
4323 call assert_equal(1, g:bufmap_iter_ref_count_increase)
4324 else
4325 call assert_equal(0, g:bufmap_iter_ref_count_increase)
4326 endif
Bram Moolenaar423a85a2020-08-29 12:57:16 +02004327 call assert_equal(1, g:options_iter_ref_count_increase)
4328endfunc
4329
Bram Moolenaar2e2f52a2020-12-21 16:03:02 +01004330func Test_python3_non_utf8_string()
4331 smap <Esc>@ <A-@>
4332 py3 vim.command('redir => _tmp_smaps | smap | redir END')
4333 py3 vim.eval('_tmp_smaps').splitlines()
4334 sunmap <Esc>@
4335endfunc
4336
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004337func Test_python3_fold_hidden_buffer()
4338 CheckFeature folding
4339
4340 set fdm=expr fde=Fde(v:lnum)
4341 let b:regex = '^'
4342 func Fde(lnum)
4343 let ld = [{}]
4344 let lines = bufnr('%')->getbufline(1, '$')
4345 let was_import = 0
4346 for lnum in range(1, len(lines))
4347 let line = lines[lnum]
4348 call add(ld, {'a': b:regex})
4349 let ld[lnum].foldexpr = was_import ? 1 : '>1'
4350 let was_import = 1
4351 endfor
4352 return ld[a:lnum].foldexpr
4353 endfunc
4354
4355 call setline(1, repeat([''], 15) + repeat(['from'], 3))
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004356 eval repeat(['x'], 17)->writefile('Xa.txt', 'D')
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004357 split Xa.txt
4358 py3 import vim
4359 py3 b = vim.current.buffer
4360 py3 aaa = b[:]
4361 hide
4362 py3 b[:] = aaa
4363
Bram Moolenaar3e0107e2021-01-02 13:53:59 +01004364 set fdm& fde&
4365 delfunc Fde
4366 bwipe! Xa.txt
4367endfunc
4368
Bram Moolenaar37233f62022-05-22 12:23:48 +01004369" Test to catch regression fix #10437.
4370func Test_python3_hidden_buf_mod_does_not_mess_up_display()
4371 CheckRunVimInTerminal
4372
4373 let testfile = 'Xtest.vim'
4374 let lines =<< trim END
4375 set hidden number
4376 new
4377 hide
4378 sil call setline(1, repeat(['aaa'], &lines) + ['bbbbbb'])
4379 fu Func()
4380 python3 << EOF
4381 import vim
4382 b = vim.buffers[2]
4383 b[:] = ['', '']
4384 EOF
4385 endfu
4386 norm! Gzb
4387 call feedkeys(":call Func()\r", 'n')
4388 END
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004389 call writefile(lines, testfile, 'D')
Bram Moolenaar37233f62022-05-22 12:23:48 +01004390
4391 let rows = 10
4392 let bufnr = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
4393 call TermWait(bufnr, 100)
4394 call assert_equal('run', job_status(term_getjob(bufnr)))
4395 let g:test_is_flaky = 0
4396 call WaitForAssert({-> assert_match('^ 3 aaa$', term_getline(bufnr, 1))})
4397 call WaitForAssert({-> assert_match('^ 11 bbbbbb$', term_getline(bufnr, rows - 1))})
4398
4399 call term_sendkeys(bufnr, ":qall!\<CR>")
4400 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(bufnr)))})
Bram Moolenaar145d1fd2022-09-30 21:57:11 +01004401
Bram Moolenaar37233f62022-05-22 12:23:48 +01004402 exe bufnr . 'bwipe!'
Bram Moolenaar37233f62022-05-22 12:23:48 +01004403endfunc
4404
Bram Moolenaar1363a302020-04-12 13:50:26 +02004405" vim: shiftwidth=2 sts=2 expandtab