blob: 187b80760fab74db42018add441520b36837895d [file] [log] [blame]
Bram Moolenaardb913952012-06-29 12:54:53 +02001Tests for various python features. vim: set ft=vim :
2
3STARTTEST
4:so small.vim
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02005:set noswapfile
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01006:if !has('python3') || !has('quickfix') | e! test.ok | wq! test.out | endif
Bram Moolenaarc24c1ac2013-05-16 20:47:56 +02007:lang C
Bram Moolenaardb913952012-06-29 12:54:53 +02008:fun Test()
Bram Moolenaar841fbd22013-06-23 14:37:07 +02009:py3 import vim
Bram Moolenaar8110a092016-04-14 15:56:09 +020010:py3 cb = vim.current.buffer
Bram Moolenaardb913952012-06-29 12:54:53 +020011:let l = []
12:py3 l=vim.bindeval('l')
13:py3 f=vim.bindeval('function("strlen")')
14:" Extending List directly with different types
15:py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]]
16:$put =string(l)
17:$put =string(l[-1])
18:try
19: $put =string(l[-4])
20:catch
21: $put =v:exception[:13]
22:endtry
23:" List assignment
24:py3 l[0]=0
25:$put =string(l)
26:py3 l[-2]=f
27:$put =string(l)
28:"
29:" Extending Dictionary directly with different types
30:let d = {}
Bram Moolenaar355fd9b2013-05-30 13:14:13 +020031:fun d.f()
32: return 1
33:endfun
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +020034py3 << trim EOF
35 d=vim.bindeval('d')
36 d['1']='asd'
37 d.update() # Must not do anything, including throwing errors
38 d.update(b=[1, 2, f])
39 d.update((('-1', {'a': 1}),))
40 d.update({'0': -1})
41 dk = d.keys()
42 dv = d.values()
43 di = d.items()
44 dk.sort(key=repr)
45 dv.sort(key=repr)
46 di.sort(key=repr)
Bram Moolenaara9922d62013-05-30 13:01:18 +020047EOF
Bram Moolenaar355fd9b2013-05-30 13:14:13 +020048:$put =py3eval('d[''f''](self={})')
Bram Moolenaara9922d62013-05-30 13:01:18 +020049:$put =py3eval('repr(dk)')
50:$put =substitute(py3eval('repr(dv)'),'0x\x\+','','g')
51:$put =substitute(py3eval('repr(di)'),'0x\x\+','','g')
Bram Moolenaar355fd9b2013-05-30 13:14:13 +020052:for [key, Val] in sort(items(d))
53: $put =string(key) . ' : ' . string(Val)
54: unlet key Val
Bram Moolenaardb913952012-06-29 12:54:53 +020055:endfor
Bram Moolenaar841fbd22013-06-23 14:37:07 +020056:py3 del dk
57:py3 del di
58:py3 del dv
Bram Moolenaardb913952012-06-29 12:54:53 +020059:"
60:" removing items with del
61:py3 del l[2]
62:$put =string(l)
63:let l = range(8)
64:py3 l=vim.bindeval('l')
65:try
66: py3 del l[:3]
67: py3 del l[1:]
68:catch
69: $put =v:exception
70:endtry
71:$put =string(l)
72:"
73:py3 del d['-1']
Bram Moolenaar355fd9b2013-05-30 13:14:13 +020074:py3 del d['f']
Bram Moolenaara9922d62013-05-30 13:01:18 +020075:$put =string(py3eval('d.get(''b'', 1)'))
76:$put =string(py3eval('d.pop(''b'')'))
77:$put =string(py3eval('d.get(''b'', 1)'))
78:$put =string(py3eval('d.pop(''1'', 2)'))
79:$put =string(py3eval('d.pop(''1'', 2)'))
80:$put =py3eval('repr(d.has_key(''0''))')
81:$put =py3eval('repr(d.has_key(''1''))')
82:$put =py3eval('repr(''0'' in d)')
83:$put =py3eval('repr(''1'' in d)')
84:$put =py3eval('repr(list(iter(d)))')
Bram Moolenaardb913952012-06-29 12:54:53 +020085:$put =string(d)
Bram Moolenaarde71b562013-06-02 17:41:54 +020086:$put =py3eval('repr(d.popitem())')
Bram Moolenaara9922d62013-05-30 13:01:18 +020087:$put =py3eval('repr(d.get(''0''))')
88:$put =py3eval('repr(list(iter(d)))')
Bram Moolenaardb913952012-06-29 12:54:53 +020089:"
90:" removing items out of range: silently skip items that don't exist
91:let l = [0, 1, 2, 3]
92:py3 l=vim.bindeval('l')
93:" The following two ranges delete nothing as they match empty list:
94:py3 del l[2:1]
95:$put =string(l)
96:py3 del l[2:2]
97:$put =string(l)
98:py3 del l[2:3]
99:$put =string(l)
100:let l = [0, 1, 2, 3]
101:py3 l=vim.bindeval('l')
102:py3 del l[2:4]
103:$put =string(l)
104:let l = [0, 1, 2, 3]
105:py3 l=vim.bindeval('l')
106:py3 del l[2:5]
107:$put =string(l)
108:let l = [0, 1, 2, 3]
109:py3 l=vim.bindeval('l')
110:py3 del l[2:6]
111:$put =string(l)
112:let l = [0, 1, 2, 3]
113:py3 l=vim.bindeval('l')
114:" The following two ranges delete nothing as they match empty list:
115:py3 del l[-1:2]
116:$put =string(l)
117:py3 del l[-2:2]
118:$put =string(l)
119:py3 del l[-3:2]
120:$put =string(l)
121:let l = [0, 1, 2, 3]
122:py3 l=vim.bindeval('l')
123:py3 del l[-4:2]
124:$put =string(l)
125:let l = [0, 1, 2, 3]
126:py3 l=vim.bindeval('l')
127:py3 del l[-5:2]
128:$put =string(l)
129:let l = [0, 1, 2, 3]
130:py3 l=vim.bindeval('l')
131:py3 del l[-6:2]
132:$put =string(l)
Bram Moolenaar063a46b2014-01-14 16:36:51 +0100133:let l = [0, 1, 2, 3]
134:py3 l=vim.bindeval('l')
135:py3 del l[::2]
136:$put =string(l)
137:let l = [0, 1, 2, 3]
138:py3 l=vim.bindeval('l')
139:py3 del l[3:0:-2]
140:$put =string(l)
141:let l = [0, 1, 2, 3]
142:py3 l=vim.bindeval('l')
143:py3 del l[2:4:-2]
144:$put =string(l)
Bram Moolenaardb913952012-06-29 12:54:53 +0200145:"
146:" Slice assignment to a list
147:let l = [0, 1, 2, 3]
148:py3 l=vim.bindeval('l')
149:py3 l[0:0]=['a']
150:$put =string(l)
151:let l = [0, 1, 2, 3]
152:py3 l=vim.bindeval('l')
153:py3 l[1:2]=['b']
154:$put =string(l)
155:let l = [0, 1, 2, 3]
156:py3 l=vim.bindeval('l')
157:py3 l[2:4]=['c']
158:$put =string(l)
159:let l = [0, 1, 2, 3]
160:py3 l=vim.bindeval('l')
161:py3 l[4:4]=['d']
162:$put =string(l)
163:let l = [0, 1, 2, 3]
164:py3 l=vim.bindeval('l')
165:py3 l[-1:2]=['e']
166:$put =string(l)
167:let l = [0, 1, 2, 3]
168:py3 l=vim.bindeval('l')
169:py3 l[-10:2]=['f']
170:$put =string(l)
171:let l = [0, 1, 2, 3]
172:py3 l=vim.bindeval('l')
173:py3 l[2:-10]=['g']
174:$put =string(l)
175:let l = []
176:py3 l=vim.bindeval('l')
177:py3 l[0:0]=['h']
178:$put =string(l)
Bram Moolenaar063a46b2014-01-14 16:36:51 +0100179:let l = range(8)
180:py3 l=vim.bindeval('l')
181:py3 l[2:6:2] = [10, 20]
182:$put =string(l)
183:let l = range(8)
184:py3 l=vim.bindeval('l')
185:py3 l[6:2:-2] = [10, 20]
186:$put =string(l)
187:let l = range(8)
188:py3 l=vim.bindeval('l')
189:py3 l[6:2] = ()
190:$put =string(l)
191:let l = range(8)
192:py3 l=vim.bindeval('l')
193:py3 l[6:2:1] = ()
194:$put =string(l)
195:let l = range(8)
196:py3 l=vim.bindeval('l')
197:py3 l[2:2:1] = ()
198:$put =string(l)
Bram Moolenaardb913952012-06-29 12:54:53 +0200199:"
200:" Locked variables
201:let l = [0, 1, 2, 3]
202:py3 l=vim.bindeval('l')
203:lockvar! l
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200204py3 << trim EOF
205 def emsg(ei):
206 return ei[0].__name__ + ':' + repr(ei[1].args)
Bram Moolenaar8110a092016-04-14 15:56:09 +0200207
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200208 try:
209 l[2]='i'
210 except vim.error:
211 cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
Bram Moolenaar8110a092016-04-14 15:56:09 +0200212EOF
Bram Moolenaardb913952012-06-29 12:54:53 +0200213:$put =string(l)
214:unlockvar! l
215:"
216:" Function calls
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200217py3 << trim EOF
218 import sys
219 import re
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100220
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200221 py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
222 py37_exception_repr = re.compile(r'([^\(\),])(\)+)$')
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100223
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200224 def ee(expr, g=globals(), l=locals()):
225 cb = vim.current.buffer
226 try:
227 try:
228 exec(expr, g, l)
229 except Exception as e:
230 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."):
231 msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))
232 elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
233 msg = repr((e.__class__, ImportError(str(e).replace("'", ''))))
234 elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError:
235 # Python 3.6 gives ModuleNotFoundError, change it to an ImportError
236 msg = repr((ImportError, ImportError(str(e).replace("'", ''))))
237 elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
238 m = py33_type_error_pattern.search(str(e))
239 if m:
240 msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
241 msg = repr((e.__class__, TypeError(msg)))
242 else:
243 msg = repr((e.__class__, e))
244 # Messages changed with Python 3.6, change new to old.
245 newmsg1 = """'argument must be str, bytes or bytearray, not None'"""
246 oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"'''
247 if msg.find(newmsg1) > -1:
248 msg = msg.replace(newmsg1, oldmsg1)
249 newmsg2 = """'argument must be str, bytes or bytearray, not int'"""
250 oldmsg2 = '''"Can't convert 'int' object to str implicitly"'''
251 if msg.find(newmsg2) > -1:
252 msg = msg.replace(newmsg2, oldmsg2)
253 elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
254 msg = repr((TypeError, TypeError('expected bytes with no null')))
255 else:
256 msg = repr((e.__class__, e))
257 # Some Python versions say can't, others cannot.
258 if msg.find('can\'t') > -1:
259 msg = msg.replace('can\'t', 'cannot')
260 # Some Python versions use single quote, some double quote
261 if msg.find('"cannot ') > -1:
262 msg = msg.replace('"cannot ', '\'cannot ')
263 if msg.find(' attributes"') > -1:
264 msg = msg.replace(' attributes"', ' attributes\'')
265 if sys.version_info >= (3, 7):
266 msg = py37_exception_repr.sub(r'\1,\2', msg)
267 cb.append(expr + ':' + msg)
268 else:
269 cb.append(expr + ':NOT FAILED')
270 except Exception as e:
271 msg = repr((e.__class__, e))
272 if sys.version_info >= (3, 7):
273 msg = py37_exception_repr.sub(r'\1,\2', msg)
274 cb.append(expr + '::' + msg)
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100275EOF
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200276:fun New(...)
277: return ['NewStart']+a:000+['NewEnd']
278:endfun
279:fun DictNew(...) dict
280: return ['DictNewStart']+a:000+['DictNewEnd', self]
281:endfun
Bram Moolenaardb913952012-06-29 12:54:53 +0200282:let l=[function('New'), function('DictNew')]
283:py3 l=vim.bindeval('l')
284:py3 l.extend(list(l[0](1, 2, 3)))
285:$put =string(l)
286:py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
287:$put =string(l)
288:py3 l+=[l[0].name]
289:$put =string(l)
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100290:py3 ee('l[1](1, 2, 3)')
Bram Moolenaar355fd9b2013-05-30 13:14:13 +0200291:py3 f=l[0]
Bram Moolenaardb913952012-06-29 12:54:53 +0200292:delfunction New
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100293:py3 ee('f(1, 2, 3)')
Bram Moolenaardb913952012-06-29 12:54:53 +0200294:if has('float')
295: let l=[0.0]
296: py3 l=vim.bindeval('l')
297: py3 l.extend([0.0])
298: $put =string(l)
299:else
300: $put ='[0.0, 0.0]'
301:endif
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200302:let messages=[]
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200303:delfunction DictNew
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200304py3 << trim EOF
305 import sys
306 d=vim.bindeval('{}')
307 m=vim.bindeval('messages')
308 def em(expr, g=globals(), l=locals()):
309 try:
310 exec(expr, g, l)
311 except Exception as e:
312 if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte':
313 m.extend([TypeError.__name__])
314 else:
315 m.extend([e.__class__.__name__])
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200316
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200317 em('d["abc1"]')
318 em('d["abc1"]="\\0"')
319 em('d["abc1"]=vim')
320 em('d[""]=1')
321 em('d["a\\0b"]=1')
322 em('d[b"a\\0b"]=1')
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200323
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200324 em('d.pop("abc1")')
325 em('d.popitem()')
326 del em
327 del m
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200328EOF
329:$put =messages
Bram Moolenaar66b79852012-09-21 14:00:35 +0200330:unlet messages
331:" locked and scope attributes
332:let d={} | let dl={} | lockvar dl
333:for s in split("d dl v: g:")
334: let name=tr(s, ':', 's')
335: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
336: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".py3eval(name.".".v:val)'), ';')
337: $put =toput
338:endfor
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200339:silent! let d.abc2=1
340:silent! let dl.abc3=1
Bram Moolenaar66b79852012-09-21 14:00:35 +0200341:py3 d.locked=True
342:py3 dl.locked=False
343:silent! let d.def=1
344:silent! let dl.def=1
345:put ='d:'.string(d)
346:put ='dl:'.string(dl)
347:unlet d dl
348:
349:let l=[] | let ll=[] | lockvar ll
350:for s in split("l ll")
351: let name=tr(s, ':', 's')
352: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
353: let toput=s.' : locked:'.py3eval(name.'.locked')
354: $put =toput
355:endfor
356:silent! call extend(l, [0])
357:silent! call extend(ll, [0])
358:py3 l.locked=True
359:py3 ll.locked=False
360:silent! call extend(l, [1])
361:silent! call extend(ll, [1])
362:put ='l:'.string(l)
363:put ='ll:'.string(ll)
364:unlet l ll
Bram Moolenaardb913952012-06-29 12:54:53 +0200365:"
366:" py3eval()
367:let l=py3eval('[0, 1, 2]')
368:$put =string(l)
369:let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}')
370:$put =sort(items(d))
Bram Moolenaar77324fc2016-01-17 22:37:03 +0100371:let v:errmsg = ''
372:$put ='py3eval(\"None\") = ' . py3eval('None') . v:errmsg
Bram Moolenaardb913952012-06-29 12:54:53 +0200373:if has('float')
374: let f=py3eval('0.0')
375: $put =string(f)
376:else
377: $put ='0.0'
378:endif
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200379:" Invalid values:
380:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim']
381: try
382: let v=py3eval(e)
383: catch
384: let toput=e.":\t".v:exception[:13]
385: $put =toput
386: endtry
387:endfor
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100388:"
389:" threading
390:let l = [0]
391:py3 l=vim.bindeval('l')
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200392py3 << trim EOF
393 import threading
394 import time
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100395
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200396 class T(threading.Thread):
397 def __init__(self):
398 threading.Thread.__init__(self)
399 self.t = 0
400 self.running = True
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100401
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200402 def run(self):
403 while self.running:
404 self.t += 1
405 time.sleep(0.1)
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100406
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200407 t = T()
408 del T
409 t.start()
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100410EOF
411:sleep 1
412:py3 t.running = False
413:py3 t.join()
Bram Moolenaar52f6ae12015-12-29 16:34:06 +0100414:" Check if the background thread is working. Count should be 10, but on a
415:" busy system (AppVeyor) it can be much lower.
416:py3 l[0] = t.t > 4
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200417:py3 del time
418:py3 del threading
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100419:py3 del t
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100420:$put =string(l)
421:"
422:" settrace
423:let l = []
424:py3 l=vim.bindeval('l')
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200425py3 << trim EOF
426 import sys
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100427
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200428 def traceit(frame, event, arg):
429 global l
430 if event == "line":
431 l += [frame.f_lineno]
432 return traceit
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100433
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200434 def trace_main():
435 for i in range(5):
436 pass
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100437EOF
438:py3 sys.settrace(traceit)
439:py3 trace_main()
Bram Moolenaardee2e312013-06-23 16:35:47 +0200440:py3 sys.settrace(None)
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200441:py3 del traceit
442:py3 del trace_main
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100443:$put =string(l)
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200444:"
Bram Moolenaar063a46b2014-01-14 16:36:51 +0100445:" Slice
446:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
447:py3 l = ll[:4]
448:$put =string(py3eval('l'))
449:py3 l = ll[2:]
450:$put =string(py3eval('l'))
451:py3 l = ll[:-4]
452:$put =string(py3eval('l'))
453:py3 l = ll[-2:]
454:$put =string(py3eval('l'))
455:py3 l = ll[2:4]
456:$put =string(py3eval('l'))
457:py3 l = ll[4:2]
458:$put =string(py3eval('l'))
459:py3 l = ll[-4:-2]
460:$put =string(py3eval('l'))
461:py3 l = ll[-2:-4]
462:$put =string(py3eval('l'))
463:py3 l = ll[:]
464:$put =string(py3eval('l'))
465:py3 l = ll[0:6]
466:$put =string(py3eval('l'))
467:py3 l = ll[-10:10]
468:$put =string(py3eval('l'))
469:py3 l = ll[4:2:-1]
470:$put =string(py3eval('l'))
471:py3 l = ll[::2]
472:$put =string(py3eval('l'))
473:py3 l = ll[4:2:1]
474:$put =string(py3eval('l'))
475:py3 del l
476:"
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200477:" Vars
478:let g:foo = 'bac'
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200479:let w:abc3 = 'def'
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200480:let b:baz = 'bar'
Bram Moolenaara4720012013-05-15 16:27:37 +0200481:let t:bar = 'jkl'
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200482:try
483: throw "Abc"
484:catch
485: put =py3eval('vim.vvars[''exception'']')
486:endtry
487:put =py3eval('vim.vars[''foo'']')
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200488:put =py3eval('vim.current.window.vars[''abc3'']')
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200489:put =py3eval('vim.current.buffer.vars[''baz'']')
Bram Moolenaara4720012013-05-15 16:27:37 +0200490:put =py3eval('vim.current.tabpage.vars[''bar'']')
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200491:"
492:" Options
493:" paste: boolean, global
494:" previewheight number, global
495:" operatorfunc: string, global
496:" number: boolean, window-local
497:" numberwidth: number, window-local
498:" colorcolumn: string, window-local
499:" statusline: string, window-local/global
500:" autoindent: boolean, buffer-local
Bram Moolenaar55b8ad32013-05-17 13:38:04 +0200501:" shiftwidth: number, buffer-local
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200502:" omnifunc: string, buffer-local
503:" preserveindent: boolean, buffer-local/global
504:" path: string, buffer-local/global
505:let g:bufs=[bufnr('%')]
506:new
507:let g:bufs+=[bufnr('%')]
508:vnew
509:let g:bufs+=[bufnr('%')]
510:wincmd j
511:vnew
512:let g:bufs+=[bufnr('%')]
513:wincmd l
514:fun RecVars(opt)
515: let gval =string(eval('&g:'.a:opt))
516: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))'))
517: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))'))
518: put =' G: '.gval
519: put =' W: '.wvals
520: put =' B: '.wvals
521:endfun
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200522py3 << trim EOF
523 def e(s, g=globals(), l=locals()):
524 try:
525 exec(s, g, l)
526 except Exception as e:
527 vim.command('return ' + repr(e.__class__.__name__))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200528
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200529 def ev(s, g=globals(), l=locals()):
530 try:
531 return eval(s, g, l)
532 except Exception as e:
533 vim.command('let exc=' + repr(e.__class__.__name__))
534 return 0
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200535EOF
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200536:fun E(s)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200537: python3 e(vim.eval('a:s'))
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200538:endfun
539:fun Ev(s)
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200540: let r=py3eval('ev(vim.eval("a:s"))')
541: if exists('exc')
542: throw exc
543: endif
544: return r
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200545:endfun
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200546:py3 gopts1=vim.options
547:py3 wopts1=vim.windows[2].options
548:py3 wopts2=vim.windows[0].options
549:py3 wopts3=vim.windows[1].options
550:py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
551:py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
552:py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
Bram Moolenaar1028f4d2014-01-14 16:55:00 +0100553:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)')
554:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)')
555:py3 gset=set(iter(gopts1))
556:py3 wset=set(iter(wopts1))
557:py3 bset=set(iter(bopts1))
Bram Moolenaar04188112013-06-01 20:32:12 +0200558:set path=.,..,,
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200559:let lst=[]
560:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
561:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]]
562:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
563:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
564:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200565:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]]
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200566:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
567:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
Bram Moolenaar55b8ad32013-05-17 13:38:04 +0200568:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200569:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]]
570:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]]
571:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]]
572:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
573: py3 oname=vim.eval('oname')
574: py3 oval1=vim.bindeval('oval1')
575: py3 oval2=vim.bindeval('oval2')
576: py3 oval3=vim.bindeval('oval3')
577: if invval is 0 || invval is 1
578: py3 invval=bool(vim.bindeval('invval'))
579: else
580: py3 invval=vim.bindeval('invval')
581: endif
582: if bool
583: py3 oval1=bool(oval1)
584: py3 oval2=bool(oval2)
585: py3 oval3=bool(oval3)
586: endif
587: put ='>>> '.oname
Bram Moolenaar1028f4d2014-01-14 16:55:00 +0100588: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset')
589: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1')
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200590: for v in ['gopts1', 'wopts1', 'bopts1']
591: try
592: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
593: catch
594: put =' p/'.v.'! '.v:exception
595: endtry
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200596: let r=E(v.'['''.oname.''']=invval')
597: if r isnot 0
598: put =' inv: '.string(invval).'! '.r
599: endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200600: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
601: let val=substitute(vv, '^.opts', 'oval', '')
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200602: let r=E(vv.'['''.oname.''']='.val)
603: if r isnot 0
604: put =' '.vv.'! '.r
605: endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200606: endfor
607: endfor
608: call RecVars(oname)
609: for v in ['wopts3', 'bopts3']
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200610: let r=E('del '.v.'["'.oname.'"]')
611: if r isnot 0
612: put =' del '.v.'! '.r
613: endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200614: endfor
615: call RecVars(oname)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200616:endfor
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200617:delfunction RecVars
618:delfunction E
619:delfunction Ev
620:py3 del ev
621:py3 del e
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200622:only
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200623:for buf in g:bufs[1:]
624: execute 'bwipeout!' buf
625:endfor
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200626:py3 del gopts1
627:py3 del wopts1
628:py3 del wopts2
629:py3 del wopts3
630:py3 del bopts1
631:py3 del bopts2
632:py3 del bopts3
633:py3 del oval1
634:py3 del oval2
635:py3 del oval3
636:py3 del oname
637:py3 del invval
Bram Moolenaarbd80f352013-05-12 21:16:23 +0200638:"
639:" Test buffer object
640:vnew
641:put ='First line'
642:put ='Second line'
643:put ='Third line'
644:1 delete _
645:py3 b=vim.current.buffer
646:wincmd w
647:mark a
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200648:augroup BUFS
649: autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
650: autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
651:augroup END
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200652py3 << trim EOF
653 # Tests BufferAppend and BufferItem
654 cb.append(b[0])
655 # Tests BufferSlice and BufferAssSlice
656 cb.append('abc5') # Will be overwritten
657 cb[-1:] = b[:-2]
658 # Test BufferLength and BufferAssSlice
659 cb.append('def') # Will not be overwritten
660 cb[len(cb):] = b[:]
661 # Test BufferAssItem and BufferMark
662 cb.append('ghi') # Will be overwritten
663 cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
664 # Test BufferRepr
665 cb.append(repr(cb) + repr(b))
666 # Modify foreign buffer
667 b.append('foo')
668 b[0]='bar'
669 b[0:0]=['baz']
670 vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
671 # Test assigning to name property
672 import os
673 old_name = cb.name
674 cb.name = 'foo'
675 cb.append(cb.name[-11:].replace(os.path.sep, '/'))
676 b.name = 'bar'
677 cb.append(b.name[-11:].replace(os.path.sep, '/'))
678 cb.name = old_name
679 cb.append(cb.name[-17:].replace(os.path.sep, '/'))
680 del old_name
681 # Test CheckBuffer
682 for _b in vim.buffers:
683 if _b is not cb:
684 vim.command('bwipeout! ' + str(_b.number))
685 del _b
686 cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
687 for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
688 try:
689 exec(expr)
690 except vim.error:
691 pass
692 else:
693 # Usually a SEGV here
694 # Should not happen in any case
695 cb.append('No exception for ' + expr)
696 vim.command('cd .')
697 del b
Bram Moolenaarbd80f352013-05-12 21:16:23 +0200698EOF
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200699:"
700:" Test vim.buffers object
701:set hidden
702:edit a
703:buffer #
704:edit b
705:buffer #
706:edit c
707:buffer #
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200708py3 << trim EOF
709 # Check GCing iterator that was not fully exhausted
710 i = iter(vim.buffers)
711 cb.append('i:' + str(next(i)))
712 # and also check creating more than one iterator at a time
713 i2 = iter(vim.buffers)
714 cb.append('i2:' + str(next(i2)))
715 cb.append('i:' + str(next(i)))
716 # The following should trigger GC and not cause any problems
717 del i
718 del i2
719 i3 = iter(vim.buffers)
720 cb.append('i3:' + str(next(i3)))
721 del i3
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200722
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200723 prevnum = 0
724 for b in vim.buffers:
725 # Check buffer order
726 if prevnum >= b.number:
727 cb.append('!!! Buffer numbers not in strictly ascending order')
728 # Check indexing: vim.buffers[number].number == number
729 cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
730 prevnum = b.number
731 del prevnum
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200732
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200733 cb.append(str(len(vim.buffers)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200734
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200735 bnums = list(map(lambda b: b.number, vim.buffers))[1:]
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200736
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200737 # Test wiping out buffer with existing iterator
738 i4 = iter(vim.buffers)
739 cb.append('i4:' + str(next(i4)))
740 vim.command('bwipeout! ' + str(bnums.pop(0)))
741 try:
742 next(i4)
743 except vim.error:
744 pass
745 else:
746 cb.append('!!!! No vim.error')
747 i4 = iter(vim.buffers)
748 vim.command('bwipeout! ' + str(bnums.pop(-1)))
749 vim.command('bwipeout! ' + str(bnums.pop(-1)))
750 cb.append('i4:' + str(next(i4)))
751 try:
752 next(i4)
753 except StopIteration:
754 cb.append('StopIteration')
755 del i4
756 del bnums
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200757EOF
Bram Moolenaara4720012013-05-15 16:27:37 +0200758:"
759:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
760:tabnew 0
761:tabnew 1
762:vnew a.1
763:tabnew 2
764:vnew a.2
765:vnew b.2
766:vnew c.2
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200767py3 << trim EOF
768 cb.append('Number of tabs: ' + str(len(vim.tabpages)))
769 cb.append('Current tab pages:')
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +0200770
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200771 def W(w):
772 if '(unknown)' in repr(w):
773 return '<window object (unknown)>'
774 else:
775 return repr(w)
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +0200776
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200777 def Cursor(w, start=len(cb)):
778 if w.buffer is cb:
779 return repr((start - w.cursor[0], w.cursor[1]))
780 else:
781 return repr(w.cursor)
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +0200782
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200783 for t in vim.tabpages:
784 cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
785 cb.append(' Windows:')
786 for w in t.windows:
787 cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w))
788 # Other values depend on the size of the terminal, so they are checked partly:
789 for attr in ('height', 'row', 'width', 'col'):
790 try:
791 aval = getattr(w, attr)
792 if type(aval) is not int:
793 raise TypeError
794 if aval < 0:
795 raise ValueError
796 except Exception as e:
797 cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__)
798 del aval
799 del attr
800 w.cursor = (len(w.buffer), 0)
801 del W
802 del Cursor
803 cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
804 if list(vim.windows) != list(vim.current.tabpage.windows):
805 cb.append('!!!!!! Windows differ')
Bram Moolenaara4720012013-05-15 16:27:37 +0200806EOF
807:"
808:" Test vim.current
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200809py3 << trim EOF
810 def H(o):
811 return repr(o)
812 cb.append('Current tab page: ' + repr(vim.current.tabpage))
813 cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
814 cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
815 del H
816 # Assigning: fails
817 try:
818 vim.current.window = vim.tabpages[0].window
819 except ValueError:
820 cb.append('ValueError at assigning foreign tab window')
Bram Moolenaara4720012013-05-15 16:27:37 +0200821
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200822 for attr in ('window', 'tabpage', 'buffer'):
823 try:
824 setattr(vim.current, attr, None)
825 except TypeError:
826 cb.append('Type error at assigning None to vim.current.' + attr)
827 del attr
Bram Moolenaara4720012013-05-15 16:27:37 +0200828
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200829 # Assigning: success
830 vim.current.tabpage = vim.tabpages[-2]
831 vim.current.buffer = cb
832 vim.current.window = vim.windows[0]
833 vim.current.window.cursor = (len(vim.current.buffer), 0)
834 cb.append('Current tab page: ' + repr(vim.current.tabpage))
835 cb.append('Current window: ' + repr(vim.current.window))
836 cb.append('Current buffer: ' + repr(vim.current.buffer))
837 cb.append('Current line: ' + repr(vim.current.line))
838 ws = list(vim.windows)
839 ts = list(vim.tabpages)
840 for b in vim.buffers:
841 if b is not cb:
842 vim.command('bwipeout! ' + str(b.number))
843 del b
844 cb.append('w.valid: ' + repr([w.valid for w in ws]))
845 cb.append('t.valid: ' + repr([t.valid for t in ts]))
846 del w
847 del t
848 del ts
849 del ws
Bram Moolenaara4720012013-05-15 16:27:37 +0200850EOF
851:tabonly!
852:only!
Bram Moolenaarcac867a2013-05-21 19:50:34 +0200853:"
854:" Test types
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200855py3 << trim EOF
856 for expr, attr in (
857 ('vim.vars', 'Dictionary'),
858 ('vim.options', 'Options'),
859 ('vim.bindeval("{}")', 'Dictionary'),
860 ('vim.bindeval("[]")', 'List'),
861 ('vim.bindeval("function(\'tr\')")', 'Function'),
862 ('vim.current.buffer', 'Buffer'),
863 ('vim.current.range', 'Range'),
864 ('vim.current.window', 'Window'),
865 ('vim.current.tabpage', 'TabPage'),
866 ):
867 cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
868 del expr
869 del attr
Bram Moolenaarcac867a2013-05-21 19:50:34 +0200870EOF
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200871:"
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200872:" Test __dir__() method
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200873py3 << trim EOF
874 for name, o in (
875 ('current', vim.current),
876 ('buffer', vim.current.buffer),
877 ('window', vim.current.window),
878 ('tabpage', vim.current.tabpage),
879 ('range', vim.current.range),
880 ('dictionary', vim.bindeval('{}')),
881 ('list', vim.bindeval('[]')),
882 ('function', vim.bindeval('function("tr")')),
883 ('output', sys.stdout),
884 ):
885 cb.append(name + ':' + ','.join(dir(o)))
886 del name
887 del o
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200888EOF
889:"
Bram Moolenaar78cddbe2013-05-30 13:05:58 +0200890:" Test vim.*.__new__
Bram Moolenaara9922d62013-05-30 13:01:18 +0200891:$put =string(py3eval('vim.Dictionary({})'))
892:$put =string(py3eval('vim.Dictionary(a=1)'))
893:$put =string(py3eval('vim.Dictionary(((''a'', 1),))'))
Bram Moolenaar78cddbe2013-05-30 13:05:58 +0200894:$put =string(py3eval('vim.List()'))
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200895:$put =string(py3eval('vim.List(iter(''abc7''))'))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +0200896:$put =string(py3eval('vim.Function(''tr'')'))
Bram Moolenaar8110a092016-04-14 15:56:09 +0200897:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
898:$put =string(py3eval('vim.Function(''tr'', args=[])'))
899:$put =string(py3eval('vim.Function(''tr'', self={})'))
900:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
Bram Moolenaar2177f9f2016-05-25 20:39:09 +0200901:$put ='auto_rebind'
902:$put =string(py3eval('vim.Function(''tr'', auto_rebind=False)'))
903:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
904:$put =string(py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
905:$put =string(py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
906:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
Bram Moolenaar8110a092016-04-14 15:56:09 +0200907:"
908:" Test vim.Function
909:function Args(...)
910: return a:000
911:endfunction
912:function SelfArgs(...) dict
913: return [a:000, self]
914:endfunction
915:" The following four lines should not crash
916:let Pt = function('tr', [[]], {'l': []})
917:py3 Pt = vim.bindeval('Pt')
918:unlet Pt
919:py3 del Pt
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200920py3 << trim EOF
921 def ecall(out_prefix, func, *args, **kwargs):
922 line = out_prefix + ': '
923 try:
924 ret = func(*args, **kwargs)
925 except Exception:
926 line += '!exception: ' + emsg(sys.exc_info())
927 else:
928 line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
929 cb.append(line)
930 a = vim.Function('Args')
931 pa1 = vim.Function('Args', args=['abcArgsPA1'])
932 pa2 = vim.Function('Args', args=[])
933 pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
934 pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
935 cb.append('a: ' + repr(a))
936 cb.append('pa1: ' + repr(pa1))
937 cb.append('pa2: ' + repr(pa2))
938 cb.append('pa3: ' + repr(pa3))
939 cb.append('pa4: ' + repr(pa4))
940 sa = vim.Function('SelfArgs')
941 psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
942 psa2 = vim.Function('SelfArgs', args=[])
943 psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
944 psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
945 psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
946 psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
947 psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
948 psa8 = vim.Function('SelfArgs', auto_rebind=False)
949 psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
950 psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
951 psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
952 psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
953 cb.append('sa: ' + repr(sa))
954 cb.append('psa1: ' + repr(psa1))
955 cb.append('psa2: ' + repr(psa2))
956 cb.append('psa3: ' + repr(psa3))
957 cb.append('psa4: ' + repr(psa4))
958 cb.append('psa5: ' + repr(psa5))
959 cb.append('psa6: ' + repr(psa6))
960 cb.append('psa7: ' + repr(psa7))
961 cb.append('psa8: ' + repr(psa8))
962 cb.append('psa9: ' + repr(psa9))
963 cb.append('psaA: ' + repr(psaA))
964 cb.append('psaB: ' + repr(psaB))
965 cb.append('psaC: ' + repr(psaC))
Bram Moolenaar8110a092016-04-14 15:56:09 +0200966
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200967 psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
968 psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
969 psar.self['rec'] = psar
970 psar.self['self'] = psar.self
971 psar.self['args'] = psar.args
Bram Moolenaar8110a092016-04-14 15:56:09 +0200972
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200973 try:
974 cb.append('psar: ' + repr(psar))
975 except Exception:
976 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
Bram Moolenaar8110a092016-04-14 15:56:09 +0200977EOF
978:$put ='s(a): '.string(py3eval('a'))
979:$put ='s(pa1): '.string(py3eval('pa1'))
980:$put ='s(pa2): '.string(py3eval('pa2'))
981:$put ='s(pa3): '.string(py3eval('pa3'))
982:$put ='s(pa4): '.string(py3eval('pa4'))
983:$put ='s(sa): '.string(py3eval('sa'))
984:$put ='s(psa1): '.string(py3eval('psa1'))
985:$put ='s(psa2): '.string(py3eval('psa2'))
986:$put ='s(psa3): '.string(py3eval('psa3'))
987:$put ='s(psa4): '.string(py3eval('psa4'))
Bram Moolenaar2177f9f2016-05-25 20:39:09 +0200988:$put ='s(psa5): '.string(py3eval('psa5'))
989:$put ='s(psa6): '.string(py3eval('psa6'))
990:$put ='s(psa7): '.string(py3eval('psa7'))
991:$put ='s(psa8): '.string(py3eval('psa8'))
992:$put ='s(psa9): '.string(py3eval('psa9'))
993:$put ='s(psaA): '.string(py3eval('psaA'))
994:$put ='s(psaB): '.string(py3eval('psaB'))
995:$put ='s(psaC): '.string(py3eval('psaC'))
996:
997:for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
998: let d = {'f': py3eval(v)}
999: $put ='d.'.v.'(): '.string(d.f())
1000:endfor
Bram Moolenaar8110a092016-04-14 15:56:09 +02001001:
1002:py3 ecall('a()', a, )
1003:py3 ecall('pa1()', pa1, )
1004:py3 ecall('pa2()', pa2, )
1005:py3 ecall('pa3()', pa3, )
1006:py3 ecall('pa4()', pa4, )
1007:py3 ecall('sa()', sa, )
1008:py3 ecall('psa1()', psa1, )
1009:py3 ecall('psa2()', psa2, )
1010:py3 ecall('psa3()', psa3, )
1011:py3 ecall('psa4()', psa4, )
1012:
1013:py3 ecall('a(42, 43)', a, 42, 43)
1014:py3 ecall('pa1(42, 43)', pa1, 42, 43)
1015:py3 ecall('pa2(42, 43)', pa2, 42, 43)
1016:py3 ecall('pa3(42, 43)', pa3, 42, 43)
1017:py3 ecall('pa4(42, 43)', pa4, 42, 43)
1018:py3 ecall('sa(42, 43)', sa, 42, 43)
1019:py3 ecall('psa1(42, 43)', psa1, 42, 43)
1020:py3 ecall('psa2(42, 43)', psa2, 42, 43)
1021:py3 ecall('psa3(42, 43)', psa3, 42, 43)
1022:py3 ecall('psa4(42, 43)', psa4, 42, 43)
1023:
1024:py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
1025:py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
1026:py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
1027:py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
1028:py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
1029:py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
1030:py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
1031:py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
1032:py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
1033:py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
1034:
1035:py3 ecall('a(self={"20": 1})', a, self={'20': 1})
1036:py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
1037:py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
1038:py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
1039:py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
1040:py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
1041:py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
1042:py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
1043:py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
1044:py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001045py3 << trim EOF
1046 def s(v):
1047 if v is None:
1048 return repr(v)
1049 else:
1050 return str(vim.Function('string')(v), 'utf-8')
Bram Moolenaar8110a092016-04-14 15:56:09 +02001051
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001052 cb.append('a.args: ' + s(a.args))
1053 cb.append('pa1.args: ' + s(pa1.args))
1054 cb.append('pa2.args: ' + s(pa2.args))
1055 cb.append('pa3.args: ' + s(pa3.args))
1056 cb.append('pa4.args: ' + s(pa4.args))
1057 cb.append('sa.args: ' + s(sa.args))
1058 cb.append('psa1.args: ' + s(psa1.args))
1059 cb.append('psa2.args: ' + s(psa2.args))
1060 cb.append('psa3.args: ' + s(psa3.args))
1061 cb.append('psa4.args: ' + s(psa4.args))
Bram Moolenaar8110a092016-04-14 15:56:09 +02001062
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001063 cb.append('a.self: ' + s(a.self))
1064 cb.append('pa1.self: ' + s(pa1.self))
1065 cb.append('pa2.self: ' + s(pa2.self))
1066 cb.append('pa3.self: ' + s(pa3.self))
1067 cb.append('pa4.self: ' + s(pa4.self))
1068 cb.append('sa.self: ' + s(sa.self))
1069 cb.append('psa1.self: ' + s(psa1.self))
1070 cb.append('psa2.self: ' + s(psa2.self))
1071 cb.append('psa3.self: ' + s(psa3.self))
1072 cb.append('psa4.self: ' + s(psa4.self))
Bram Moolenaar8110a092016-04-14 15:56:09 +02001073
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001074 cb.append('a.name: ' + s(a.name))
1075 cb.append('pa1.name: ' + s(pa1.name))
1076 cb.append('pa2.name: ' + s(pa2.name))
1077 cb.append('pa3.name: ' + s(pa3.name))
1078 cb.append('pa4.name: ' + s(pa4.name))
1079 cb.append('sa.name: ' + s(sa.name))
1080 cb.append('psa1.name: ' + s(psa1.name))
1081 cb.append('psa2.name: ' + s(psa2.name))
1082 cb.append('psa3.name: ' + s(psa3.name))
1083 cb.append('psa4.name: ' + s(psa4.name))
Bram Moolenaar8110a092016-04-14 15:56:09 +02001084
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001085 cb.append('a.auto_rebind: ' + s(a.auto_rebind))
1086 cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
1087 cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
1088 cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
1089 cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
1090 cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
1091 cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
1092 cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
1093 cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
1094 cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
1095 cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
1096 cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
1097 cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
1098 cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
1099 cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
1100 cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
1101 cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
1102 cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02001103
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001104 del s
Bram Moolenaar8110a092016-04-14 15:56:09 +02001105
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001106 del a
1107 del pa1
1108 del pa2
1109 del pa3
1110 del pa4
1111 del sa
1112 del psa1
1113 del psa2
1114 del psa3
1115 del psa4
1116 del psa5
1117 del psa6
1118 del psa7
1119 del psa8
1120 del psa9
1121 del psaA
1122 del psaB
1123 del psaC
1124 del psar
Bram Moolenaar8110a092016-04-14 15:56:09 +02001125
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001126 del ecall
Bram Moolenaar8110a092016-04-14 15:56:09 +02001127EOF
Bram Moolenaar01a7a722013-05-30 12:26:58 +02001128:"
1129:" Test stdout/stderr
1130:redir => messages
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001131:py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
1132:py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
1133:py3 sys.stdout.writelines(iter('abcA'))
1134:py3 sys.stderr.writelines(iter('abcB'))
Bram Moolenaar01a7a722013-05-30 12:26:58 +02001135:redir END
1136:$put =string(substitute(messages, '\d\+', '', 'g'))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001137:" Test subclassing
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001138:fun Put(...)
1139: $put =string(a:000)
1140: return a:000
1141:endfun
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001142py3 << trim EOF
1143 class DupDict(vim.Dictionary):
1144 def __setitem__(self, key, value):
1145 super(DupDict, self).__setitem__(key, value)
1146 super(DupDict, self).__setitem__('dup_' + key, value)
1147 dd = DupDict()
1148 dd['a'] = 'b'
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001149
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001150 class DupList(vim.List):
1151 def __getitem__(self, idx):
1152 return [super(DupList, self).__getitem__(idx)] * 2
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001153
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001154 dl = DupList()
1155 dl2 = DupList(iter('abcC'))
1156 dl.extend(dl2[0])
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001157
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001158 class DupFun(vim.Function):
1159 def __call__(self, arg):
1160 return super(DupFun, self).__call__(arg, arg)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001161
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001162 df = DupFun('Put')
Bram Moolenaara9922d62013-05-30 13:01:18 +02001163EOF
1164:$put =string(sort(keys(py3eval('dd'))))
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001165:$put =string(py3eval('dl'))
1166:$put =string(py3eval('dl2'))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001167:$put =string(py3eval('df(2)'))
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001168:$put =string(py3eval('dl') is# py3eval('dl'))
1169:$put =string(py3eval('dd') is# py3eval('dd'))
1170:$put =string(py3eval('df'))
1171:delfunction Put
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001172py3 << trim EOF
1173 del DupDict
1174 del DupList
1175 del DupFun
1176 del dd
1177 del dl
1178 del dl2
1179 del df
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001180EOF
Bram Moolenaar01a7a722013-05-30 12:26:58 +02001181:"
Bram Moolenaarf4258302013-06-02 18:20:17 +02001182:" Test chdir
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001183py3 << trim EOF
1184 import os
1185 fnamemodify = vim.Function('fnamemodify')
1186 cb.append(str(fnamemodify('.', ':p:h:t')))
1187 cb.append(vim.eval('@%'))
Bram Moolenaar91376b62015-12-11 16:17:02 +01001188 os.chdir('..')
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001189 path = fnamemodify('.', ':p:h:t')
1190 if path != b'src':
1191 # Running tests from a shadow directory, so move up another level
1192 # This will result in @% looking like shadow/testdir/test87.in, hence the
1193 # slicing to remove the leading path and path separator
1194 os.chdir('..')
1195 cb.append(str(fnamemodify('.', ':p:h:t')))
1196 cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/'))
1197 os.chdir(path)
1198 else:
1199 cb.append(str(fnamemodify('.', ':p:h:t')))
1200 cb.append(vim.eval('@%').replace(os.path.sep, '/'))
1201 del path
1202 os.chdir('testdir')
Bram Moolenaar91376b62015-12-11 16:17:02 +01001203 cb.append(str(fnamemodify('.', ':p:h:t')))
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001204 cb.append(vim.eval('@%'))
1205 del fnamemodify
Bram Moolenaarf4258302013-06-02 18:20:17 +02001206EOF
1207:"
Bram Moolenaar8600e402013-05-30 13:28:41 +02001208:" Test errors
1209:fun F() dict
1210:endfun
1211:fun D()
1212:endfun
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001213py3 << trim EOF
1214 d = vim.Dictionary()
1215 ned = vim.Dictionary(foo='bar', baz='abcD')
1216 dl = vim.Dictionary(a=1)
1217 dl.locked = True
1218 l = vim.List()
1219 ll = vim.List('abcE')
1220 ll.locked = True
1221 nel = vim.List('abcO')
1222 f = vim.Function('string')
1223 fd = vim.Function('F')
1224 fdel = vim.Function('D')
1225 vim.command('delfunction D')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001226
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001227 def subexpr_test(expr, name, subexprs):
1228 cb.append('>>> Testing %s using %s' % (name, expr))
1229 for subexpr in subexprs:
1230 ee(expr % subexpr)
1231 cb.append('<<< Finished')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001232
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001233 def stringtochars_test(expr):
1234 return subexpr_test(expr, 'StringToChars', (
1235 '1', # Fail type checks
1236 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
1237 '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
1238 ))
Bram Moolenaar8600e402013-05-30 13:28:41 +02001239
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001240 class Mapping(object):
1241 def __init__(self, d):
1242 self.d = d
Bram Moolenaar8600e402013-05-30 13:28:41 +02001243
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001244 def __getitem__(self, key):
1245 return self.d[key]
Bram Moolenaar8600e402013-05-30 13:28:41 +02001246
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001247 def keys(self):
1248 return self.d.keys()
Bram Moolenaar8600e402013-05-30 13:28:41 +02001249
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001250 def items(self):
1251 return self.d.items()
Bram Moolenaar8600e402013-05-30 13:28:41 +02001252
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001253 def convertfrompyobject_test(expr, recurse=True):
1254 # pydict_to_tv
1255 stringtochars_test(expr % '{%s : 1}')
1256 if recurse:
1257 convertfrompyobject_test(expr % '{"abcF" : %s}', False)
1258 # pymap_to_tv
1259 stringtochars_test(expr % 'Mapping({%s : 1})')
1260 if recurse:
1261 convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
1262 # pyseq_to_tv
1263 iter_test(expr)
1264 return subexpr_test(expr, 'ConvertFromPyObject', (
1265 'None', # Not conversible
1266 '{b"": 1}', # Empty key not allowed
1267 '{"": 1}', # Same, but with unicode object
1268 'FailingMapping()', #
1269 'FailingMappingKey()', #
1270 'FailingNumber()', #
1271 ))
Bram Moolenaar8600e402013-05-30 13:28:41 +02001272
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001273 def convertfrompymapping_test(expr):
1274 convertfrompyobject_test(expr)
1275 return subexpr_test(expr, 'ConvertFromPyMapping', (
1276 '[]',
1277 ))
Bram Moolenaar8600e402013-05-30 13:28:41 +02001278
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001279 def iter_test(expr):
1280 return subexpr_test(expr, '*Iter*', (
1281 'FailingIter()',
1282 'FailingIterNext()',
1283 ))
Bram Moolenaar8600e402013-05-30 13:28:41 +02001284
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001285 def number_test(expr, natural=False, unsigned=False):
1286 if natural:
1287 unsigned = True
1288 return subexpr_test(expr, 'NumberToLong', (
1289 '[]',
1290 'None',
1291 ) + (('-1',) if unsigned else ())
1292 + (('0',) if natural else ()))
Bram Moolenaardee2e312013-06-23 16:35:47 +02001293
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001294 class FailingTrue(object):
1295 def __bool__(self):
1296 raise NotImplementedError('bool')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001297
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001298 class FailingIter(object):
1299 def __iter__(self):
1300 raise NotImplementedError('iter')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001301
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001302 class FailingIterNext(object):
1303 def __iter__(self):
1304 return self
Bram Moolenaar8600e402013-05-30 13:28:41 +02001305
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001306 def __next__(self):
1307 raise NotImplementedError('next')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001308
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001309 class FailingIterNextN(object):
1310 def __init__(self, n):
1311 self.n = n
Bram Moolenaar063a46b2014-01-14 16:36:51 +01001312
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001313 def __iter__(self):
1314 return self
Bram Moolenaar063a46b2014-01-14 16:36:51 +01001315
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001316 def __next__(self):
1317 if self.n:
1318 self.n -= 1
1319 return 1
1320 else:
1321 raise NotImplementedError('next N')
Bram Moolenaar063a46b2014-01-14 16:36:51 +01001322
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001323 class FailingMappingKey(object):
1324 def __getitem__(self, item):
1325 raise NotImplementedError('getitem:mappingkey')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001326
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001327 def keys(self):
1328 return list("abcH")
Bram Moolenaar8600e402013-05-30 13:28:41 +02001329
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001330 class FailingMapping(object):
1331 def __getitem__(self):
1332 raise NotImplementedError('getitem:mapping')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001333
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001334 def keys(self):
1335 raise NotImplementedError('keys')
Bram Moolenaar8600e402013-05-30 13:28:41 +02001336
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001337 class FailingList(list):
1338 def __getitem__(self, idx):
1339 if i == 2:
1340 raise NotImplementedError('getitem:list')
1341 else:
1342 return super(FailingList, self).__getitem__(idx)
Bram Moolenaar8600e402013-05-30 13:28:41 +02001343
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001344 class NoArgsCall(object):
1345 def __call__(self):
1346 pass
Bram Moolenaardee2e312013-06-23 16:35:47 +02001347
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001348 class FailingCall(object):
1349 def __call__(self, path):
1350 raise NotImplementedError('call')
Bram Moolenaardee2e312013-06-23 16:35:47 +02001351
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001352 class FailingNumber(object):
1353 def __int__(self):
1354 raise NotImplementedError('int')
Bram Moolenaardee2e312013-06-23 16:35:47 +02001355
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001356 cb.append("> Output")
1357 cb.append(">> OutputSetattr")
1358 ee('del sys.stdout.softspace')
1359 number_test('sys.stdout.softspace = %s', unsigned=True)
1360 number_test('sys.stderr.softspace = %s', unsigned=True)
1361 ee('assert sys.stdout.isatty()==False')
1362 ee('assert sys.stdout.seekable()==False')
1363 ee('sys.stdout.close()')
1364 ee('sys.stdout.flush()')
1365 ee('assert sys.stderr.isatty()==False')
1366 ee('assert sys.stderr.seekable()==False')
1367 ee('sys.stderr.close()')
1368 ee('sys.stderr.flush()')
1369 ee('sys.stdout.attr = None')
1370 cb.append(">> OutputWrite")
1371 ee('assert sys.stdout.writable()==True')
1372 ee('assert sys.stdout.readable()==False')
1373 ee('assert sys.stderr.writable()==True')
1374 ee('assert sys.stderr.readable()==False')
1375 ee('assert sys.stdout.closed()==False')
1376 ee('assert sys.stderr.closed()==False')
1377 ee('assert sys.stdout.errors=="strict"')
1378 ee('assert sys.stderr.errors=="strict"')
1379 ee('assert sys.stdout.encoding==sys.stderr.encoding')
1380 ee('sys.stdout.write(None)')
1381 cb.append(">> OutputWriteLines")
1382 ee('sys.stdout.writelines(None)')
1383 ee('sys.stdout.writelines([1])')
1384 iter_test('sys.stdout.writelines(%s)')
1385 cb.append("> VimCommand")
1386 stringtochars_test('vim.command(%s)')
1387 ee('vim.command("", 2)')
1388 #! Not checked: vim->python exceptions translating: checked later
1389 cb.append("> VimToPython")
1390 #! Not checked: everything: needs errors in internal python functions
1391 cb.append("> VimEval")
1392 stringtochars_test('vim.eval(%s)')
1393 ee('vim.eval("", FailingTrue())')
1394 #! Not checked: everything: needs errors in internal python functions
1395 cb.append("> VimEvalPy")
1396 stringtochars_test('vim.bindeval(%s)')
1397 ee('vim.eval("", 2)')
1398 #! Not checked: vim->python exceptions translating: checked later
1399 cb.append("> VimStrwidth")
1400 stringtochars_test('vim.strwidth(%s)')
1401 cb.append("> VimForeachRTP")
1402 ee('vim.foreach_rtp(None)')
1403 ee('vim.foreach_rtp(NoArgsCall())')
1404 ee('vim.foreach_rtp(FailingCall())')
1405 ee('vim.foreach_rtp(int, 2)')
1406 cb.append('> import')
1407 old_rtp = vim.options['rtp']
1408 vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
1409 ee('import xxx_no_such_module_xxx')
1410 ee('import failing_import')
1411 ee('import failing')
1412 vim.options['rtp'] = old_rtp
1413 del old_rtp
1414 cb.append("> Options")
1415 cb.append(">> OptionsItem")
1416 ee('vim.options["abcQ"]')
1417 ee('vim.options[""]')
1418 stringtochars_test('vim.options[%s]')
1419 cb.append(">> OptionsContains")
1420 stringtochars_test('%s in vim.options')
1421 cb.append("> Dictionary")
1422 cb.append(">> DictionaryConstructor")
1423 ee('vim.Dictionary("abcI")')
1424 ##! Not checked: py_dict_alloc failure
1425 cb.append(">> DictionarySetattr")
1426 ee('del d.locked')
1427 ee('d.locked = FailingTrue()')
1428 ee('vim.vvars.locked = False')
1429 ee('d.scope = True')
1430 ee('d.xxx = True')
1431 cb.append(">> _DictionaryItem")
1432 ee('d.get("a", 2, 3)')
1433 stringtochars_test('d.get(%s)')
1434 ee('d.pop("a")')
1435 ee('dl.pop("a")')
1436 cb.append(">> DictionaryContains")
1437 ee('"" in d')
1438 ee('0 in d')
1439 cb.append(">> DictionaryIterNext")
1440 ee('for i in ned: ned["a"] = 1')
1441 del i
1442 cb.append(">> DictionaryAssItem")
1443 ee('dl["b"] = 1')
1444 stringtochars_test('d[%s] = 1')
1445 convertfrompyobject_test('d["a"] = %s')
1446 cb.append(">> DictionaryUpdate")
1447 cb.append(">>> kwargs")
1448 cb.append(">>> iter")
1449 ee('d.update(FailingMapping())')
1450 ee('d.update([FailingIterNext()])')
1451 ee('d.update([FailingIterNextN(1)])')
1452 iter_test('d.update(%s)')
1453 convertfrompyobject_test('d.update(%s)')
1454 stringtochars_test('d.update(((%s, 0),))')
1455 convertfrompyobject_test('d.update((("a", %s),))')
1456 cb.append(">> DictionaryPopItem")
1457 ee('d.popitem(1, 2)')
1458 cb.append(">> DictionaryHasKey")
1459 ee('d.has_key()')
1460 cb.append("> List")
1461 cb.append(">> ListConstructor")
1462 ee('vim.List(1, 2)')
1463 ee('vim.List(a=1)')
1464 iter_test('vim.List(%s)')
1465 convertfrompyobject_test('vim.List([%s])')
1466 cb.append(">> ListItem")
1467 ee('l[1000]')
1468 cb.append(">> ListAssItem")
1469 ee('ll[1] = 2')
1470 ee('l[1000] = 3')
1471 cb.append(">> ListAssSlice")
1472 ee('ll[1:100] = "abcJ"')
1473 iter_test('l[:] = %s')
1474 ee('nel[1:10:2] = "abcK"')
1475 cb.append(repr(tuple(nel)))
1476 ee('nel[1:10:2] = "a"')
1477 cb.append(repr(tuple(nel)))
1478 ee('nel[1:1:-1] = "a"')
1479 cb.append(repr(tuple(nel)))
1480 ee('nel[:] = FailingIterNextN(2)')
1481 cb.append(repr(tuple(nel)))
1482 convertfrompyobject_test('l[:] = [%s]')
1483 cb.append(">> ListConcatInPlace")
1484 iter_test('l.extend(%s)')
1485 convertfrompyobject_test('l.extend([%s])')
1486 cb.append(">> ListSetattr")
1487 ee('del l.locked')
1488 ee('l.locked = FailingTrue()')
1489 ee('l.xxx = True')
1490 cb.append("> Function")
1491 cb.append(">> FunctionConstructor")
1492 cb.append(">>> FunctionConstructor")
1493 ee('vim.Function("123")')
1494 ee('vim.Function("xxx_non_existent_function_xxx")')
1495 ee('vim.Function("xxx#non#existent#function#xxx")')
1496 ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
1497 ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
1498 ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
1499 cb.append(">>> FunctionNew")
1500 ee('vim.Function("tr", self="abcFuncSelf")')
1501 ee('vim.Function("tr", args=427423)')
1502 ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
1503 ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
1504 ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
1505 ee('vim.Function("tr", "")')
1506 cb.append(">> FunctionCall")
1507 convertfrompyobject_test('f(%s)')
1508 convertfrompymapping_test('fd(self=%s)')
1509 cb.append("> TabPage")
1510 cb.append(">> TabPageAttr")
1511 ee('vim.current.tabpage.xxx')
1512 cb.append("> TabList")
1513 cb.append(">> TabListItem")
1514 ee('vim.tabpages[1000]')
1515 cb.append("> Window")
1516 cb.append(">> WindowAttr")
1517 ee('vim.current.window.xxx')
1518 cb.append(">> WindowSetattr")
1519 ee('vim.current.window.buffer = 0')
1520 ee('vim.current.window.cursor = (100000000, 100000000)')
1521 ee('vim.current.window.cursor = True')
1522 number_test('vim.current.window.height = %s', unsigned=True)
1523 number_test('vim.current.window.width = %s', unsigned=True)
1524 ee('vim.current.window.xxxxxx = True')
1525 cb.append("> WinList")
1526 cb.append(">> WinListItem")
1527 ee('vim.windows[1000]')
1528 cb.append("> Buffer")
1529 cb.append(">> StringToLine (indirect)")
1530 ee('vim.current.buffer[0] = "\\na"')
1531 ee('vim.current.buffer[0] = b"\\na"')
1532 cb.append(">> SetBufferLine (indirect)")
1533 ee('vim.current.buffer[0] = True')
1534 cb.append(">> SetBufferLineList (indirect)")
1535 ee('vim.current.buffer[:] = True')
1536 ee('vim.current.buffer[:] = ["\\na", "bc"]')
1537 cb.append(">> InsertBufferLines (indirect)")
1538 ee('vim.current.buffer.append(None)')
1539 ee('vim.current.buffer.append(["\\na", "bc"])')
1540 ee('vim.current.buffer.append("\\nbc")')
1541 cb.append(">> RBItem")
1542 ee('vim.current.buffer[100000000]')
1543 cb.append(">> RBAsItem")
1544 ee('vim.current.buffer[100000000] = ""')
1545 cb.append(">> BufferAttr")
1546 ee('vim.current.buffer.xxx')
1547 cb.append(">> BufferSetattr")
1548 ee('vim.current.buffer.name = True')
1549 ee('vim.current.buffer.xxx = True')
1550 cb.append(">> BufferMark")
1551 ee('vim.current.buffer.mark(0)')
1552 ee('vim.current.buffer.mark("abcM")')
1553 ee('vim.current.buffer.mark("!")')
1554 cb.append(">> BufferRange")
1555 ee('vim.current.buffer.range(1, 2, 3)')
1556 cb.append("> BufMap")
1557 cb.append(">> BufMapItem")
1558 ee('vim.buffers[100000000]')
1559 number_test('vim.buffers[%s]', natural=True)
1560 cb.append("> Current")
1561 cb.append(">> CurrentGetattr")
1562 ee('vim.current.xxx')
1563 cb.append(">> CurrentSetattr")
1564 ee('vim.current.line = True')
1565 ee('vim.current.buffer = True')
1566 ee('vim.current.window = True')
1567 ee('vim.current.tabpage = True')
1568 ee('vim.current.xxx = True')
1569 del d
1570 del ned
1571 del dl
1572 del l
1573 del ll
1574 del nel
1575 del f
1576 del fd
1577 del fdel
1578 del subexpr_test
1579 del stringtochars_test
1580 del Mapping
1581 del convertfrompyobject_test
1582 del convertfrompymapping_test
1583 del iter_test
1584 del number_test
1585 del FailingTrue
1586 del FailingIter
1587 del FailingIterNext
1588 del FailingIterNextN
1589 del FailingMapping
1590 del FailingMappingKey
1591 del FailingList
1592 del NoArgsCall
1593 del FailingCall
1594 del FailingNumber
Bram Moolenaar8600e402013-05-30 13:28:41 +02001595EOF
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001596:delfunction F
Bram Moolenaar8600e402013-05-30 13:28:41 +02001597:"
Bram Moolenaara9f22202013-06-11 18:48:21 +02001598:" Test import
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001599py3 << trim EOF
1600 sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
1601 sys.path.append(os.path.join(os.getcwd(), 'python_after'))
1602 vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
1603 l = []
1604 def callback(path):
1605 l.append(os.path.relpath(path))
1606 vim.foreach_rtp(callback)
1607 cb.append(repr(l))
1608 del l
1609 def callback(path):
1610 return os.path.relpath(path)
1611 cb.append(repr(vim.foreach_rtp(callback)))
1612 del callback
1613 from module import dir as d
1614 from modulex import ddir
1615 cb.append(d + ',' + ddir)
1616 import before
1617 cb.append(before.dir)
1618 import after
1619 cb.append(after.dir)
1620 import topmodule as tm
1621 import topmodule.submodule as tms
1622 import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
1623 cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
1624 cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
1625 cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
1626 del before
1627 del after
1628 del d
1629 del ddir
1630 del tm
1631 del tms
1632 del tmsss
Bram Moolenaara9f22202013-06-11 18:48:21 +02001633EOF
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001634:"
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001635:" Test exceptions
1636:fun Exe(e)
1637: execute a:e
1638:endfun
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001639py3 << trim EOF
1640 Exe = vim.bindeval('function("Exe")')
1641 ee('vim.command("throw \'abcN\'")')
1642 ee('Exe("throw \'def\'")')
1643 ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
1644 ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
1645 ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
1646 ee('vim.eval("xxx_unknown_function_xxx()")')
1647 ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
1648 del Exe
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001649EOF
1650:delfunction Exe
1651:"
Bram Moolenaard6b8a522013-11-11 01:05:48 +01001652:" Regression: interrupting vim.command propagates to next vim.command
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001653py3 << trim EOF
1654 def test_keyboard_interrupt():
1655 try:
1656 vim.command('while 1 | endwhile')
1657 except KeyboardInterrupt:
1658 cb.append('Caught KeyboardInterrupt')
1659 except Exception:
1660 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
1661 else:
1662 cb.append('!!!!!!!! No exception')
1663 try:
1664 vim.command('$ put =\'Running :put\'')
1665 except KeyboardInterrupt:
1666 cb.append('!!!!!!!! Caught KeyboardInterrupt')
1667 except Exception:
1668 cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
1669 else:
1670 cb.append('No exception')
Bram Moolenaard6b8a522013-11-11 01:05:48 +01001671EOF
1672:debuggreedy
1673:call inputsave()
1674:call feedkeys("s\ns\ns\ns\nq\n")
1675:redir => output
1676:debug silent! py3 test_keyboard_interrupt()
1677:redir END
1678:0 debuggreedy
Bram Moolenaar56f62272014-09-29 18:08:59 +02001679:call inputrestore()
Bram Moolenaard6b8a522013-11-11 01:05:48 +01001680:silent $put =output
1681:unlet output
1682:py3 del test_keyboard_interrupt
1683:"
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001684:" Cleanup
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +02001685py3 << trim EOF
1686 del cb
1687 del ee
1688 del emsg
1689 del sys
1690 del os
1691 del vim
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001692EOF
Bram Moolenaardb913952012-06-29 12:54:53 +02001693:endfun
1694:"
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001695:fun RunTest()
1696:let checkrefs = !empty($PYTHONDUMPREFS)
1697:let start = getline(1, '$')
1698:for i in range(checkrefs ? 10 : 1)
1699: if i != 0
1700: %d _
1701: call setline(1, start)
1702: endif
1703: call Test()
1704: if i == 0
1705: let result = getline(1, '$')
1706: endif
1707:endfor
1708:if checkrefs
1709: %d _
1710: call setline(1, result)
1711:endif
1712:endfun
Bram Moolenaardb913952012-06-29 12:54:53 +02001713:"
Bram Moolenaar841fbd22013-06-23 14:37:07 +02001714:call RunTest()
1715:delfunction RunTest
1716:delfunction Test
Bram Moolenaardb913952012-06-29 12:54:53 +02001717:call garbagecollect(1)
1718:"
1719:/^start:/,$wq! test.out
Bram Moolenaar8110a092016-04-14 15:56:09 +02001720:/^start:/,$w! test.out
Bram Moolenaardee2e312013-06-23 16:35:47 +02001721:" vim: et ts=4 isk-=\:
Bram Moolenaar8110a092016-04-14 15:56:09 +02001722:while getchar(0) isnot 0|endwhile
Bram Moolenaardb913952012-06-29 12:54:53 +02001723ENDTEST
1724
1725start: