To: vim_dev@googlegroups.com Subject: Patch 8.2.0578 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0578 Problem: Heredoc for interfaces does not support "trim". Solution: Update the script heredoc support to be same as the :let command. (Yegappan Lakshmanan, closes #5916) Files: runtime/doc/if_lua.txt, runtime/doc/if_mzsch.txt, runtime/doc/if_perl.txt, runtime/doc/if_pyth.txt, runtime/doc/if_ruby.txt, runtime/doc/if_tcl.txt, src/evalvars.c, src/ex_getln.c, src/proto/evalvars.pro, src/testdir/test86.in, src/testdir/test87.in, src/testdir/test_lua.vim, src/testdir/test_perl.vim, src/testdir/test_python2.vim, src/testdir/test_python3.vim, src/testdir/test_pyx2.vim, src/testdir/test_pyx3.vim, src/testdir/test_ruby.vim, src/testdir/test_tcl.vim, src/userfunc.c, src/vim9compile.c *** ../vim-8.2.0577/runtime/doc/if_lua.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_lua.txt 2020-04-14 20:04:20.129971201 +0200 *************** *** 32,38 **** :lua local curbuf = vim.buffer() curbuf[7] = "line #7" < ! :[range]lua << [endmarker] {script} {endmarker} Execute Lua script {script}. --- 32,38 ---- :lua local curbuf = vim.buffer() curbuf[7] = "line #7" < ! :[range]lua << [trim] [{endmarker}] {script} {endmarker} Execute Lua script {script}. *************** *** 40,49 **** feature wasn't compiled in. To avoid errors, see |script-here|. - The {endmarker} must NOT be preceded by any white space. - If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. This form of the |:lua| command is mainly useful for including Lua code in Vim scripts. --- 40,48 ---- feature wasn't compiled in. To avoid errors, see |script-here|. If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. Refer to ! |:let-heredoc| for more information. This form of the |:lua| command is mainly useful for including Lua code in Vim scripts. *** ../vim-8.2.0577/runtime/doc/if_mzsch.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_mzsch.txt 2020-04-14 20:04:20.129971201 +0200 *************** *** 39,45 **** :[range]mz[scheme] {stmt} Execute MzScheme statement {stmt}. ! :[range]mz[scheme] << [endmarker] {script} {endmarker} Execute inlined MzScheme script {script}. --- 39,45 ---- :[range]mz[scheme] {stmt} Execute MzScheme statement {stmt}. ! :[range]mz[scheme] << [trim] [{endmarker}] {script} {endmarker} Execute inlined MzScheme script {script}. *************** *** 47,58 **** feature wasn't compiled in. To avoid errors, see |script-here|. - The {endmarker} below the {script} must NOT be - preceded by any white space. - If [endmarker] is omitted from after the "<<", a dot '.' must be used after {script}, like for the ! |:append| and |:insert| commands. *:mzfile* *:mzf* :[range]mzf[ile] {file} Execute the MzScheme script in {file}. --- 47,57 ---- feature wasn't compiled in. To avoid errors, see |script-here|. If [endmarker] is omitted from after the "<<", a dot '.' must be used after {script}, like for the ! |:append| and |:insert| commands. Refer to ! |:let-heredoc| for more information. ! *:mzfile* *:mzf* :[range]mzf[ile] {file} Execute the MzScheme script in {file}. *** ../vim-8.2.0577/runtime/doc/if_perl.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_perl.txt 2020-04-14 20:04:20.129971201 +0200 *************** *** 55,61 **** working: > :perl VIM::Msg("Hello") ! :pe[rl] << [endmarker] {script} {endmarker} Execute Perl script {script}. --- 55,61 ---- working: > :perl VIM::Msg("Hello") ! :pe[rl] << [trim] [{endmarker}] {script} {endmarker} Execute Perl script {script}. *** ../vim-8.2.0577/runtime/doc/if_pyth.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_pyth.txt 2020-04-14 20:04:20.133971191 +0200 *************** *** 34,40 **** the `:python` command is working: > :python print "Hello" ! :[range]py[thon] << [endmarker] {script} {endmarker} Execute Python script {script}. --- 34,40 ---- the `:python` command is working: > :python print "Hello" ! :[range]py[thon] << [trim] [{endmarker}] {script} {endmarker} Execute Python script {script}. *************** *** 42,51 **** feature wasn't compiled in. To avoid errors, see |script-here|. - The {endmarker} below the {script} must NOT be preceded by any white space. - If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. This form of the |:python| command is mainly useful for including python code in Vim scripts. --- 42,50 ---- feature wasn't compiled in. To avoid errors, see |script-here|. If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. Refer to ! |:let-heredoc| for more information. This form of the |:python| command is mainly useful for including python code in Vim scripts. *************** *** 768,779 **** *:py3* *:python3* :[range]py3 {stmt} ! :[range]py3 << [endmarker] {script} {endmarker} :[range]python3 {stmt} ! :[range]python3 << [endmarker] {script} {endmarker} The `:py3` and `:python3` commands work similar to `:python`. A --- 767,778 ---- *:py3* *:python3* :[range]py3 {stmt} ! :[range]py3 << [trim] [{endmarker}] {script} {endmarker} :[range]python3 {stmt} ! :[range]python3 << [trim] [{endmarker}] {script} {endmarker} The `:py3` and `:python3` commands work similar to `:python`. A *** ../vim-8.2.0577/runtime/doc/if_ruby.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_ruby.txt 2020-04-14 20:04:20.133971191 +0200 *************** *** 28,42 **** :rub[y] {cmd} Execute Ruby command {cmd}. A command to try it out: > :ruby print "Hello" ! :rub[y] << [endmarker] {script} {endmarker} Execute Ruby script {script}. - The {endmarker} after {script} must NOT be preceded by - any white space. If [endmarker] is omitted, it defaults to a dot '.' ! like for the |:append| and |:insert| commands. This form of the |:ruby| command is mainly useful for including ruby code in vim scripts. --- 28,42 ---- :rub[y] {cmd} Execute Ruby command {cmd}. A command to try it out: > :ruby print "Hello" ! :rub[y] << [trim] [{endmarker}] {script} {endmarker} Execute Ruby script {script}. If [endmarker] is omitted, it defaults to a dot '.' ! like for the |:append| and |:insert| commands. Refer ! to |:let-heredoc| for more information. ! This form of the |:ruby| command is mainly useful for including ruby code in vim scripts. *** ../vim-8.2.0577/runtime/doc/if_tcl.txt 2019-12-12 12:49:05.000000000 +0100 --- runtime/doc/if_tcl.txt 2020-04-14 20:04:20.133971191 +0200 *************** *** 30,36 **** is working: > :tcl puts "Hello" ! :[range]tc[l] << [endmarker] {script} {endmarker} Execute Tcl script {script}. --- 30,36 ---- is working: > :tcl puts "Hello" ! :[range]tc[l] << [trim] [{endmarker}] {script} {endmarker} Execute Tcl script {script}. *************** *** 38,47 **** wasn't compiled in. To avoid errors, see |script-here|. - The {endmarker} after {script} must NOT be preceded by any white space. - If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. This form of the |:tcl| command is mainly useful for including tcl code in Vim scripts. --- 38,46 ---- wasn't compiled in. To avoid errors, see |script-here|. If [endmarker] is omitted from after the "<<", a dot '.' must be used after ! {script}, like for the |:append| and |:insert| commands. Refer to ! |:let-heredoc| for more information. This form of the |:tcl| command is mainly useful for including tcl code in Vim scripts. *** ../vim-8.2.0577/src/evalvars.c 2020-04-09 20:10:50.389873647 +0200 --- src/evalvars.c 2020-04-14 20:04:20.133971191 +0200 *************** *** 541,550 **** * The {marker} is a string. If the optional 'trim' word is supplied before the * marker, then the leading indentation before the lines (matching the * indentation in the 'cmd' line) is stripped. * Returns a List with {lines} or NULL. */ list_T * ! heredoc_get(exarg_T *eap, char_u *cmd) { char_u *theline; char_u *marker; --- 541,555 ---- * The {marker} is a string. If the optional 'trim' word is supplied before the * marker, then the leading indentation before the lines (matching the * indentation in the 'cmd' line) is stripped. + * + * When getting lines for an embedded script (e.g. python, lua, perl, ruby, + * tcl, mzscheme), script_get is set to TRUE. In this case, if the marker is + * missing, then '.' is accepted as a marker. + * * Returns a List with {lines} or NULL. */ list_T * ! heredoc_get(exarg_T *eap, char_u *cmd, int script_get) { char_u *theline; char_u *marker; *************** *** 553,558 **** --- 558,564 ---- int marker_indent_len = 0; int text_indent_len = 0; char_u *text_indent = NULL; + char_u dot[] = "."; if (eap->getline == NULL) { *************** *** 598,605 **** } else { ! emsg(_("E172: Missing marker")); ! return NULL; } l = list_alloc(); --- 604,618 ---- } else { ! // When getting lines for an embedded script, if the marker is missing, ! // accept '.' as the marker. ! if (script_get) ! marker = dot; ! else ! { ! emsg(_("E172: Missing marker")); ! return NULL; ! } } l = list_alloc(); *************** *** 746,752 **** list_T *l; // HERE document ! l = heredoc_get(eap, expr + 3); if (l != NULL) { rettv_list_set(&rettv, l); --- 759,765 ---- list_T *l; // HERE document ! l = heredoc_get(eap, expr + 3, FALSE); if (l != NULL) { rettv_list_set(&rettv, l); *** ../vim-8.2.0577/src/ex_getln.c 2020-04-12 19:37:13.510297280 +0200 --- src/ex_getln.c 2020-04-14 20:04:20.133971191 +0200 *************** *** 4408,4451 **** * Returns a pointer to allocated memory with {script} or NULL. */ char_u * ! script_get(exarg_T *eap, char_u *cmd) { ! char_u *theline; ! char *end_pattern = NULL; ! char dot[] = "."; garray_T ga; if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) return NULL; ! ga_init2(&ga, 1, 0x400); ! if (cmd[2] != NUL) ! end_pattern = (char *)skipwhite(cmd + 2); ! else ! end_pattern = dot; ! for (;;) { ! theline = eap->getline( ! #ifdef FEAT_EVAL ! eap->cstack->cs_looplevel > 0 ? -1 : ! #endif ! NUL, eap->cookie, 0, TRUE); ! ! if (theline == NULL || STRCMP(end_pattern, theline) == 0) ! { ! vim_free(theline); ! break; ! } ! ! ga_concat(&ga, theline); ga_append(&ga, '\n'); - vim_free(theline); } ga_append(&ga, NUL); return (char_u *)ga.ga_data; } #if defined(FEAT_EVAL) || defined(PROTO) --- 4408,4444 ---- * Returns a pointer to allocated memory with {script} or NULL. */ char_u * ! script_get(exarg_T *eap UNUSED, char_u *cmd UNUSED) { ! #ifdef FEAT_EVAL ! list_T *l; ! listitem_T *li; ! char_u *s; garray_T ga; if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) return NULL; + cmd += 2; ! l = heredoc_get(eap, cmd, TRUE); ! if (l == NULL) ! return NULL; ! ga_init2(&ga, 1, 0x400); ! FOR_ALL_LIST_ITEMS(l, li) { ! s = tv_get_string(&li->li_tv); ! ga_concat(&ga, s); ga_append(&ga, '\n'); } ga_append(&ga, NUL); + list_free(l); return (char_u *)ga.ga_data; + #else + return NULL; + #endif } #if defined(FEAT_EVAL) || defined(PROTO) *** ../vim-8.2.0577/src/proto/evalvars.pro 2020-04-09 19:34:40.051480485 +0200 --- src/proto/evalvars.pro 2020-04-14 20:04:20.133971191 +0200 *************** *** 13,19 **** int get_spellword(list_T *list, char_u **pp); void prepare_vimvar(int idx, typval_T *save_tv); void restore_vimvar(int idx, typval_T *save_tv); ! list_T *heredoc_get(exarg_T *eap, char_u *cmd); void ex_let(exarg_T *eap); void ex_const(exarg_T *eap); int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count, int flags, char_u *op); --- 13,19 ---- int get_spellword(list_T *list, char_u **pp); void prepare_vimvar(int idx, typval_T *save_tv); void restore_vimvar(int idx, typval_T *save_tv); ! list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get); void ex_let(exarg_T *eap); void ex_const(exarg_T *eap); int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count, int flags, char_u *op); *** ../vim-8.2.0577/src/testdir/test86.in 2020-03-02 20:54:19.319757505 +0100 --- src/testdir/test86.in 2020-04-14 20:04:20.133971191 +0200 *************** *** 37,56 **** :fun d.f() : return 1 :endfun ! py << EOF ! d=vim.bindeval('d') ! d['1']='asd' ! d.update() # Must not do anything, including throwing errors ! d.update(b=[1, 2, f]) ! d.update((('-1', {'a': 1}),)) ! d.update({'0': -1}) ! dk = d.keys() ! dv = d.values() ! di = d.items() ! cmpfun = lambda a, b: cmp(repr(a), repr(b)) ! dk.sort(cmpfun) ! dv.sort(cmpfun) ! di.sort(cmpfun) EOF :$put =pyeval('d[''f''](self={})') :$put =pyeval('repr(dk)') --- 37,56 ---- :fun d.f() : return 1 :endfun ! py << trim EOF ! d=vim.bindeval('d') ! d['1']='asd' ! d.update() # Must not do anything, including throwing errors ! d.update(b=[1, 2, f]) ! d.update((('-1', {'a': 1}),)) ! d.update({'0': -1}) ! dk = d.keys() ! dv = d.values() ! di = d.items() ! cmpfun = lambda a, b: cmp(repr(a), repr(b)) ! dk.sort(cmpfun) ! dv.sort(cmpfun) ! di.sort(cmpfun) EOF :$put =pyeval('d[''f''](self={})') :$put =pyeval('repr(dk)') *************** *** 208,259 **** :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :lockvar! l ! py << EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) EOF :$put =string(l) :unlockvar! l :" :" Function calls ! py << EOF ! import sys ! def ee(expr, g=globals(), l=locals()): ! try: ! exec(expr, g, l) ! except: ! ei = sys.exc_info() ! msg = emsg(ei) ! msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') ! if expr.find('None') > -1: ! msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', ! 'TypeError:("\'NoneType\' object is not iterable",)') ! if expr.find('FailingNumber') > -1: ! msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') ! msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', ! 'TypeError:("\'FailingNumber\' object is not iterable",)') ! if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: ! msg = msg.replace('(\'', '("').replace('\',)', '",)') ! # Some Python versions say can't, others cannot. ! if msg.find('can\'t') > -1: ! msg = msg.replace('can\'t', 'cannot') ! # Some Python versions use single quote, some double quote ! if msg.find('"cannot ') > -1: ! msg = msg.replace('"cannot ', '\'cannot ') ! if msg.find(' attributes"') > -1: ! msg = msg.replace(' attributes"', ' attributes\'') ! if expr == 'fd(self=[])': ! # HACK: PyMapping_Check changed meaning ! msg = msg.replace('AttributeError:(\'keys\',)', ! 'TypeError:(\'unable to convert list to vim dictionary\',)') ! vim.current.buffer.append(expr + ':' + msg) ! else: ! vim.current.buffer.append(expr + ':NOT FAILED') EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] --- 208,259 ---- :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :lockvar! l ! py << trim EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) EOF :$put =string(l) :unlockvar! l :" :" Function calls ! py << trim EOF ! import sys ! def ee(expr, g=globals(), l=locals()): ! try: ! exec(expr, g, l) ! except: ! ei = sys.exc_info() ! msg = emsg(ei) ! msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') ! if expr.find('None') > -1: ! msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', ! 'TypeError:("\'NoneType\' object is not iterable",)') ! if expr.find('FailingNumber') > -1: ! msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') ! msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', ! 'TypeError:("\'FailingNumber\' object is not iterable",)') ! if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: ! msg = msg.replace('(\'', '("').replace('\',)', '",)') ! # Some Python versions say can't, others cannot. ! if msg.find('can\'t') > -1: ! msg = msg.replace('can\'t', 'cannot') ! # Some Python versions use single quote, some double quote ! if msg.find('"cannot ') > -1: ! msg = msg.replace('"cannot ', '\'cannot ') ! if msg.find(' attributes"') > -1: ! msg = msg.replace(' attributes"', ' attributes\'') ! if expr == 'fd(self=[])': ! # HACK: PyMapping_Check changed meaning ! msg = msg.replace('AttributeError:(\'keys\',)', ! 'TypeError:(\'unable to convert list to vim dictionary\',)') ! vim.current.buffer.append(expr + ':' + msg) ! else: ! vim.current.buffer.append(expr + ':NOT FAILED') EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] *************** *** 283,308 **** :endif :let messages=[] :delfunction DictNew ! py <")') + ':BufFilePost:' + vim.eval('bufnr("%")')) : autocmd BufFilePre * python cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END ! py << EOF ! # Tests BufferAppend and BufferItem ! cb.append(b[0]) ! # Tests BufferSlice and BufferAssSlice ! cb.append('abc5') # Will be overwritten ! cb[-1:] = b[:-2] ! # Test BufferLength and BufferAssSlice ! cb.append('def') # Will not be overwritten ! cb[len(cb):] = b[:] ! # Test BufferAssItem and BufferMark ! cb.append('ghi') # Will be overwritten ! cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) ! # Test BufferRepr ! cb.append(repr(cb) + repr(b)) ! # Modify foreign buffer ! b.append('foo') ! b[0]='bar' ! b[0:0]=['baz'] ! vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) ! # Test assigning to name property ! import os ! old_name = cb.name ! cb.name = 'foo' ! cb.append(cb.name[-11:].replace(os.path.sep, '/')) ! b.name = 'bar' ! cb.append(b.name[-11:].replace(os.path.sep, '/')) ! cb.name = old_name ! cb.append(cb.name[-17:].replace(os.path.sep, '/')) ! del old_name ! # Test CheckBuffer ! for _b in vim.buffers: ! if _b is not cb: ! vim.command('bwipeout! ' + str(_b.number)) ! del _b ! cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) ! for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'): ! try: ! exec(expr) ! except vim.error: ! pass ! else: ! # Usually a SEGV here ! # Should not happen in any case ! cb.append('No exception for ' + expr) ! vim.command('cd .') ! del b EOF :augroup BUFS : autocmd! --- 627,678 ---- : autocmd BufFilePost * python cb.append(vim.eval('expand("")') + ':BufFilePost:' + vim.eval('bufnr("%")')) : autocmd BufFilePre * python cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END ! py << trim EOF ! # Tests BufferAppend and BufferItem ! cb.append(b[0]) ! # Tests BufferSlice and BufferAssSlice ! cb.append('abc5') # Will be overwritten ! cb[-1:] = b[:-2] ! # Test BufferLength and BufferAssSlice ! cb.append('def') # Will not be overwritten ! cb[len(cb):] = b[:] ! # Test BufferAssItem and BufferMark ! cb.append('ghi') # Will be overwritten ! cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) ! # Test BufferRepr ! cb.append(repr(cb) + repr(b)) ! # Modify foreign buffer ! b.append('foo') ! b[0]='bar' ! b[0:0]=['baz'] ! vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) ! # Test assigning to name property ! import os ! old_name = cb.name ! cb.name = 'foo' ! cb.append(cb.name[-11:].replace(os.path.sep, '/')) ! b.name = 'bar' ! cb.append(b.name[-11:].replace(os.path.sep, '/')) ! cb.name = old_name ! cb.append(cb.name[-17:].replace(os.path.sep, '/')) ! del old_name ! # Test CheckBuffer ! for _b in vim.buffers: ! if _b is not cb: ! vim.command('bwipeout! ' + str(_b.number)) ! del _b ! cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) ! for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'): ! try: ! exec(expr) ! except vim.error: ! pass ! else: ! # Usually a SEGV here ! # Should not happen in any case ! cb.append('No exception for ' + expr) ! vim.command('cd .') ! del b EOF :augroup BUFS : autocmd! *************** *** 687,745 **** :buffer # :edit c :buffer # ! py << EOF ! try: ! from __builtin__ import next ! except ImportError: ! next = lambda o: o.next() ! # Check GCing iterator that was not fully exhausted ! i = iter(vim.buffers) ! cb.append('i:' + str(next(i))) ! # and also check creating more than one iterator at a time ! i2 = iter(vim.buffers) ! cb.append('i2:' + str(next(i2))) ! cb.append('i:' + str(next(i))) ! # The following should trigger GC and not cause any problems ! del i ! del i2 ! i3 = iter(vim.buffers) ! cb.append('i3:' + str(next(i3))) ! del i3 ! ! prevnum = 0 ! for b in vim.buffers: ! # Check buffer order ! if prevnum >= b.number: ! cb.append('!!! Buffer numbers not in strictly ascending order') ! # Check indexing: vim.buffers[number].number == number ! cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) ! prevnum = b.number ! del prevnum ! ! cb.append(str(len(vim.buffers))) ! ! bnums = list(map(lambda b: b.number, vim.buffers))[1:] ! ! # Test wiping out buffer with existing iterator ! i4 = iter(vim.buffers) ! cb.append('i4:' + str(next(i4))) ! vim.command('bwipeout! ' + str(bnums.pop(0))) ! try: ! next(i4) ! except vim.error: ! pass ! else: ! cb.append('!!!! No vim.error') ! i4 = iter(vim.buffers) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! cb.append('i4:' + str(next(i4))) ! try: ! next(i4) ! except StopIteration: ! cb.append('StopIteration') ! del i4 ! del bnums EOF :" :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects --- 687,745 ---- :buffer # :edit c :buffer # ! py << trim EOF ! try: ! from __builtin__ import next ! except ImportError: ! next = lambda o: o.next() ! # Check GCing iterator that was not fully exhausted ! i = iter(vim.buffers) ! cb.append('i:' + str(next(i))) ! # and also check creating more than one iterator at a time ! i2 = iter(vim.buffers) ! cb.append('i2:' + str(next(i2))) ! cb.append('i:' + str(next(i))) ! # The following should trigger GC and not cause any problems ! del i ! del i2 ! i3 = iter(vim.buffers) ! cb.append('i3:' + str(next(i3))) ! del i3 ! ! prevnum = 0 ! for b in vim.buffers: ! # Check buffer order ! if prevnum >= b.number: ! cb.append('!!! Buffer numbers not in strictly ascending order') ! # Check indexing: vim.buffers[number].number == number ! cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) ! prevnum = b.number ! del prevnum ! ! cb.append(str(len(vim.buffers))) ! ! bnums = list(map(lambda b: b.number, vim.buffers))[1:] ! ! # Test wiping out buffer with existing iterator ! i4 = iter(vim.buffers) ! cb.append('i4:' + str(next(i4))) ! vim.command('bwipeout! ' + str(bnums.pop(0))) ! try: ! next(i4) ! except vim.error: ! pass ! else: ! cb.append('!!!! No vim.error') ! i4 = iter(vim.buffers) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! cb.append('i4:' + str(next(i4))) ! try: ! next(i4) ! except StopIteration: ! cb.append('StopIteration') ! del i4 ! del bnums EOF :" :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects *************** *** 750,877 **** :vnew a.2 :vnew b.2 :vnew c.2 ! py << EOF ! cb.append('Number of tabs: ' + str(len(vim.tabpages))) ! cb.append('Current tab pages:') ! def W(w): ! if repr(w).find('(unknown)') != -1: ! return '' ! else: ! return repr(w) ! ! start = len(cb) ! ! def Cursor(w): ! if w.buffer is cb: ! return repr((start - w.cursor[0], w.cursor[1])) ! else: ! return repr(w.cursor) ! ! for t in vim.tabpages: ! cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) ! cb.append(' Windows:') ! for w in t.windows: ! cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) ! # Other values depend on the size of the terminal, so they are checked partly: ! for attr in ('height', 'row', 'width', 'col'): ! try: ! aval = getattr(w, attr) ! if type(aval) is not long: ! raise TypeError ! if aval < 0: ! raise ValueError ! except Exception: ! cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__) ! del aval ! del attr ! w.cursor = (len(w.buffer), 0) ! del W ! del Cursor ! cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) ! if list(vim.windows) != list(vim.current.tabpage.windows): ! cb.append('!!!!!! Windows differ') EOF :" :" Test vim.current ! py << EOF ! def H(o): ! return repr(o) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) ! 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)) ! del H ! # Assigning: fails ! try: ! vim.current.window = vim.tabpages[0].window ! except ValueError: ! cb.append('ValueError at assigning foreign tab window') ! ! for attr in ('window', 'tabpage', 'buffer'): ! try: ! setattr(vim.current, attr, None) ! except TypeError: ! cb.append('Type error at assigning None to vim.current.' + attr) ! del attr ! ! # Assigning: success ! vim.current.tabpage = vim.tabpages[-2] ! vim.current.buffer = cb ! vim.current.window = vim.windows[0] ! vim.current.window.cursor = (len(vim.current.buffer), 0) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window)) ! cb.append('Current buffer: ' + repr(vim.current.buffer)) ! cb.append('Current line: ' + repr(vim.current.line)) ! ws = list(vim.windows) ! ts = list(vim.tabpages) ! for b in vim.buffers: ! if b is not cb: ! vim.command('bwipeout! ' + str(b.number)) ! del b ! cb.append('w.valid: ' + repr([w.valid for w in ws])) ! cb.append('t.valid: ' + repr([t.valid for t in ts])) ! del w ! del t ! del ts ! del ws EOF :tabonly! :only! :" :" Test types ! py << EOF ! for expr, attr in ( ! ('vim.vars', 'Dictionary'), ! ('vim.options', 'Options'), ! ('vim.bindeval("{}")', 'Dictionary'), ! ('vim.bindeval("[]")', 'List'), ! ('vim.bindeval("function(\'tr\')")', 'Function'), ! ('vim.current.buffer', 'Buffer'), ! ('vim.current.range', 'Range'), ! ('vim.current.window', 'Window'), ! ('vim.current.tabpage', 'TabPage'), ! ): ! cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) ! del expr ! del attr EOF :" :" Test __dir__() method ! py << EOF ! for name, o in ( ! ('current', vim.current), ! ('buffer', vim.current.buffer), ! ('window', vim.current.window), ! ('tabpage', vim.current.tabpage), ! ('range', vim.current.range), ! ('dictionary', vim.bindeval('{}')), ! ('list', vim.bindeval('[]')), ! ('function', vim.bindeval('function("tr")')), ! ('output', sys.stdout), ! ): ! cb.append(name + ':' + ','.join(dir(o))) ! del name ! del o EOF :" :" Test vim.*.__new__ --- 750,877 ---- :vnew a.2 :vnew b.2 :vnew c.2 ! py << trim EOF ! cb.append('Number of tabs: ' + str(len(vim.tabpages))) ! cb.append('Current tab pages:') ! def W(w): ! if repr(w).find('(unknown)') != -1: ! return '' ! else: ! return repr(w) ! ! start = len(cb) ! ! def Cursor(w): ! if w.buffer is cb: ! return repr((start - w.cursor[0], w.cursor[1])) ! else: ! return repr(w.cursor) ! ! for t in vim.tabpages: ! cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) ! cb.append(' Windows:') ! for w in t.windows: ! cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) ! # Other values depend on the size of the terminal, so they are checked partly: ! for attr in ('height', 'row', 'width', 'col'): ! try: ! aval = getattr(w, attr) ! if type(aval) is not long: ! raise TypeError ! if aval < 0: ! raise ValueError ! except Exception: ! cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__) ! del aval ! del attr ! w.cursor = (len(w.buffer), 0) ! del W ! del Cursor ! cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) ! if list(vim.windows) != list(vim.current.tabpage.windows): ! cb.append('!!!!!! Windows differ') EOF :" :" Test vim.current ! py << trim EOF ! def H(o): ! return repr(o) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) ! 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)) ! del H ! # Assigning: fails ! try: ! vim.current.window = vim.tabpages[0].window ! except ValueError: ! cb.append('ValueError at assigning foreign tab window') ! ! for attr in ('window', 'tabpage', 'buffer'): ! try: ! setattr(vim.current, attr, None) ! except TypeError: ! cb.append('Type error at assigning None to vim.current.' + attr) ! del attr ! ! # Assigning: success ! vim.current.tabpage = vim.tabpages[-2] ! vim.current.buffer = cb ! vim.current.window = vim.windows[0] ! vim.current.window.cursor = (len(vim.current.buffer), 0) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window)) ! cb.append('Current buffer: ' + repr(vim.current.buffer)) ! cb.append('Current line: ' + repr(vim.current.line)) ! ws = list(vim.windows) ! ts = list(vim.tabpages) ! for b in vim.buffers: ! if b is not cb: ! vim.command('bwipeout! ' + str(b.number)) ! del b ! cb.append('w.valid: ' + repr([w.valid for w in ws])) ! cb.append('t.valid: ' + repr([t.valid for t in ts])) ! del w ! del t ! del ts ! del ws EOF :tabonly! :only! :" :" Test types ! py << trim EOF ! for expr, attr in ( ! ('vim.vars', 'Dictionary'), ! ('vim.options', 'Options'), ! ('vim.bindeval("{}")', 'Dictionary'), ! ('vim.bindeval("[]")', 'List'), ! ('vim.bindeval("function(\'tr\')")', 'Function'), ! ('vim.current.buffer', 'Buffer'), ! ('vim.current.range', 'Range'), ! ('vim.current.window', 'Window'), ! ('vim.current.tabpage', 'TabPage'), ! ): ! cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) ! del expr ! del attr EOF :" :" Test __dir__() method ! py << trim EOF ! for name, o in ( ! ('current', vim.current), ! ('buffer', vim.current.buffer), ! ('window', vim.current.window), ! ('tabpage', vim.current.tabpage), ! ('range', vim.current.range), ! ('dictionary', vim.bindeval('{}')), ! ('list', vim.bindeval('[]')), ! ('function', vim.bindeval('function("tr")')), ! ('output', sys.stdout), ! ): ! cb.append(name + ':' + ','.join(dir(o))) ! del name ! del o EOF :" :" Test vim.*.__new__ *************** *** 904,966 **** :py Pt = vim.bindeval('Pt') :unlet Pt :py del Pt ! py << EOF ! def ecall(out_prefix, func, *args, **kwargs): ! line = out_prefix + ': ' ! try: ! ret = func(*args, **kwargs) ! except Exception: ! line += '!exception: ' + emsg(sys.exc_info()) ! else: ! line += '!result: ' + vim.Function('string')(ret) ! cb.append(line) ! a = vim.Function('Args') ! pa1 = vim.Function('Args', args=['abcArgsPA1']) ! pa2 = vim.Function('Args', args=[]) ! pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) ! pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) ! cb.append('a: ' + repr(a)) ! cb.append('pa1: ' + repr(pa1)) ! cb.append('pa2: ' + repr(pa2)) ! cb.append('pa3: ' + repr(pa3)) ! cb.append('pa4: ' + repr(pa4)) ! sa = vim.Function('SelfArgs') ! psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) ! psa2 = vim.Function('SelfArgs', args=[]) ! psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) ! psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) ! psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) ! psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) ! psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) ! psa8 = vim.Function('SelfArgs', auto_rebind=False) ! psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) ! psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) ! psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) ! psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) ! cb.append('sa: ' + repr(sa)) ! cb.append('psa1: ' + repr(psa1)) ! cb.append('psa2: ' + repr(psa2)) ! cb.append('psa3: ' + repr(psa3)) ! cb.append('psa4: ' + repr(psa4)) ! cb.append('psa5: ' + repr(psa5)) ! cb.append('psa6: ' + repr(psa6)) ! cb.append('psa7: ' + repr(psa7)) ! cb.append('psa8: ' + repr(psa8)) ! cb.append('psa9: ' + repr(psa9)) ! cb.append('psaA: ' + repr(psaA)) ! cb.append('psaB: ' + repr(psaB)) ! cb.append('psaC: ' + repr(psaC)) ! ! psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) ! psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] ! psar.self['rec'] = psar ! psar.self['self'] = psar.self ! psar.self['args'] = psar.args ! ! try: ! cb.append('psar: ' + repr(psar)) ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) EOF :$put ='s(a): '.string(pyeval('a')) :$put ='s(pa1): '.string(pyeval('pa1')) --- 904,966 ---- :py Pt = vim.bindeval('Pt') :unlet Pt :py del Pt ! py << trim EOF ! def ecall(out_prefix, func, *args, **kwargs): ! line = out_prefix + ': ' ! try: ! ret = func(*args, **kwargs) ! except Exception: ! line += '!exception: ' + emsg(sys.exc_info()) ! else: ! line += '!result: ' + vim.Function('string')(ret) ! cb.append(line) ! a = vim.Function('Args') ! pa1 = vim.Function('Args', args=['abcArgsPA1']) ! pa2 = vim.Function('Args', args=[]) ! pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) ! pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) ! cb.append('a: ' + repr(a)) ! cb.append('pa1: ' + repr(pa1)) ! cb.append('pa2: ' + repr(pa2)) ! cb.append('pa3: ' + repr(pa3)) ! cb.append('pa4: ' + repr(pa4)) ! sa = vim.Function('SelfArgs') ! psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) ! psa2 = vim.Function('SelfArgs', args=[]) ! psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) ! psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) ! psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) ! psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) ! psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) ! psa8 = vim.Function('SelfArgs', auto_rebind=False) ! psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) ! psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) ! psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) ! psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) ! cb.append('sa: ' + repr(sa)) ! cb.append('psa1: ' + repr(psa1)) ! cb.append('psa2: ' + repr(psa2)) ! cb.append('psa3: ' + repr(psa3)) ! cb.append('psa4: ' + repr(psa4)) ! cb.append('psa5: ' + repr(psa5)) ! cb.append('psa6: ' + repr(psa6)) ! cb.append('psa7: ' + repr(psa7)) ! cb.append('psa8: ' + repr(psa8)) ! cb.append('psa9: ' + repr(psa9)) ! cb.append('psaA: ' + repr(psaA)) ! cb.append('psaB: ' + repr(psaB)) ! cb.append('psaC: ' + repr(psaC)) ! ! psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) ! psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] ! psar.self['rec'] = psar ! psar.self['self'] = psar.self ! psar.self['args'] = psar.args ! ! try: ! cb.append('psar: ' + repr(psar)) ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) EOF :$put ='s(a): '.string(pyeval('a')) :$put ='s(pa1): '.string(pyeval('pa1')) *************** *** 1029,1116 **** :py ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) :py ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) :py ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) ! py << EOF ! def s(v): ! if v is None: ! return repr(v) ! else: ! return vim.Function('string')(v) ! ! cb.append('a.args: ' + s(a.args)) ! cb.append('pa1.args: ' + s(pa1.args)) ! cb.append('pa2.args: ' + s(pa2.args)) ! cb.append('pa3.args: ' + s(pa3.args)) ! cb.append('pa4.args: ' + s(pa4.args)) ! cb.append('sa.args: ' + s(sa.args)) ! cb.append('psa1.args: ' + s(psa1.args)) ! cb.append('psa2.args: ' + s(psa2.args)) ! cb.append('psa3.args: ' + s(psa3.args)) ! cb.append('psa4.args: ' + s(psa4.args)) ! ! cb.append('a.self: ' + s(a.self)) ! cb.append('pa1.self: ' + s(pa1.self)) ! cb.append('pa2.self: ' + s(pa2.self)) ! cb.append('pa3.self: ' + s(pa3.self)) ! cb.append('pa4.self: ' + s(pa4.self)) ! cb.append('sa.self: ' + s(sa.self)) ! cb.append('psa1.self: ' + s(psa1.self)) ! cb.append('psa2.self: ' + s(psa2.self)) ! cb.append('psa3.self: ' + s(psa3.self)) ! cb.append('psa4.self: ' + s(psa4.self)) ! ! cb.append('a.name: ' + s(a.name)) ! cb.append('pa1.name: ' + s(pa1.name)) ! cb.append('pa2.name: ' + s(pa2.name)) ! cb.append('pa3.name: ' + s(pa3.name)) ! cb.append('pa4.name: ' + s(pa4.name)) ! cb.append('sa.name: ' + s(sa.name)) ! cb.append('psa1.name: ' + s(psa1.name)) ! cb.append('psa2.name: ' + s(psa2.name)) ! cb.append('psa3.name: ' + s(psa3.name)) ! cb.append('psa4.name: ' + s(psa4.name)) ! ! cb.append('a.auto_rebind: ' + s(a.auto_rebind)) ! cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) ! cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) ! cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) ! cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) ! cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) ! cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) ! cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) ! cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) ! cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) ! cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) ! cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) ! cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) ! cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) ! cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) ! cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) ! cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) ! cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) ! ! del s ! ! del a ! del pa1 ! del pa2 ! del pa3 ! del pa4 ! del sa ! del psa1 ! del psa2 ! del psa3 ! del psa4 ! del psa5 ! del psa6 ! del psa7 ! del psa8 ! del psa9 ! del psaA ! del psaB ! del psaC ! del psar ! del ecall EOF :" :" Test stdout/stderr --- 1029,1116 ---- :py ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) :py ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) :py ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) ! py << trim EOF ! def s(v): ! if v is None: ! return repr(v) ! else: ! return vim.Function('string')(v) ! ! cb.append('a.args: ' + s(a.args)) ! cb.append('pa1.args: ' + s(pa1.args)) ! cb.append('pa2.args: ' + s(pa2.args)) ! cb.append('pa3.args: ' + s(pa3.args)) ! cb.append('pa4.args: ' + s(pa4.args)) ! cb.append('sa.args: ' + s(sa.args)) ! cb.append('psa1.args: ' + s(psa1.args)) ! cb.append('psa2.args: ' + s(psa2.args)) ! cb.append('psa3.args: ' + s(psa3.args)) ! cb.append('psa4.args: ' + s(psa4.args)) ! ! cb.append('a.self: ' + s(a.self)) ! cb.append('pa1.self: ' + s(pa1.self)) ! cb.append('pa2.self: ' + s(pa2.self)) ! cb.append('pa3.self: ' + s(pa3.self)) ! cb.append('pa4.self: ' + s(pa4.self)) ! cb.append('sa.self: ' + s(sa.self)) ! cb.append('psa1.self: ' + s(psa1.self)) ! cb.append('psa2.self: ' + s(psa2.self)) ! cb.append('psa3.self: ' + s(psa3.self)) ! cb.append('psa4.self: ' + s(psa4.self)) ! ! cb.append('a.name: ' + s(a.name)) ! cb.append('pa1.name: ' + s(pa1.name)) ! cb.append('pa2.name: ' + s(pa2.name)) ! cb.append('pa3.name: ' + s(pa3.name)) ! cb.append('pa4.name: ' + s(pa4.name)) ! cb.append('sa.name: ' + s(sa.name)) ! cb.append('psa1.name: ' + s(psa1.name)) ! cb.append('psa2.name: ' + s(psa2.name)) ! cb.append('psa3.name: ' + s(psa3.name)) ! cb.append('psa4.name: ' + s(psa4.name)) ! ! cb.append('a.auto_rebind: ' + s(a.auto_rebind)) ! cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) ! cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) ! cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) ! cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) ! cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) ! cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) ! cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) ! cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) ! cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) ! cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) ! cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) ! cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) ! cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) ! cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) ! cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) ! cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) ! cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) ! ! del s ! ! del a ! del pa1 ! del pa2 ! del pa3 ! del pa4 ! del sa ! del psa1 ! del psa2 ! del psa3 ! del psa4 ! del psa5 ! del psa6 ! del psa7 ! del psa8 ! del psa9 ! del psaA ! del psaB ! del psaC ! del psar ! del ecall EOF :" :" Test stdout/stderr *************** *** 1126,1152 **** : $put =string(a:000) : return a:000 :endfun ! py << EOF ! class DupDict(vim.Dictionary): ! def __setitem__(self, key, value): ! super(DupDict, self).__setitem__(key, value) ! super(DupDict, self).__setitem__('dup_' + key, value) ! dd = DupDict() ! dd['a'] = 'b' ! ! class DupList(vim.List): ! def __getitem__(self, idx): ! return [super(DupList, self).__getitem__(idx)] * 2 ! ! dl = DupList() ! dl2 = DupList(iter('abcC')) ! dl.extend(dl2[0]) ! ! class DupFun(vim.Function): ! def __call__(self, arg): ! return super(DupFun, self).__call__(arg, arg) ! df = DupFun('Put') EOF :$put =string(sort(keys(pyeval('dd')))) :$put =string(pyeval('dl')) --- 1126,1152 ---- : $put =string(a:000) : return a:000 :endfun ! py << trim EOF ! class DupDict(vim.Dictionary): ! def __setitem__(self, key, value): ! super(DupDict, self).__setitem__(key, value) ! super(DupDict, self).__setitem__('dup_' + key, value) ! dd = DupDict() ! dd['a'] = 'b' ! ! class DupList(vim.List): ! def __getitem__(self, idx): ! return [super(DupList, self).__getitem__(idx)] * 2 ! ! dl = DupList() ! dl2 = DupList(iter('abcC')) ! dl.extend(dl2[0]) ! ! class DupFun(vim.Function): ! def __call__(self, arg): ! return super(DupFun, self).__call__(arg, arg) ! df = DupFun('Put') EOF :$put =string(sort(keys(pyeval('dd')))) :$put =string(pyeval('dl')) *************** *** 1156,1195 **** :$put =string(pyeval('dd') is# pyeval('dd')) :$put =string(pyeval('df')) :delfunction Put ! py << ! del DupDict ! del DupList ! del DupFun ! del dd ! del dl ! del dl2 ! del df . :" :" Test chdir ! py << EOF ! import os ! fnamemodify = vim.Function('fnamemodify') ! cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%')) ! os.chdir('..') ! path = fnamemodify('.', ':p:h:t') ! if path != 'src': ! # Running tests from a shadow directory, so move up another level ! # This will result in @% looking like shadow/testdir/test86.in, hence the ! # extra fnamemodify ! os.chdir('..') cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(fnamemodify(vim.eval('@%'), ':s?^%s.??' % path).replace(os.path.sep, '/')) ! os.chdir(path) ! del path ! else: cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%').replace(os.path.sep, '/')) ! os.chdir('testdir') ! cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%')) ! del fnamemodify EOF :" :" Test errors --- 1156,1195 ---- :$put =string(pyeval('dd') is# pyeval('dd')) :$put =string(pyeval('df')) :delfunction Put ! py << trim ! del DupDict ! del DupList ! del DupFun ! del dd ! del dl ! del dl2 ! del df . :" :" Test chdir ! py << trim EOF ! import os ! fnamemodify = vim.Function('fnamemodify') cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%')) ! os.chdir('..') ! path = fnamemodify('.', ':p:h:t') ! if path != 'src': ! # Running tests from a shadow directory, so move up another level ! # This will result in @% looking like shadow/testdir/test86.in, hence the ! # extra fnamemodify ! os.chdir('..') ! cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(fnamemodify(vim.eval('@%'), ':s?^%s.??' % path).replace(os.path.sep, '/')) ! os.chdir(path) ! del path ! else: ! cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%').replace(os.path.sep, '/')) ! os.chdir('testdir') cb.append(fnamemodify('.', ':p:h:t')) ! cb.append(vim.eval('@%')) ! del fnamemodify EOF :" :" Test errors *************** *** 1197,1660 **** :endfun :fun D() :endfun ! py << EOF ! d = vim.Dictionary() ! ned = vim.Dictionary(foo='bar', baz='abcD') ! dl = vim.Dictionary(a=1) ! dl.locked = True ! l = vim.List() ! ll = vim.List('abcE') ! ll.locked = True ! nel = vim.List('abcO') ! f = vim.Function('string') ! fd = vim.Function('F') ! fdel = vim.Function('D') ! vim.command('delfunction D') ! ! def subexpr_test(expr, name, subexprs): ! cb.append('>>> Testing %s using %s' % (name, expr)) ! for subexpr in subexprs: ! ee(expr % subexpr) ! cb.append('<<< Finished') ! ! def stringtochars_test(expr): ! return subexpr_test(expr, 'StringToChars', ( ! '1', # Fail type checks ! 'u"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check ! '"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check ! )) ! ! class Mapping(object): ! def __init__(self, d): ! self.d = d ! ! def __getitem__(self, key): ! return self.d[key] ! ! def keys(self): ! return self.d.keys() ! ! def items(self): ! return self.d.items() ! ! def convertfrompyobject_test(expr, recurse=True): ! # pydict_to_tv ! stringtochars_test(expr % '{%s : 1}') ! if recurse: ! convertfrompyobject_test(expr % '{"abcF" : %s}', False) ! # pymap_to_tv ! stringtochars_test(expr % 'Mapping({%s : 1})') ! if recurse: ! convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) ! # pyseq_to_tv ! iter_test(expr) ! return subexpr_test(expr, 'ConvertFromPyObject', ( ! 'None', # Not conversible ! '{"": 1}', # Empty key not allowed ! '{u"": 1}', # Same, but with unicode object ! 'FailingMapping()', # ! 'FailingMappingKey()', # ! 'FailingNumber()', # ! )) ! ! def convertfrompymapping_test(expr): ! convertfrompyobject_test(expr) ! return subexpr_test(expr, 'ConvertFromPyMapping', ( ! '[]', ! )) ! ! def iter_test(expr): ! return subexpr_test(expr, '*Iter*', ( ! 'FailingIter()', ! 'FailingIterNext()', ! )) ! ! def number_test(expr, natural=False, unsigned=False): ! if natural: ! unsigned = True ! return subexpr_test(expr, 'NumberToLong', ( ! '[]', ! 'None', ! ) + (unsigned and ('-1',) or ()) ! + (natural and ('0',) or ())) ! ! class FailingTrue(object): ! def __nonzero__(self): ! raise NotImplementedError('bool') ! ! class FailingIter(object): ! def __iter__(self): ! raise NotImplementedError('iter') ! ! class FailingIterNext(object): ! def __iter__(self): ! return self ! ! def next(self): ! raise NotImplementedError('next') ! ! class FailingIterNextN(object): ! def __init__(self, n): ! self.n = n ! ! def __iter__(self): ! return self ! ! def next(self): ! if self.n: ! self.n -= 1 ! return 1 ! else: ! raise NotImplementedError('next N') ! ! class FailingMappingKey(object): ! def __getitem__(self, item): ! raise NotImplementedError('getitem:mappingkey') ! ! def keys(self): ! return list("abcH") ! ! class FailingMapping(object): ! def __getitem__(self): ! raise NotImplementedError('getitem:mapping') ! ! def keys(self): ! raise NotImplementedError('keys') ! ! class FailingList(list): ! def __getitem__(self, idx): ! if i == 2: ! raise NotImplementedError('getitem:list') ! else: ! return super(FailingList, self).__getitem__(idx) ! ! class NoArgsCall(object): ! def __call__(self): ! pass ! ! class FailingCall(object): ! def __call__(self, path): ! raise NotImplementedError('call') ! ! class FailingNumber(object): ! def __int__(self): ! raise NotImplementedError('int') ! ! cb.append("> Output") ! cb.append(">> OutputSetattr") ! ee('del sys.stdout.softspace') ! number_test('sys.stdout.softspace = %s', unsigned=True) ! number_test('sys.stderr.softspace = %s', unsigned=True) ! ee('assert sys.stdout.isatty()==False') ! ee('assert sys.stdout.seekable()==False') ! ee('sys.stdout.close()') ! ee('sys.stdout.flush()') ! ee('assert sys.stderr.isatty()==False') ! ee('assert sys.stderr.seekable()==False') ! ee('sys.stderr.close()') ! ee('sys.stderr.flush()') ! ee('sys.stdout.attr = None') ! cb.append(">> OutputWrite") ! ee('assert sys.stdout.writable()==True') ! ee('assert sys.stdout.readable()==False') ! ee('assert sys.stderr.writable()==True') ! ee('assert sys.stderr.readable()==False') ! ee('assert sys.stdout.closed()==False') ! ee('assert sys.stderr.closed()==False') ! ee('assert sys.stdout.errors=="strict"') ! ee('assert sys.stderr.errors=="strict"') ! ee('assert sys.stdout.encoding==sys.stderr.encoding') ! ee('sys.stdout.write(None)') ! cb.append(">> OutputWriteLines") ! ee('sys.stdout.writelines(None)') ! ee('sys.stdout.writelines([1])') ! iter_test('sys.stdout.writelines(%s)') ! cb.append("> VimCommand") ! stringtochars_test('vim.command(%s)') ! ee('vim.command("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimToPython") ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEval") ! stringtochars_test('vim.eval(%s)') ! ee('vim.eval("", FailingTrue())') ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEvalPy") ! stringtochars_test('vim.bindeval(%s)') ! ee('vim.eval("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimStrwidth") ! stringtochars_test('vim.strwidth(%s)') ! cb.append("> VimForeachRTP") ! ee('vim.foreach_rtp(None)') ! ee('vim.foreach_rtp(NoArgsCall())') ! ee('vim.foreach_rtp(FailingCall())') ! ee('vim.foreach_rtp(int, 2)') ! cb.append('> import') ! old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ! ee('import xxx_no_such_module_xxx') ! ee('import failing_import') ! ee('import failing') ! vim.options['rtp'] = old_rtp ! del old_rtp ! cb.append("> Options") ! cb.append(">> OptionsItem") ! ee('vim.options["abcQ"]') ! ee('vim.options[""]') ! stringtochars_test('vim.options[%s]') ! cb.append(">> OptionsContains") ! stringtochars_test('%s in vim.options') ! cb.append("> Dictionary") ! cb.append(">> DictionaryConstructor") ! ee('vim.Dictionary("abcI")') ! ##! Not checked: py_dict_alloc failure ! cb.append(">> DictionarySetattr") ! ee('del d.locked') ! ee('d.locked = FailingTrue()') ! ee('vim.vvars.locked = False') ! ee('d.scope = True') ! ee('d.xxx = True') ! cb.append(">> _DictionaryItem") ! ee('d.get("a", 2, 3)') ! stringtochars_test('d.get(%s)') ! ee('d.pop("a")') ! ee('dl.pop("a")') ! cb.append(">> DictionaryContains") ! ee('"" in d') ! ee('0 in d') ! cb.append(">> DictionaryIterNext") ! ee('for i in ned: ned["a"] = 1') ! del i ! cb.append(">> DictionaryAssItem") ! ee('dl["b"] = 1') ! stringtochars_test('d[%s] = 1') ! convertfrompyobject_test('d["a"] = %s') ! cb.append(">> DictionaryUpdate") ! cb.append(">>> kwargs") ! cb.append(">>> iter") ! ee('d.update(FailingMapping())') ! ee('d.update([FailingIterNext()])') ! ee('d.update([FailingIterNextN(1)])') ! iter_test('d.update(%s)') ! convertfrompyobject_test('d.update(%s)') ! stringtochars_test('d.update(((%s, 0),))') ! convertfrompyobject_test('d.update((("a", %s),))') ! cb.append(">> DictionaryPopItem") ! ee('d.popitem(1, 2)') ! cb.append(">> DictionaryHasKey") ! ee('d.has_key()') ! cb.append("> List") ! cb.append(">> ListConstructor") ! ee('vim.List(1, 2)') ! ee('vim.List(a=1)') ! iter_test('vim.List(%s)') ! convertfrompyobject_test('vim.List([%s])') ! cb.append(">> ListItem") ! ee('l[1000]') ! cb.append(">> ListAssItem") ! ee('ll[1] = 2') ! ee('l[1000] = 3') ! cb.append(">> ListAssSlice") ! ee('ll[1:100] = "abcJ"') ! iter_test('l[:] = %s') ! ee('nel[1:10:2] = "abcK"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:10:2] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:1:-1] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[:] = FailingIterNextN(2)') ! cb.append(repr(tuple(nel))) ! convertfrompyobject_test('l[:] = [%s]') ! cb.append(">> ListConcatInPlace") ! iter_test('l.extend(%s)') ! convertfrompyobject_test('l.extend([%s])') ! cb.append(">> ListSetattr") ! ee('del l.locked') ! ee('l.locked = FailingTrue()') ! ee('l.xxx = True') ! cb.append("> Function") ! cb.append(">> FunctionConstructor") ! cb.append(">>> FunctionConstructor") ! ee('vim.Function("123")') ! ee('vim.Function("xxx_non_existent_function_xxx")') ! ee('vim.Function("xxx#non#existent#function#xxx")') ! ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') ! ee('vim.Function("xxx_non_existent_function_xxx3", self={})') ! ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') ! cb.append(">>> FunctionNew") ! ee('vim.Function("tr", self="abcFuncSelf")') ! ee('vim.Function("tr", args=427423)') ! ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "")') ! cb.append(">> FunctionCall") ! convertfrompyobject_test('f(%s)') ! convertfrompymapping_test('fd(self=%s)') ! cb.append("> TabPage") ! cb.append(">> TabPageAttr") ! ee('vim.current.tabpage.xxx') ! cb.append("> TabList") ! cb.append(">> TabListItem") ! ee('vim.tabpages[1000]') ! cb.append("> Window") ! cb.append(">> WindowAttr") ! ee('vim.current.window.xxx') ! cb.append(">> WindowSetattr") ! ee('vim.current.window.buffer = 0') ! ee('vim.current.window.cursor = (100000000, 100000000)') ! ee('vim.current.window.cursor = True') ! number_test('vim.current.window.height = %s', unsigned=True) ! number_test('vim.current.window.width = %s', unsigned=True) ! ee('vim.current.window.xxxxxx = True') ! cb.append("> WinList") ! cb.append(">> WinListItem") ! ee('vim.windows[1000]') ! cb.append("> Buffer") ! cb.append(">> StringToLine (indirect)") ! ee('vim.current.buffer[0] = u"\\na"') ! ee('vim.current.buffer[0] = "\\na"') ! cb.append(">> SetBufferLine (indirect)") ! ee('vim.current.buffer[0] = True') ! cb.append(">> SetBufferLineList (indirect)") ! ee('vim.current.buffer[:] = True') ! ee('vim.current.buffer[:] = ["\\na", "bc"]') ! cb.append(">> InsertBufferLines (indirect)") ! ee('vim.current.buffer.append(None)') ! ee('vim.current.buffer.append(["\\na", "bc"])') ! ee('vim.current.buffer.append("\\nbc")') ! cb.append(">> RBItem") ! ee('vim.current.buffer[100000000]') ! cb.append(">> RBAsItem") ! ee('vim.current.buffer[100000000] = ""') ! cb.append(">> BufferAttr") ! ee('vim.current.buffer.xxx') ! cb.append(">> BufferSetattr") ! ee('vim.current.buffer.name = True') ! ee('vim.current.buffer.xxx = True') ! cb.append(">> BufferMark") ! ee('vim.current.buffer.mark(0)') ! ee('vim.current.buffer.mark("abcM")') ! ee('vim.current.buffer.mark("!")') ! cb.append(">> BufferRange") ! ee('vim.current.buffer.range(1, 2, 3)') ! cb.append("> BufMap") ! cb.append(">> BufMapItem") ! ee('vim.buffers[100000000]') ! number_test('vim.buffers[%s]', natural=True) ! cb.append("> Current") ! cb.append(">> CurrentGetattr") ! ee('vim.current.xxx') ! cb.append(">> CurrentSetattr") ! ee('vim.current.line = True') ! ee('vim.current.buffer = True') ! ee('vim.current.window = True') ! ee('vim.current.tabpage = True') ! ee('vim.current.xxx = True') ! del d ! del ned ! del dl ! del l ! del ll ! del nel ! del f ! del fd ! del fdel ! del subexpr_test ! del stringtochars_test ! del Mapping ! del convertfrompyobject_test ! del convertfrompymapping_test ! del iter_test ! del number_test ! del FailingTrue ! del FailingIter ! del FailingIterNext ! del FailingIterNextN ! del FailingMapping ! del FailingMappingKey ! del FailingList ! del NoArgsCall ! del FailingCall ! del FailingNumber EOF :delfunction F :" :" Test import ! py << EOF ! sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) ! sys.path.append(os.path.join(os.getcwd(), 'python_after')) ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ! l = [] ! def callback(path): ! l.append(path[-len('/testdir'):].replace(os.path.sep, '/')) ! vim.foreach_rtp(callback) ! cb.append(repr(l)) ! del l ! def callback(path): ! return path[-len('/testdir'):].replace(os.path.sep, '/') ! cb.append(repr(vim.foreach_rtp(callback))) ! del callback ! from module import dir as d ! from modulex import ddir ! cb.append(d + ',' + ddir) ! import before ! cb.append(before.dir) ! import after ! cb.append(after.dir) ! import topmodule as tm ! import topmodule.submodule as tms ! import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss ! cb.append(tm.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) ! cb.append(tms.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) ! cb.append(tmsss.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) ! del before ! del after ! del d ! del ddir ! del tm ! del tms ! del tmsss EOF :" :" Test exceptions :fun Exe(e) : execute a:e :endfun ! py << EOF ! Exe = vim.bindeval('function("Exe")') ! ee('vim.command("throw \'abcN\'")') ! ee('Exe("throw \'def\'")') ! ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ! ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ! ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') ! ee('vim.eval("xxx_unknown_function_xxx()")') ! ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') ! del Exe EOF :delfunction Exe :" :" Regression: interrupting vim.command propagates to next vim.command ! py << EOF ! def test_keyboard_interrupt(): ! try: ! vim.command('while 1 | endwhile') ! except KeyboardInterrupt: ! cb.append('Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('!!!!!!!! No exception') ! try: ! vim.command('$ put =\'Running :put\'') ! except KeyboardInterrupt: ! cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('No exception') EOF :debuggreedy :call inputsave() --- 1197,1660 ---- :endfun :fun D() :endfun ! py << trim EOF ! d = vim.Dictionary() ! ned = vim.Dictionary(foo='bar', baz='abcD') ! dl = vim.Dictionary(a=1) ! dl.locked = True ! l = vim.List() ! ll = vim.List('abcE') ! ll.locked = True ! nel = vim.List('abcO') ! f = vim.Function('string') ! fd = vim.Function('F') ! fdel = vim.Function('D') ! vim.command('delfunction D') ! ! def subexpr_test(expr, name, subexprs): ! cb.append('>>> Testing %s using %s' % (name, expr)) ! for subexpr in subexprs: ! ee(expr % subexpr) ! cb.append('<<< Finished') ! ! def stringtochars_test(expr): ! return subexpr_test(expr, 'StringToChars', ( ! '1', # Fail type checks ! 'u"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check ! '"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check ! )) ! ! class Mapping(object): ! def __init__(self, d): ! self.d = d ! ! def __getitem__(self, key): ! return self.d[key] ! ! def keys(self): ! return self.d.keys() ! ! def items(self): ! return self.d.items() ! ! def convertfrompyobject_test(expr, recurse=True): ! # pydict_to_tv ! stringtochars_test(expr % '{%s : 1}') ! if recurse: ! convertfrompyobject_test(expr % '{"abcF" : %s}', False) ! # pymap_to_tv ! stringtochars_test(expr % 'Mapping({%s : 1})') ! if recurse: ! convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) ! # pyseq_to_tv ! iter_test(expr) ! return subexpr_test(expr, 'ConvertFromPyObject', ( ! 'None', # Not conversible ! '{"": 1}', # Empty key not allowed ! '{u"": 1}', # Same, but with unicode object ! 'FailingMapping()', # ! 'FailingMappingKey()', # ! 'FailingNumber()', # ! )) ! ! def convertfrompymapping_test(expr): ! convertfrompyobject_test(expr) ! return subexpr_test(expr, 'ConvertFromPyMapping', ( ! '[]', ! )) ! ! def iter_test(expr): ! return subexpr_test(expr, '*Iter*', ( ! 'FailingIter()', ! 'FailingIterNext()', ! )) ! ! def number_test(expr, natural=False, unsigned=False): ! if natural: ! unsigned = True ! return subexpr_test(expr, 'NumberToLong', ( ! '[]', ! 'None', ! ) + (unsigned and ('-1',) or ()) ! + (natural and ('0',) or ())) ! ! class FailingTrue(object): ! def __nonzero__(self): ! raise NotImplementedError('bool') ! ! class FailingIter(object): ! def __iter__(self): ! raise NotImplementedError('iter') ! ! class FailingIterNext(object): ! def __iter__(self): ! return self ! ! def next(self): ! raise NotImplementedError('next') ! ! class FailingIterNextN(object): ! def __init__(self, n): ! self.n = n ! ! def __iter__(self): ! return self ! ! def next(self): ! if self.n: ! self.n -= 1 ! return 1 ! else: ! raise NotImplementedError('next N') ! ! class FailingMappingKey(object): ! def __getitem__(self, item): ! raise NotImplementedError('getitem:mappingkey') ! ! def keys(self): ! return list("abcH") ! ! class FailingMapping(object): ! def __getitem__(self): ! raise NotImplementedError('getitem:mapping') ! ! def keys(self): ! raise NotImplementedError('keys') ! ! class FailingList(list): ! def __getitem__(self, idx): ! if i == 2: ! raise NotImplementedError('getitem:list') ! else: ! return super(FailingList, self).__getitem__(idx) ! ! class NoArgsCall(object): ! def __call__(self): ! pass ! ! class FailingCall(object): ! def __call__(self, path): ! raise NotImplementedError('call') ! ! class FailingNumber(object): ! def __int__(self): ! raise NotImplementedError('int') ! ! cb.append("> Output") ! cb.append(">> OutputSetattr") ! ee('del sys.stdout.softspace') ! number_test('sys.stdout.softspace = %s', unsigned=True) ! number_test('sys.stderr.softspace = %s', unsigned=True) ! ee('assert sys.stdout.isatty()==False') ! ee('assert sys.stdout.seekable()==False') ! ee('sys.stdout.close()') ! ee('sys.stdout.flush()') ! ee('assert sys.stderr.isatty()==False') ! ee('assert sys.stderr.seekable()==False') ! ee('sys.stderr.close()') ! ee('sys.stderr.flush()') ! ee('sys.stdout.attr = None') ! cb.append(">> OutputWrite") ! ee('assert sys.stdout.writable()==True') ! ee('assert sys.stdout.readable()==False') ! ee('assert sys.stderr.writable()==True') ! ee('assert sys.stderr.readable()==False') ! ee('assert sys.stdout.closed()==False') ! ee('assert sys.stderr.closed()==False') ! ee('assert sys.stdout.errors=="strict"') ! ee('assert sys.stderr.errors=="strict"') ! ee('assert sys.stdout.encoding==sys.stderr.encoding') ! ee('sys.stdout.write(None)') ! cb.append(">> OutputWriteLines") ! ee('sys.stdout.writelines(None)') ! ee('sys.stdout.writelines([1])') ! iter_test('sys.stdout.writelines(%s)') ! cb.append("> VimCommand") ! stringtochars_test('vim.command(%s)') ! ee('vim.command("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimToPython") ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEval") ! stringtochars_test('vim.eval(%s)') ! ee('vim.eval("", FailingTrue())') ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEvalPy") ! stringtochars_test('vim.bindeval(%s)') ! ee('vim.eval("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimStrwidth") ! stringtochars_test('vim.strwidth(%s)') ! cb.append("> VimForeachRTP") ! ee('vim.foreach_rtp(None)') ! ee('vim.foreach_rtp(NoArgsCall())') ! ee('vim.foreach_rtp(FailingCall())') ! ee('vim.foreach_rtp(int, 2)') ! cb.append('> import') ! old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ! ee('import xxx_no_such_module_xxx') ! ee('import failing_import') ! ee('import failing') ! vim.options['rtp'] = old_rtp ! del old_rtp ! cb.append("> Options") ! cb.append(">> OptionsItem") ! ee('vim.options["abcQ"]') ! ee('vim.options[""]') ! stringtochars_test('vim.options[%s]') ! cb.append(">> OptionsContains") ! stringtochars_test('%s in vim.options') ! cb.append("> Dictionary") ! cb.append(">> DictionaryConstructor") ! ee('vim.Dictionary("abcI")') ! ##! Not checked: py_dict_alloc failure ! cb.append(">> DictionarySetattr") ! ee('del d.locked') ! ee('d.locked = FailingTrue()') ! ee('vim.vvars.locked = False') ! ee('d.scope = True') ! ee('d.xxx = True') ! cb.append(">> _DictionaryItem") ! ee('d.get("a", 2, 3)') ! stringtochars_test('d.get(%s)') ! ee('d.pop("a")') ! ee('dl.pop("a")') ! cb.append(">> DictionaryContains") ! ee('"" in d') ! ee('0 in d') ! cb.append(">> DictionaryIterNext") ! ee('for i in ned: ned["a"] = 1') ! del i ! cb.append(">> DictionaryAssItem") ! ee('dl["b"] = 1') ! stringtochars_test('d[%s] = 1') ! convertfrompyobject_test('d["a"] = %s') ! cb.append(">> DictionaryUpdate") ! cb.append(">>> kwargs") ! cb.append(">>> iter") ! ee('d.update(FailingMapping())') ! ee('d.update([FailingIterNext()])') ! ee('d.update([FailingIterNextN(1)])') ! iter_test('d.update(%s)') ! convertfrompyobject_test('d.update(%s)') ! stringtochars_test('d.update(((%s, 0),))') ! convertfrompyobject_test('d.update((("a", %s),))') ! cb.append(">> DictionaryPopItem") ! ee('d.popitem(1, 2)') ! cb.append(">> DictionaryHasKey") ! ee('d.has_key()') ! cb.append("> List") ! cb.append(">> ListConstructor") ! ee('vim.List(1, 2)') ! ee('vim.List(a=1)') ! iter_test('vim.List(%s)') ! convertfrompyobject_test('vim.List([%s])') ! cb.append(">> ListItem") ! ee('l[1000]') ! cb.append(">> ListAssItem") ! ee('ll[1] = 2') ! ee('l[1000] = 3') ! cb.append(">> ListAssSlice") ! ee('ll[1:100] = "abcJ"') ! iter_test('l[:] = %s') ! ee('nel[1:10:2] = "abcK"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:10:2] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:1:-1] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[:] = FailingIterNextN(2)') ! cb.append(repr(tuple(nel))) ! convertfrompyobject_test('l[:] = [%s]') ! cb.append(">> ListConcatInPlace") ! iter_test('l.extend(%s)') ! convertfrompyobject_test('l.extend([%s])') ! cb.append(">> ListSetattr") ! ee('del l.locked') ! ee('l.locked = FailingTrue()') ! ee('l.xxx = True') ! cb.append("> Function") ! cb.append(">> FunctionConstructor") ! cb.append(">>> FunctionConstructor") ! ee('vim.Function("123")') ! ee('vim.Function("xxx_non_existent_function_xxx")') ! ee('vim.Function("xxx#non#existent#function#xxx")') ! ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') ! ee('vim.Function("xxx_non_existent_function_xxx3", self={})') ! ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') ! cb.append(">>> FunctionNew") ! ee('vim.Function("tr", self="abcFuncSelf")') ! ee('vim.Function("tr", args=427423)') ! ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "")') ! cb.append(">> FunctionCall") ! convertfrompyobject_test('f(%s)') ! convertfrompymapping_test('fd(self=%s)') ! cb.append("> TabPage") ! cb.append(">> TabPageAttr") ! ee('vim.current.tabpage.xxx') ! cb.append("> TabList") ! cb.append(">> TabListItem") ! ee('vim.tabpages[1000]') ! cb.append("> Window") ! cb.append(">> WindowAttr") ! ee('vim.current.window.xxx') ! cb.append(">> WindowSetattr") ! ee('vim.current.window.buffer = 0') ! ee('vim.current.window.cursor = (100000000, 100000000)') ! ee('vim.current.window.cursor = True') ! number_test('vim.current.window.height = %s', unsigned=True) ! number_test('vim.current.window.width = %s', unsigned=True) ! ee('vim.current.window.xxxxxx = True') ! cb.append("> WinList") ! cb.append(">> WinListItem") ! ee('vim.windows[1000]') ! cb.append("> Buffer") ! cb.append(">> StringToLine (indirect)") ! ee('vim.current.buffer[0] = u"\\na"') ! ee('vim.current.buffer[0] = "\\na"') ! cb.append(">> SetBufferLine (indirect)") ! ee('vim.current.buffer[0] = True') ! cb.append(">> SetBufferLineList (indirect)") ! ee('vim.current.buffer[:] = True') ! ee('vim.current.buffer[:] = ["\\na", "bc"]') ! cb.append(">> InsertBufferLines (indirect)") ! ee('vim.current.buffer.append(None)') ! ee('vim.current.buffer.append(["\\na", "bc"])') ! ee('vim.current.buffer.append("\\nbc")') ! cb.append(">> RBItem") ! ee('vim.current.buffer[100000000]') ! cb.append(">> RBAsItem") ! ee('vim.current.buffer[100000000] = ""') ! cb.append(">> BufferAttr") ! ee('vim.current.buffer.xxx') ! cb.append(">> BufferSetattr") ! ee('vim.current.buffer.name = True') ! ee('vim.current.buffer.xxx = True') ! cb.append(">> BufferMark") ! ee('vim.current.buffer.mark(0)') ! ee('vim.current.buffer.mark("abcM")') ! ee('vim.current.buffer.mark("!")') ! cb.append(">> BufferRange") ! ee('vim.current.buffer.range(1, 2, 3)') ! cb.append("> BufMap") ! cb.append(">> BufMapItem") ! ee('vim.buffers[100000000]') ! number_test('vim.buffers[%s]', natural=True) ! cb.append("> Current") ! cb.append(">> CurrentGetattr") ! ee('vim.current.xxx') ! cb.append(">> CurrentSetattr") ! ee('vim.current.line = True') ! ee('vim.current.buffer = True') ! ee('vim.current.window = True') ! ee('vim.current.tabpage = True') ! ee('vim.current.xxx = True') ! del d ! del ned ! del dl ! del l ! del ll ! del nel ! del f ! del fd ! del fdel ! del subexpr_test ! del stringtochars_test ! del Mapping ! del convertfrompyobject_test ! del convertfrompymapping_test ! del iter_test ! del number_test ! del FailingTrue ! del FailingIter ! del FailingIterNext ! del FailingIterNextN ! del FailingMapping ! del FailingMappingKey ! del FailingList ! del NoArgsCall ! del FailingCall ! del FailingNumber EOF :delfunction F :" :" Test import ! py << trim EOF ! sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) ! sys.path.append(os.path.join(os.getcwd(), 'python_after')) ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ! l = [] ! def callback(path): ! l.append(path[-len('/testdir'):].replace(os.path.sep, '/')) ! vim.foreach_rtp(callback) ! cb.append(repr(l)) ! del l ! def callback(path): ! return path[-len('/testdir'):].replace(os.path.sep, '/') ! cb.append(repr(vim.foreach_rtp(callback))) ! del callback ! from module import dir as d ! from modulex import ddir ! cb.append(d + ',' + ddir) ! import before ! cb.append(before.dir) ! import after ! cb.append(after.dir) ! import topmodule as tm ! import topmodule.submodule as tms ! import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss ! cb.append(tm.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) ! cb.append(tms.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) ! cb.append(tmsss.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) ! del before ! del after ! del d ! del ddir ! del tm ! del tms ! del tmsss EOF :" :" Test exceptions :fun Exe(e) : execute a:e :endfun ! py << trim EOF ! Exe = vim.bindeval('function("Exe")') ! ee('vim.command("throw \'abcN\'")') ! ee('Exe("throw \'def\'")') ! ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ! ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ! ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') ! ee('vim.eval("xxx_unknown_function_xxx()")') ! ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') ! del Exe EOF :delfunction Exe :" :" Regression: interrupting vim.command propagates to next vim.command ! py << trim EOF ! def test_keyboard_interrupt(): ! try: ! vim.command('while 1 | endwhile') ! except KeyboardInterrupt: ! cb.append('Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('!!!!!!!! No exception') ! try: ! vim.command('$ put =\'Running :put\'') ! except KeyboardInterrupt: ! cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('No exception') EOF :debuggreedy :call inputsave() *************** *** 1669,1681 **** :py del test_keyboard_interrupt :" :" Cleanup ! py << EOF ! del cb ! del ee ! del emsg ! del sys ! del os ! del vim EOF :endfun :" --- 1669,1681 ---- :py del test_keyboard_interrupt :" :" Cleanup ! py << trim EOF ! del cb ! del ee ! del emsg ! del sys ! del os ! del vim EOF :endfun :" *** ../vim-8.2.0577/src/testdir/test87.in 2019-12-01 14:26:07.000000000 +0100 --- src/testdir/test87.in 2020-04-14 20:04:20.133971191 +0200 *************** *** 31,49 **** :fun d.f() : return 1 :endfun ! py3 << EOF ! d=vim.bindeval('d') ! d['1']='asd' ! d.update() # Must not do anything, including throwing errors ! d.update(b=[1, 2, f]) ! d.update((('-1', {'a': 1}),)) ! d.update({'0': -1}) ! dk = d.keys() ! dv = d.values() ! di = d.items() ! dk.sort(key=repr) ! dv.sort(key=repr) ! di.sort(key=repr) EOF :$put =py3eval('d[''f''](self={})') :$put =py3eval('repr(dk)') --- 31,49 ---- :fun d.f() : return 1 :endfun ! py3 << trim EOF ! d=vim.bindeval('d') ! d['1']='asd' ! d.update() # Must not do anything, including throwing errors ! d.update(b=[1, 2, f]) ! d.update((('-1', {'a': 1}),)) ! d.update({'0': -1}) ! dk = d.keys() ! dv = d.values() ! di = d.items() ! dk.sort(key=repr) ! dv.sort(key=repr) ! di.sort(key=repr) EOF :$put =py3eval('d[''f''](self={})') :$put =py3eval('repr(dk)') *************** *** 201,277 **** :let l = [0, 1, 2, 3] :py3 l=vim.bindeval('l') :lockvar! l ! py3 << EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) EOF :$put =string(l) :unlockvar! l :" :" Function calls ! py3 << EOF ! import sys ! import re ! ! py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') ! py37_exception_repr = re.compile(r'([^\(\),])(\)+)$') ! ! def ee(expr, g=globals(), l=locals()): ! cb = vim.current.buffer ! try: ! try: ! exec(expr, g, l) ! except Exception as e: ! 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."): ! msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1]))) ! elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: ! msg = repr((e.__class__, ImportError(str(e).replace("'", '')))) ! elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError: ! # Python 3.6 gives ModuleNotFoundError, change it to an ImportError ! msg = repr((ImportError, ImportError(str(e).replace("'", '')))) ! elif sys.version_info >= (3, 3) and e.__class__ is TypeError: ! m = py33_type_error_pattern.search(str(e)) ! if m: ! msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) ! msg = repr((e.__class__, TypeError(msg))) ! else: ! msg = repr((e.__class__, e)) ! # Messages changed with Python 3.6, change new to old. ! newmsg1 = """'argument must be str, bytes or bytearray, not None'""" ! oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"''' ! if msg.find(newmsg1) > -1: ! msg = msg.replace(newmsg1, oldmsg1) ! newmsg2 = """'argument must be str, bytes or bytearray, not int'""" ! oldmsg2 = '''"Can't convert 'int' object to str implicitly"''' ! if msg.find(newmsg2) > -1: ! msg = msg.replace(newmsg2, oldmsg2) ! elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte': ! msg = repr((TypeError, TypeError('expected bytes with no null'))) ! else: ! msg = repr((e.__class__, e)) ! # Some Python versions say can't, others cannot. ! if msg.find('can\'t') > -1: ! msg = msg.replace('can\'t', 'cannot') ! # Some Python versions use single quote, some double quote ! if msg.find('"cannot ') > -1: ! msg = msg.replace('"cannot ', '\'cannot ') ! if msg.find(' attributes"') > -1: ! msg = msg.replace(' attributes"', ' attributes\'') ! if sys.version_info >= (3, 7): ! msg = py37_exception_repr.sub(r'\1,\2', msg) ! cb.append(expr + ':' + msg) ! else: ! cb.append(expr + ':NOT FAILED') ! except Exception as e: ! msg = repr((e.__class__, e)) ! if sys.version_info >= (3, 7): ! msg = py37_exception_repr.sub(r'\1,\2', msg) ! cb.append(expr + '::' + msg) EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] --- 201,277 ---- :let l = [0, 1, 2, 3] :py3 l=vim.bindeval('l') :lockvar! l ! py3 << trim EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) EOF :$put =string(l) :unlockvar! l :" :" Function calls ! py3 << trim EOF ! import sys ! import re ! ! py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') ! py37_exception_repr = re.compile(r'([^\(\),])(\)+)$') ! ! def ee(expr, g=globals(), l=locals()): ! cb = vim.current.buffer ! try: ! try: ! exec(expr, g, l) ! except Exception as e: ! 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."): ! msg = repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1]))) ! elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: ! msg = repr((e.__class__, ImportError(str(e).replace("'", '')))) ! elif sys.version_info >= (3, 6) and e.__class__ is ModuleNotFoundError: ! # Python 3.6 gives ModuleNotFoundError, change it to an ImportError ! msg = repr((ImportError, ImportError(str(e).replace("'", '')))) ! elif sys.version_info >= (3, 3) and e.__class__ is TypeError: ! m = py33_type_error_pattern.search(str(e)) ! if m: ! msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) ! msg = repr((e.__class__, TypeError(msg))) ! else: ! msg = repr((e.__class__, e)) ! # Messages changed with Python 3.6, change new to old. ! newmsg1 = """'argument must be str, bytes or bytearray, not None'""" ! oldmsg1 = '''"Can't convert 'NoneType' object to str implicitly"''' ! if msg.find(newmsg1) > -1: ! msg = msg.replace(newmsg1, oldmsg1) ! newmsg2 = """'argument must be str, bytes or bytearray, not int'""" ! oldmsg2 = '''"Can't convert 'int' object to str implicitly"''' ! if msg.find(newmsg2) > -1: ! msg = msg.replace(newmsg2, oldmsg2) ! elif sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte': ! msg = repr((TypeError, TypeError('expected bytes with no null'))) ! else: ! msg = repr((e.__class__, e)) ! # Some Python versions say can't, others cannot. ! if msg.find('can\'t') > -1: ! msg = msg.replace('can\'t', 'cannot') ! # Some Python versions use single quote, some double quote ! if msg.find('"cannot ') > -1: ! msg = msg.replace('"cannot ', '\'cannot ') ! if msg.find(' attributes"') > -1: ! msg = msg.replace(' attributes"', ' attributes\'') ! if sys.version_info >= (3, 7): ! msg = py37_exception_repr.sub(r'\1,\2', msg) ! cb.append(expr + ':' + msg) ! else: ! cb.append(expr + ':NOT FAILED') ! except Exception as e: ! msg = repr((e.__class__, e)) ! if sys.version_info >= (3, 7): ! msg = py37_exception_repr.sub(r'\1,\2', msg) ! cb.append(expr + '::' + msg) EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] *************** *** 301,330 **** :endif :let messages=[] :delfunction DictNew ! py3 <= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte': ! m.extend([TypeError.__name__]) ! else: ! m.extend([e.__class__.__name__]) ! ! em('d["abc1"]') ! em('d["abc1"]="\\0"') ! em('d["abc1"]=vim') ! em('d[""]=1') ! em('d["a\\0b"]=1') ! em('d[b"a\\0b"]=1') ! ! em('d.pop("abc1")') ! em('d.popitem()') ! del em ! del m EOF :$put =messages :unlet messages --- 301,330 ---- :endif :let messages=[] :delfunction DictNew ! py3 << trim EOF ! import sys ! d=vim.bindeval('{}') ! m=vim.bindeval('messages') ! def em(expr, g=globals(), l=locals()): ! try: ! exec(expr, g, l) ! except Exception as e: ! if sys.version_info >= (3, 5) and e.__class__ is ValueError and str(e) == 'embedded null byte': ! m.extend([TypeError.__name__]) ! else: ! m.extend([e.__class__.__name__]) ! ! em('d["abc1"]') ! em('d["abc1"]="\\0"') ! em('d["abc1"]=vim') ! em('d[""]=1') ! em('d["a\\0b"]=1') ! em('d[b"a\\0b"]=1') ! ! em('d.pop("abc1")') ! em('d.popitem()') ! del em ! del m EOF :$put =messages :unlet messages *************** *** 389,412 **** :" threading :let l = [0] :py3 l=vim.bindeval('l') ! py3 <")') + ':BufFilePost:' + vim.eval('bufnr("%")')) : autocmd BufFilePre * python3 cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END ! py3 << EOF ! # Tests BufferAppend and BufferItem ! cb.append(b[0]) ! # Tests BufferSlice and BufferAssSlice ! cb.append('abc5') # Will be overwritten ! cb[-1:] = b[:-2] ! # Test BufferLength and BufferAssSlice ! cb.append('def') # Will not be overwritten ! cb[len(cb):] = b[:] ! # Test BufferAssItem and BufferMark ! cb.append('ghi') # Will be overwritten ! cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) ! # Test BufferRepr ! cb.append(repr(cb) + repr(b)) ! # Modify foreign buffer ! b.append('foo') ! b[0]='bar' ! b[0:0]=['baz'] ! vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) ! # Test assigning to name property ! import os ! old_name = cb.name ! cb.name = 'foo' ! cb.append(cb.name[-11:].replace(os.path.sep, '/')) ! b.name = 'bar' ! cb.append(b.name[-11:].replace(os.path.sep, '/')) ! cb.name = old_name ! cb.append(cb.name[-17:].replace(os.path.sep, '/')) ! del old_name ! # Test CheckBuffer ! for _b in vim.buffers: ! if _b is not cb: ! vim.command('bwipeout! ' + str(_b.number)) ! del _b ! cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) ! for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'): ! try: ! exec(expr) ! except vim.error: ! pass ! else: ! # Usually a SEGV here ! # Should not happen in any case ! cb.append('No exception for ' + expr) ! vim.command('cd .') ! del b EOF :" :" Test vim.buffers object --- 649,700 ---- : autocmd BufFilePost * python3 cb.append(vim.eval('expand("")') + ':BufFilePost:' + vim.eval('bufnr("%")')) : autocmd BufFilePre * python3 cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END ! py3 << trim EOF ! # Tests BufferAppend and BufferItem ! cb.append(b[0]) ! # Tests BufferSlice and BufferAssSlice ! cb.append('abc5') # Will be overwritten ! cb[-1:] = b[:-2] ! # Test BufferLength and BufferAssSlice ! cb.append('def') # Will not be overwritten ! cb[len(cb):] = b[:] ! # Test BufferAssItem and BufferMark ! cb.append('ghi') # Will be overwritten ! cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) ! # Test BufferRepr ! cb.append(repr(cb) + repr(b)) ! # Modify foreign buffer ! b.append('foo') ! b[0]='bar' ! b[0:0]=['baz'] ! vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) ! # Test assigning to name property ! import os ! old_name = cb.name ! cb.name = 'foo' ! cb.append(cb.name[-11:].replace(os.path.sep, '/')) ! b.name = 'bar' ! cb.append(b.name[-11:].replace(os.path.sep, '/')) ! cb.name = old_name ! cb.append(cb.name[-17:].replace(os.path.sep, '/')) ! del old_name ! # Test CheckBuffer ! for _b in vim.buffers: ! if _b is not cb: ! vim.command('bwipeout! ' + str(_b.number)) ! del _b ! cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid))) ! for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'): ! try: ! exec(expr) ! except vim.error: ! pass ! else: ! # Usually a SEGV here ! # Should not happen in any case ! cb.append('No exception for ' + expr) ! vim.command('cd .') ! del b EOF :" :" Test vim.buffers object *************** *** 705,759 **** :buffer # :edit c :buffer # ! py3 << EOF ! # Check GCing iterator that was not fully exhausted ! i = iter(vim.buffers) ! cb.append('i:' + str(next(i))) ! # and also check creating more than one iterator at a time ! i2 = iter(vim.buffers) ! cb.append('i2:' + str(next(i2))) ! cb.append('i:' + str(next(i))) ! # The following should trigger GC and not cause any problems ! del i ! del i2 ! i3 = iter(vim.buffers) ! cb.append('i3:' + str(next(i3))) ! del i3 ! ! prevnum = 0 ! for b in vim.buffers: ! # Check buffer order ! if prevnum >= b.number: ! cb.append('!!! Buffer numbers not in strictly ascending order') ! # Check indexing: vim.buffers[number].number == number ! cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) ! prevnum = b.number ! del prevnum ! ! cb.append(str(len(vim.buffers))) ! ! bnums = list(map(lambda b: b.number, vim.buffers))[1:] ! ! # Test wiping out buffer with existing iterator ! i4 = iter(vim.buffers) ! cb.append('i4:' + str(next(i4))) ! vim.command('bwipeout! ' + str(bnums.pop(0))) ! try: ! next(i4) ! except vim.error: ! pass ! else: ! cb.append('!!!! No vim.error') ! i4 = iter(vim.buffers) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! cb.append('i4:' + str(next(i4))) ! try: ! next(i4) ! except StopIteration: ! cb.append('StopIteration') ! del i4 ! del bnums EOF :" :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects --- 705,759 ---- :buffer # :edit c :buffer # ! py3 << trim EOF ! # Check GCing iterator that was not fully exhausted ! i = iter(vim.buffers) ! cb.append('i:' + str(next(i))) ! # and also check creating more than one iterator at a time ! i2 = iter(vim.buffers) ! cb.append('i2:' + str(next(i2))) ! cb.append('i:' + str(next(i))) ! # The following should trigger GC and not cause any problems ! del i ! del i2 ! i3 = iter(vim.buffers) ! cb.append('i3:' + str(next(i3))) ! del i3 ! ! prevnum = 0 ! for b in vim.buffers: ! # Check buffer order ! if prevnum >= b.number: ! cb.append('!!! Buffer numbers not in strictly ascending order') ! # Check indexing: vim.buffers[number].number == number ! cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b)) ! prevnum = b.number ! del prevnum ! ! cb.append(str(len(vim.buffers))) ! ! bnums = list(map(lambda b: b.number, vim.buffers))[1:] ! ! # Test wiping out buffer with existing iterator ! i4 = iter(vim.buffers) ! cb.append('i4:' + str(next(i4))) ! vim.command('bwipeout! ' + str(bnums.pop(0))) ! try: ! next(i4) ! except vim.error: ! pass ! else: ! cb.append('!!!! No vim.error') ! i4 = iter(vim.buffers) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! vim.command('bwipeout! ' + str(bnums.pop(-1))) ! cb.append('i4:' + str(next(i4))) ! try: ! next(i4) ! except StopIteration: ! cb.append('StopIteration') ! del i4 ! del bnums EOF :" :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects *************** *** 764,890 **** :vnew a.2 :vnew b.2 :vnew c.2 ! py3 << EOF ! cb.append('Number of tabs: ' + str(len(vim.tabpages))) ! cb.append('Current tab pages:') ! ! def W(w): ! if '(unknown)' in repr(w): ! return '' ! else: ! return repr(w) ! ! def Cursor(w, start=len(cb)): ! if w.buffer is cb: ! return repr((start - w.cursor[0], w.cursor[1])) ! else: ! return repr(w.cursor) ! ! for t in vim.tabpages: ! cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) ! cb.append(' Windows:') ! for w in t.windows: ! cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) ! # Other values depend on the size of the terminal, so they are checked partly: ! for attr in ('height', 'row', 'width', 'col'): ! try: ! aval = getattr(w, attr) ! if type(aval) is not int: ! raise TypeError ! if aval < 0: ! raise ValueError ! except Exception as e: ! cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__) ! del aval ! del attr ! w.cursor = (len(w.buffer), 0) ! del W ! del Cursor ! cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) ! if list(vim.windows) != list(vim.current.tabpage.windows): ! cb.append('!!!!!! Windows differ') EOF :" :" Test vim.current ! py3 << EOF ! def H(o): ! return repr(o) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) ! 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)) ! del H ! # Assigning: fails ! try: ! vim.current.window = vim.tabpages[0].window ! except ValueError: ! cb.append('ValueError at assigning foreign tab window') ! ! for attr in ('window', 'tabpage', 'buffer'): ! try: ! setattr(vim.current, attr, None) ! except TypeError: ! cb.append('Type error at assigning None to vim.current.' + attr) ! del attr ! ! # Assigning: success ! vim.current.tabpage = vim.tabpages[-2] ! vim.current.buffer = cb ! vim.current.window = vim.windows[0] ! vim.current.window.cursor = (len(vim.current.buffer), 0) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window)) ! cb.append('Current buffer: ' + repr(vim.current.buffer)) ! cb.append('Current line: ' + repr(vim.current.line)) ! ws = list(vim.windows) ! ts = list(vim.tabpages) ! for b in vim.buffers: ! if b is not cb: ! vim.command('bwipeout! ' + str(b.number)) ! del b ! cb.append('w.valid: ' + repr([w.valid for w in ws])) ! cb.append('t.valid: ' + repr([t.valid for t in ts])) ! del w ! del t ! del ts ! del ws EOF :tabonly! :only! :" :" Test types ! py3 << EOF ! for expr, attr in ( ! ('vim.vars', 'Dictionary'), ! ('vim.options', 'Options'), ! ('vim.bindeval("{}")', 'Dictionary'), ! ('vim.bindeval("[]")', 'List'), ! ('vim.bindeval("function(\'tr\')")', 'Function'), ! ('vim.current.buffer', 'Buffer'), ! ('vim.current.range', 'Range'), ! ('vim.current.window', 'Window'), ! ('vim.current.tabpage', 'TabPage'), ! ): ! cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) ! del expr ! del attr EOF :" :" Test __dir__() method ! py3 << EOF ! for name, o in ( ! ('current', vim.current), ! ('buffer', vim.current.buffer), ! ('window', vim.current.window), ! ('tabpage', vim.current.tabpage), ! ('range', vim.current.range), ! ('dictionary', vim.bindeval('{}')), ! ('list', vim.bindeval('[]')), ! ('function', vim.bindeval('function("tr")')), ! ('output', sys.stdout), ! ): ! cb.append(name + ':' + ','.join(dir(o))) ! del name ! del o EOF :" :" Test vim.*.__new__ --- 764,890 ---- :vnew a.2 :vnew b.2 :vnew c.2 ! py3 << trim EOF ! cb.append('Number of tabs: ' + str(len(vim.tabpages))) ! cb.append('Current tab pages:') ! ! def W(w): ! if '(unknown)' in repr(w): ! return '' ! else: ! return repr(w) ! ! def Cursor(w, start=len(cb)): ! if w.buffer is cb: ! return repr((start - w.cursor[0], w.cursor[1])) ! else: ! return repr(w.cursor) ! ! for t in vim.tabpages: ! cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window)) ! cb.append(' Windows:') ! for w in t.windows: ! cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w)) ! # Other values depend on the size of the terminal, so they are checked partly: ! for attr in ('height', 'row', 'width', 'col'): ! try: ! aval = getattr(w, attr) ! if type(aval) is not int: ! raise TypeError ! if aval < 0: ! raise ValueError ! except Exception as e: ! cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__) ! del aval ! del attr ! w.cursor = (len(w.buffer), 0) ! del W ! del Cursor ! cb.append('Number of windows in current tab page: ' + str(len(vim.windows))) ! if list(vim.windows) != list(vim.current.tabpage.windows): ! cb.append('!!!!!! Windows differ') EOF :" :" Test vim.current ! py3 << trim EOF ! def H(o): ! return repr(o) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window)) ! 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)) ! del H ! # Assigning: fails ! try: ! vim.current.window = vim.tabpages[0].window ! except ValueError: ! cb.append('ValueError at assigning foreign tab window') ! ! for attr in ('window', 'tabpage', 'buffer'): ! try: ! setattr(vim.current, attr, None) ! except TypeError: ! cb.append('Type error at assigning None to vim.current.' + attr) ! del attr ! ! # Assigning: success ! vim.current.tabpage = vim.tabpages[-2] ! vim.current.buffer = cb ! vim.current.window = vim.windows[0] ! vim.current.window.cursor = (len(vim.current.buffer), 0) ! cb.append('Current tab page: ' + repr(vim.current.tabpage)) ! cb.append('Current window: ' + repr(vim.current.window)) ! cb.append('Current buffer: ' + repr(vim.current.buffer)) ! cb.append('Current line: ' + repr(vim.current.line)) ! ws = list(vim.windows) ! ts = list(vim.tabpages) ! for b in vim.buffers: ! if b is not cb: ! vim.command('bwipeout! ' + str(b.number)) ! del b ! cb.append('w.valid: ' + repr([w.valid for w in ws])) ! cb.append('t.valid: ' + repr([t.valid for t in ts])) ! del w ! del t ! del ts ! del ws EOF :tabonly! :only! :" :" Test types ! py3 << trim EOF ! for expr, attr in ( ! ('vim.vars', 'Dictionary'), ! ('vim.options', 'Options'), ! ('vim.bindeval("{}")', 'Dictionary'), ! ('vim.bindeval("[]")', 'List'), ! ('vim.bindeval("function(\'tr\')")', 'Function'), ! ('vim.current.buffer', 'Buffer'), ! ('vim.current.range', 'Range'), ! ('vim.current.window', 'Window'), ! ('vim.current.tabpage', 'TabPage'), ! ): ! cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr))) ! del expr ! del attr EOF :" :" Test __dir__() method ! py3 << trim EOF ! for name, o in ( ! ('current', vim.current), ! ('buffer', vim.current.buffer), ! ('window', vim.current.window), ! ('tabpage', vim.current.tabpage), ! ('range', vim.current.range), ! ('dictionary', vim.bindeval('{}')), ! ('list', vim.bindeval('[]')), ! ('function', vim.bindeval('function("tr")')), ! ('output', sys.stdout), ! ): ! cb.append(name + ':' + ','.join(dir(o))) ! del name ! del o EOF :" :" Test vim.*.__new__ *************** *** 917,979 **** :py3 Pt = vim.bindeval('Pt') :unlet Pt :py3 del Pt ! py3 << EOF ! def ecall(out_prefix, func, *args, **kwargs): ! line = out_prefix + ': ' ! try: ! ret = func(*args, **kwargs) ! except Exception: ! line += '!exception: ' + emsg(sys.exc_info()) ! else: ! line += '!result: ' + str(vim.Function('string')(ret), 'utf-8') ! cb.append(line) ! a = vim.Function('Args') ! pa1 = vim.Function('Args', args=['abcArgsPA1']) ! pa2 = vim.Function('Args', args=[]) ! pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) ! pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) ! cb.append('a: ' + repr(a)) ! cb.append('pa1: ' + repr(pa1)) ! cb.append('pa2: ' + repr(pa2)) ! cb.append('pa3: ' + repr(pa3)) ! cb.append('pa4: ' + repr(pa4)) ! sa = vim.Function('SelfArgs') ! psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) ! psa2 = vim.Function('SelfArgs', args=[]) ! psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) ! psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) ! psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) ! psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) ! psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) ! psa8 = vim.Function('SelfArgs', auto_rebind=False) ! psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) ! psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) ! psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) ! psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) ! cb.append('sa: ' + repr(sa)) ! cb.append('psa1: ' + repr(psa1)) ! cb.append('psa2: ' + repr(psa2)) ! cb.append('psa3: ' + repr(psa3)) ! cb.append('psa4: ' + repr(psa4)) ! cb.append('psa5: ' + repr(psa5)) ! cb.append('psa6: ' + repr(psa6)) ! cb.append('psa7: ' + repr(psa7)) ! cb.append('psa8: ' + repr(psa8)) ! cb.append('psa9: ' + repr(psa9)) ! cb.append('psaA: ' + repr(psaA)) ! cb.append('psaB: ' + repr(psaB)) ! cb.append('psaC: ' + repr(psaC)) ! ! psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) ! psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] ! psar.self['rec'] = psar ! psar.self['self'] = psar.self ! psar.self['args'] = psar.args ! ! try: ! cb.append('psar: ' + repr(psar)) ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) EOF :$put ='s(a): '.string(py3eval('a')) :$put ='s(pa1): '.string(py3eval('pa1')) --- 917,979 ---- :py3 Pt = vim.bindeval('Pt') :unlet Pt :py3 del Pt ! py3 << trim EOF ! def ecall(out_prefix, func, *args, **kwargs): ! line = out_prefix + ': ' ! try: ! ret = func(*args, **kwargs) ! except Exception: ! line += '!exception: ' + emsg(sys.exc_info()) ! else: ! line += '!result: ' + str(vim.Function('string')(ret), 'utf-8') ! cb.append(line) ! a = vim.Function('Args') ! pa1 = vim.Function('Args', args=['abcArgsPA1']) ! pa2 = vim.Function('Args', args=[]) ! pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) ! pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) ! cb.append('a: ' + repr(a)) ! cb.append('pa1: ' + repr(pa1)) ! cb.append('pa2: ' + repr(pa2)) ! cb.append('pa3: ' + repr(pa3)) ! cb.append('pa4: ' + repr(pa4)) ! sa = vim.Function('SelfArgs') ! psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) ! psa2 = vim.Function('SelfArgs', args=[]) ! psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) ! psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) ! psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) ! psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) ! psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) ! psa8 = vim.Function('SelfArgs', auto_rebind=False) ! psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) ! psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) ! psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) ! psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) ! cb.append('sa: ' + repr(sa)) ! cb.append('psa1: ' + repr(psa1)) ! cb.append('psa2: ' + repr(psa2)) ! cb.append('psa3: ' + repr(psa3)) ! cb.append('psa4: ' + repr(psa4)) ! cb.append('psa5: ' + repr(psa5)) ! cb.append('psa6: ' + repr(psa6)) ! cb.append('psa7: ' + repr(psa7)) ! cb.append('psa8: ' + repr(psa8)) ! cb.append('psa9: ' + repr(psa9)) ! cb.append('psaA: ' + repr(psaA)) ! cb.append('psaB: ' + repr(psaB)) ! cb.append('psaC: ' + repr(psaC)) ! ! psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) ! psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] ! psar.self['rec'] = psar ! psar.self['self'] = psar.self ! psar.self['args'] = psar.args ! ! try: ! cb.append('psar: ' + repr(psar)) ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) EOF :$put ='s(a): '.string(py3eval('a')) :$put ='s(pa1): '.string(py3eval('pa1')) *************** *** 1042,1129 **** :py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) :py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) :py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) ! py3 << EOF ! def s(v): ! if v is None: ! return repr(v) ! else: ! return str(vim.Function('string')(v), 'utf-8') ! ! cb.append('a.args: ' + s(a.args)) ! cb.append('pa1.args: ' + s(pa1.args)) ! cb.append('pa2.args: ' + s(pa2.args)) ! cb.append('pa3.args: ' + s(pa3.args)) ! cb.append('pa4.args: ' + s(pa4.args)) ! cb.append('sa.args: ' + s(sa.args)) ! cb.append('psa1.args: ' + s(psa1.args)) ! cb.append('psa2.args: ' + s(psa2.args)) ! cb.append('psa3.args: ' + s(psa3.args)) ! cb.append('psa4.args: ' + s(psa4.args)) ! ! cb.append('a.self: ' + s(a.self)) ! cb.append('pa1.self: ' + s(pa1.self)) ! cb.append('pa2.self: ' + s(pa2.self)) ! cb.append('pa3.self: ' + s(pa3.self)) ! cb.append('pa4.self: ' + s(pa4.self)) ! cb.append('sa.self: ' + s(sa.self)) ! cb.append('psa1.self: ' + s(psa1.self)) ! cb.append('psa2.self: ' + s(psa2.self)) ! cb.append('psa3.self: ' + s(psa3.self)) ! cb.append('psa4.self: ' + s(psa4.self)) ! ! cb.append('a.name: ' + s(a.name)) ! cb.append('pa1.name: ' + s(pa1.name)) ! cb.append('pa2.name: ' + s(pa2.name)) ! cb.append('pa3.name: ' + s(pa3.name)) ! cb.append('pa4.name: ' + s(pa4.name)) ! cb.append('sa.name: ' + s(sa.name)) ! cb.append('psa1.name: ' + s(psa1.name)) ! cb.append('psa2.name: ' + s(psa2.name)) ! cb.append('psa3.name: ' + s(psa3.name)) ! cb.append('psa4.name: ' + s(psa4.name)) ! ! cb.append('a.auto_rebind: ' + s(a.auto_rebind)) ! cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) ! cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) ! cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) ! cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) ! cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) ! cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) ! cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) ! cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) ! cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) ! cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) ! cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) ! cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) ! cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) ! cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) ! cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) ! cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) ! cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) ! ! del s ! ! del a ! del pa1 ! del pa2 ! del pa3 ! del pa4 ! del sa ! del psa1 ! del psa2 ! del psa3 ! del psa4 ! del psa5 ! del psa6 ! del psa7 ! del psa8 ! del psa9 ! del psaA ! del psaB ! del psaC ! del psar ! del ecall EOF :" :" Test stdout/stderr --- 1042,1129 ---- :py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) :py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) :py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) ! py3 << trim EOF ! def s(v): ! if v is None: ! return repr(v) ! else: ! return str(vim.Function('string')(v), 'utf-8') ! ! cb.append('a.args: ' + s(a.args)) ! cb.append('pa1.args: ' + s(pa1.args)) ! cb.append('pa2.args: ' + s(pa2.args)) ! cb.append('pa3.args: ' + s(pa3.args)) ! cb.append('pa4.args: ' + s(pa4.args)) ! cb.append('sa.args: ' + s(sa.args)) ! cb.append('psa1.args: ' + s(psa1.args)) ! cb.append('psa2.args: ' + s(psa2.args)) ! cb.append('psa3.args: ' + s(psa3.args)) ! cb.append('psa4.args: ' + s(psa4.args)) ! ! cb.append('a.self: ' + s(a.self)) ! cb.append('pa1.self: ' + s(pa1.self)) ! cb.append('pa2.self: ' + s(pa2.self)) ! cb.append('pa3.self: ' + s(pa3.self)) ! cb.append('pa4.self: ' + s(pa4.self)) ! cb.append('sa.self: ' + s(sa.self)) ! cb.append('psa1.self: ' + s(psa1.self)) ! cb.append('psa2.self: ' + s(psa2.self)) ! cb.append('psa3.self: ' + s(psa3.self)) ! cb.append('psa4.self: ' + s(psa4.self)) ! ! cb.append('a.name: ' + s(a.name)) ! cb.append('pa1.name: ' + s(pa1.name)) ! cb.append('pa2.name: ' + s(pa2.name)) ! cb.append('pa3.name: ' + s(pa3.name)) ! cb.append('pa4.name: ' + s(pa4.name)) ! cb.append('sa.name: ' + s(sa.name)) ! cb.append('psa1.name: ' + s(psa1.name)) ! cb.append('psa2.name: ' + s(psa2.name)) ! cb.append('psa3.name: ' + s(psa3.name)) ! cb.append('psa4.name: ' + s(psa4.name)) ! ! cb.append('a.auto_rebind: ' + s(a.auto_rebind)) ! cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) ! cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) ! cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) ! cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) ! cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) ! cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) ! cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) ! cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) ! cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) ! cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) ! cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) ! cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) ! cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) ! cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) ! cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) ! cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) ! cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) ! ! del s ! ! del a ! del pa1 ! del pa2 ! del pa3 ! del pa4 ! del sa ! del psa1 ! del psa2 ! del psa3 ! del psa4 ! del psa5 ! del psa6 ! del psa7 ! del psa8 ! del psa9 ! del psaA ! del psaB ! del psaC ! del psar ! del ecall EOF :" :" Test stdout/stderr *************** *** 1139,1165 **** : $put =string(a:000) : return a:000 :endfun ! py3 << EOF ! class DupDict(vim.Dictionary): ! def __setitem__(self, key, value): ! super(DupDict, self).__setitem__(key, value) ! super(DupDict, self).__setitem__('dup_' + key, value) ! dd = DupDict() ! dd['a'] = 'b' ! ! class DupList(vim.List): ! def __getitem__(self, idx): ! return [super(DupList, self).__getitem__(idx)] * 2 ! ! dl = DupList() ! dl2 = DupList(iter('abcC')) ! dl.extend(dl2[0]) ! ! class DupFun(vim.Function): ! def __call__(self, arg): ! return super(DupFun, self).__call__(arg, arg) ! df = DupFun('Put') EOF :$put =string(sort(keys(py3eval('dd')))) :$put =string(py3eval('dl')) --- 1139,1165 ---- : $put =string(a:000) : return a:000 :endfun ! py3 << trim EOF ! class DupDict(vim.Dictionary): ! def __setitem__(self, key, value): ! super(DupDict, self).__setitem__(key, value) ! super(DupDict, self).__setitem__('dup_' + key, value) ! dd = DupDict() ! dd['a'] = 'b' ! ! class DupList(vim.List): ! def __getitem__(self, idx): ! return [super(DupList, self).__getitem__(idx)] * 2 ! ! dl = DupList() ! dl2 = DupList(iter('abcC')) ! dl.extend(dl2[0]) ! ! class DupFun(vim.Function): ! def __call__(self, arg): ! return super(DupFun, self).__call__(arg, arg) ! df = DupFun('Put') EOF :$put =string(sort(keys(py3eval('dd')))) :$put =string(py3eval('dl')) *************** *** 1169,1208 **** :$put =string(py3eval('dd') is# py3eval('dd')) :$put =string(py3eval('df')) :delfunction Put ! py3 << EOF ! del DupDict ! del DupList ! del DupFun ! del dd ! del dl ! del dl2 ! del df EOF :" :" Test chdir ! py3 << EOF ! import os ! fnamemodify = vim.Function('fnamemodify') ! cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')) ! os.chdir('..') ! path = fnamemodify('.', ':p:h:t') ! if path != b'src': ! # Running tests from a shadow directory, so move up another level ! # This will result in @% looking like shadow/testdir/test87.in, hence the ! # slicing to remove the leading path and path separator ! os.chdir('..') cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/')) ! os.chdir(path) ! else: cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%').replace(os.path.sep, '/')) ! del path ! os.chdir('testdir') ! cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')) ! del fnamemodify EOF :" :" Test errors --- 1169,1208 ---- :$put =string(py3eval('dd') is# py3eval('dd')) :$put =string(py3eval('df')) :delfunction Put ! py3 << trim EOF ! del DupDict ! del DupList ! del DupFun ! del dd ! del dl ! del dl2 ! del df EOF :" :" Test chdir ! py3 << trim EOF ! import os ! fnamemodify = vim.Function('fnamemodify') cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')) ! os.chdir('..') ! path = fnamemodify('.', ':p:h:t') ! if path != b'src': ! # Running tests from a shadow directory, so move up another level ! # This will result in @% looking like shadow/testdir/test87.in, hence the ! # slicing to remove the leading path and path separator ! os.chdir('..') ! cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')[len(path)+1:].replace(os.path.sep, '/')) ! os.chdir(path) ! else: ! cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%').replace(os.path.sep, '/')) ! del path ! os.chdir('testdir') cb.append(str(fnamemodify('.', ':p:h:t'))) ! cb.append(vim.eval('@%')) ! del fnamemodify EOF :" :" Test errors *************** *** 1210,1673 **** :endfun :fun D() :endfun ! py3 << EOF ! d = vim.Dictionary() ! ned = vim.Dictionary(foo='bar', baz='abcD') ! dl = vim.Dictionary(a=1) ! dl.locked = True ! l = vim.List() ! ll = vim.List('abcE') ! ll.locked = True ! nel = vim.List('abcO') ! f = vim.Function('string') ! fd = vim.Function('F') ! fdel = vim.Function('D') ! vim.command('delfunction D') ! ! def subexpr_test(expr, name, subexprs): ! cb.append('>>> Testing %s using %s' % (name, expr)) ! for subexpr in subexprs: ! ee(expr % subexpr) ! cb.append('<<< Finished') ! ! def stringtochars_test(expr): ! return subexpr_test(expr, 'StringToChars', ( ! '1', # Fail type checks ! 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check ! '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check ! )) ! ! class Mapping(object): ! def __init__(self, d): ! self.d = d ! ! def __getitem__(self, key): ! return self.d[key] ! ! def keys(self): ! return self.d.keys() ! ! def items(self): ! return self.d.items() ! ! def convertfrompyobject_test(expr, recurse=True): ! # pydict_to_tv ! stringtochars_test(expr % '{%s : 1}') ! if recurse: ! convertfrompyobject_test(expr % '{"abcF" : %s}', False) ! # pymap_to_tv ! stringtochars_test(expr % 'Mapping({%s : 1})') ! if recurse: ! convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) ! # pyseq_to_tv ! iter_test(expr) ! return subexpr_test(expr, 'ConvertFromPyObject', ( ! 'None', # Not conversible ! '{b"": 1}', # Empty key not allowed ! '{"": 1}', # Same, but with unicode object ! 'FailingMapping()', # ! 'FailingMappingKey()', # ! 'FailingNumber()', # ! )) ! ! def convertfrompymapping_test(expr): ! convertfrompyobject_test(expr) ! return subexpr_test(expr, 'ConvertFromPyMapping', ( ! '[]', ! )) ! ! def iter_test(expr): ! return subexpr_test(expr, '*Iter*', ( ! 'FailingIter()', ! 'FailingIterNext()', ! )) ! ! def number_test(expr, natural=False, unsigned=False): ! if natural: ! unsigned = True ! return subexpr_test(expr, 'NumberToLong', ( ! '[]', ! 'None', ! ) + (('-1',) if unsigned else ()) ! + (('0',) if natural else ())) ! ! class FailingTrue(object): ! def __bool__(self): ! raise NotImplementedError('bool') ! ! class FailingIter(object): ! def __iter__(self): ! raise NotImplementedError('iter') ! ! class FailingIterNext(object): ! def __iter__(self): ! return self ! ! def __next__(self): ! raise NotImplementedError('next') ! ! class FailingIterNextN(object): ! def __init__(self, n): ! self.n = n ! ! def __iter__(self): ! return self ! ! def __next__(self): ! if self.n: ! self.n -= 1 ! return 1 ! else: ! raise NotImplementedError('next N') ! ! class FailingMappingKey(object): ! def __getitem__(self, item): ! raise NotImplementedError('getitem:mappingkey') ! ! def keys(self): ! return list("abcH") ! ! class FailingMapping(object): ! def __getitem__(self): ! raise NotImplementedError('getitem:mapping') ! ! def keys(self): ! raise NotImplementedError('keys') ! ! class FailingList(list): ! def __getitem__(self, idx): ! if i == 2: ! raise NotImplementedError('getitem:list') ! else: ! return super(FailingList, self).__getitem__(idx) ! ! class NoArgsCall(object): ! def __call__(self): ! pass ! ! class FailingCall(object): ! def __call__(self, path): ! raise NotImplementedError('call') ! ! class FailingNumber(object): ! def __int__(self): ! raise NotImplementedError('int') ! ! cb.append("> Output") ! cb.append(">> OutputSetattr") ! ee('del sys.stdout.softspace') ! number_test('sys.stdout.softspace = %s', unsigned=True) ! number_test('sys.stderr.softspace = %s', unsigned=True) ! ee('assert sys.stdout.isatty()==False') ! ee('assert sys.stdout.seekable()==False') ! ee('sys.stdout.close()') ! ee('sys.stdout.flush()') ! ee('assert sys.stderr.isatty()==False') ! ee('assert sys.stderr.seekable()==False') ! ee('sys.stderr.close()') ! ee('sys.stderr.flush()') ! ee('sys.stdout.attr = None') ! cb.append(">> OutputWrite") ! ee('assert sys.stdout.writable()==True') ! ee('assert sys.stdout.readable()==False') ! ee('assert sys.stderr.writable()==True') ! ee('assert sys.stderr.readable()==False') ! ee('assert sys.stdout.closed()==False') ! ee('assert sys.stderr.closed()==False') ! ee('assert sys.stdout.errors=="strict"') ! ee('assert sys.stderr.errors=="strict"') ! ee('assert sys.stdout.encoding==sys.stderr.encoding') ! ee('sys.stdout.write(None)') ! cb.append(">> OutputWriteLines") ! ee('sys.stdout.writelines(None)') ! ee('sys.stdout.writelines([1])') ! iter_test('sys.stdout.writelines(%s)') ! cb.append("> VimCommand") ! stringtochars_test('vim.command(%s)') ! ee('vim.command("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimToPython") ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEval") ! stringtochars_test('vim.eval(%s)') ! ee('vim.eval("", FailingTrue())') ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEvalPy") ! stringtochars_test('vim.bindeval(%s)') ! ee('vim.eval("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimStrwidth") ! stringtochars_test('vim.strwidth(%s)') ! cb.append("> VimForeachRTP") ! ee('vim.foreach_rtp(None)') ! ee('vim.foreach_rtp(NoArgsCall())') ! ee('vim.foreach_rtp(FailingCall())') ! ee('vim.foreach_rtp(int, 2)') ! cb.append('> import') ! old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ! ee('import xxx_no_such_module_xxx') ! ee('import failing_import') ! ee('import failing') ! vim.options['rtp'] = old_rtp ! del old_rtp ! cb.append("> Options") ! cb.append(">> OptionsItem") ! ee('vim.options["abcQ"]') ! ee('vim.options[""]') ! stringtochars_test('vim.options[%s]') ! cb.append(">> OptionsContains") ! stringtochars_test('%s in vim.options') ! cb.append("> Dictionary") ! cb.append(">> DictionaryConstructor") ! ee('vim.Dictionary("abcI")') ! ##! Not checked: py_dict_alloc failure ! cb.append(">> DictionarySetattr") ! ee('del d.locked') ! ee('d.locked = FailingTrue()') ! ee('vim.vvars.locked = False') ! ee('d.scope = True') ! ee('d.xxx = True') ! cb.append(">> _DictionaryItem") ! ee('d.get("a", 2, 3)') ! stringtochars_test('d.get(%s)') ! ee('d.pop("a")') ! ee('dl.pop("a")') ! cb.append(">> DictionaryContains") ! ee('"" in d') ! ee('0 in d') ! cb.append(">> DictionaryIterNext") ! ee('for i in ned: ned["a"] = 1') ! del i ! cb.append(">> DictionaryAssItem") ! ee('dl["b"] = 1') ! stringtochars_test('d[%s] = 1') ! convertfrompyobject_test('d["a"] = %s') ! cb.append(">> DictionaryUpdate") ! cb.append(">>> kwargs") ! cb.append(">>> iter") ! ee('d.update(FailingMapping())') ! ee('d.update([FailingIterNext()])') ! ee('d.update([FailingIterNextN(1)])') ! iter_test('d.update(%s)') ! convertfrompyobject_test('d.update(%s)') ! stringtochars_test('d.update(((%s, 0),))') ! convertfrompyobject_test('d.update((("a", %s),))') ! cb.append(">> DictionaryPopItem") ! ee('d.popitem(1, 2)') ! cb.append(">> DictionaryHasKey") ! ee('d.has_key()') ! cb.append("> List") ! cb.append(">> ListConstructor") ! ee('vim.List(1, 2)') ! ee('vim.List(a=1)') ! iter_test('vim.List(%s)') ! convertfrompyobject_test('vim.List([%s])') ! cb.append(">> ListItem") ! ee('l[1000]') ! cb.append(">> ListAssItem") ! ee('ll[1] = 2') ! ee('l[1000] = 3') ! cb.append(">> ListAssSlice") ! ee('ll[1:100] = "abcJ"') ! iter_test('l[:] = %s') ! ee('nel[1:10:2] = "abcK"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:10:2] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:1:-1] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[:] = FailingIterNextN(2)') ! cb.append(repr(tuple(nel))) ! convertfrompyobject_test('l[:] = [%s]') ! cb.append(">> ListConcatInPlace") ! iter_test('l.extend(%s)') ! convertfrompyobject_test('l.extend([%s])') ! cb.append(">> ListSetattr") ! ee('del l.locked') ! ee('l.locked = FailingTrue()') ! ee('l.xxx = True') ! cb.append("> Function") ! cb.append(">> FunctionConstructor") ! cb.append(">>> FunctionConstructor") ! ee('vim.Function("123")') ! ee('vim.Function("xxx_non_existent_function_xxx")') ! ee('vim.Function("xxx#non#existent#function#xxx")') ! ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') ! ee('vim.Function("xxx_non_existent_function_xxx3", self={})') ! ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') ! cb.append(">>> FunctionNew") ! ee('vim.Function("tr", self="abcFuncSelf")') ! ee('vim.Function("tr", args=427423)') ! ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "")') ! cb.append(">> FunctionCall") ! convertfrompyobject_test('f(%s)') ! convertfrompymapping_test('fd(self=%s)') ! cb.append("> TabPage") ! cb.append(">> TabPageAttr") ! ee('vim.current.tabpage.xxx') ! cb.append("> TabList") ! cb.append(">> TabListItem") ! ee('vim.tabpages[1000]') ! cb.append("> Window") ! cb.append(">> WindowAttr") ! ee('vim.current.window.xxx') ! cb.append(">> WindowSetattr") ! ee('vim.current.window.buffer = 0') ! ee('vim.current.window.cursor = (100000000, 100000000)') ! ee('vim.current.window.cursor = True') ! number_test('vim.current.window.height = %s', unsigned=True) ! number_test('vim.current.window.width = %s', unsigned=True) ! ee('vim.current.window.xxxxxx = True') ! cb.append("> WinList") ! cb.append(">> WinListItem") ! ee('vim.windows[1000]') ! cb.append("> Buffer") ! cb.append(">> StringToLine (indirect)") ! ee('vim.current.buffer[0] = "\\na"') ! ee('vim.current.buffer[0] = b"\\na"') ! cb.append(">> SetBufferLine (indirect)") ! ee('vim.current.buffer[0] = True') ! cb.append(">> SetBufferLineList (indirect)") ! ee('vim.current.buffer[:] = True') ! ee('vim.current.buffer[:] = ["\\na", "bc"]') ! cb.append(">> InsertBufferLines (indirect)") ! ee('vim.current.buffer.append(None)') ! ee('vim.current.buffer.append(["\\na", "bc"])') ! ee('vim.current.buffer.append("\\nbc")') ! cb.append(">> RBItem") ! ee('vim.current.buffer[100000000]') ! cb.append(">> RBAsItem") ! ee('vim.current.buffer[100000000] = ""') ! cb.append(">> BufferAttr") ! ee('vim.current.buffer.xxx') ! cb.append(">> BufferSetattr") ! ee('vim.current.buffer.name = True') ! ee('vim.current.buffer.xxx = True') ! cb.append(">> BufferMark") ! ee('vim.current.buffer.mark(0)') ! ee('vim.current.buffer.mark("abcM")') ! ee('vim.current.buffer.mark("!")') ! cb.append(">> BufferRange") ! ee('vim.current.buffer.range(1, 2, 3)') ! cb.append("> BufMap") ! cb.append(">> BufMapItem") ! ee('vim.buffers[100000000]') ! number_test('vim.buffers[%s]', natural=True) ! cb.append("> Current") ! cb.append(">> CurrentGetattr") ! ee('vim.current.xxx') ! cb.append(">> CurrentSetattr") ! ee('vim.current.line = True') ! ee('vim.current.buffer = True') ! ee('vim.current.window = True') ! ee('vim.current.tabpage = True') ! ee('vim.current.xxx = True') ! del d ! del ned ! del dl ! del l ! del ll ! del nel ! del f ! del fd ! del fdel ! del subexpr_test ! del stringtochars_test ! del Mapping ! del convertfrompyobject_test ! del convertfrompymapping_test ! del iter_test ! del number_test ! del FailingTrue ! del FailingIter ! del FailingIterNext ! del FailingIterNextN ! del FailingMapping ! del FailingMappingKey ! del FailingList ! del NoArgsCall ! del FailingCall ! del FailingNumber EOF :delfunction F :" :" Test import ! py3 << EOF ! sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) ! sys.path.append(os.path.join(os.getcwd(), 'python_after')) ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ! l = [] ! def callback(path): ! l.append(os.path.relpath(path)) ! vim.foreach_rtp(callback) ! cb.append(repr(l)) ! del l ! def callback(path): ! return os.path.relpath(path) ! cb.append(repr(vim.foreach_rtp(callback))) ! del callback ! from module import dir as d ! from modulex import ddir ! cb.append(d + ',' + ddir) ! import before ! cb.append(before.dir) ! import after ! cb.append(after.dir) ! import topmodule as tm ! import topmodule.submodule as tms ! import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss ! cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) ! cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) ! cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) ! del before ! del after ! del d ! del ddir ! del tm ! del tms ! del tmsss EOF :" :" Test exceptions :fun Exe(e) : execute a:e :endfun ! py3 << EOF ! Exe = vim.bindeval('function("Exe")') ! ee('vim.command("throw \'abcN\'")') ! ee('Exe("throw \'def\'")') ! ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ! ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ! ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') ! ee('vim.eval("xxx_unknown_function_xxx()")') ! ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') ! del Exe EOF :delfunction Exe :" :" Regression: interrupting vim.command propagates to next vim.command ! py3 << EOF ! def test_keyboard_interrupt(): ! try: ! vim.command('while 1 | endwhile') ! except KeyboardInterrupt: ! cb.append('Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('!!!!!!!! No exception') ! try: ! vim.command('$ put =\'Running :put\'') ! except KeyboardInterrupt: ! cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('No exception') EOF :debuggreedy :call inputsave() --- 1210,1673 ---- :endfun :fun D() :endfun ! py3 << trim EOF ! d = vim.Dictionary() ! ned = vim.Dictionary(foo='bar', baz='abcD') ! dl = vim.Dictionary(a=1) ! dl.locked = True ! l = vim.List() ! ll = vim.List('abcE') ! ll.locked = True ! nel = vim.List('abcO') ! f = vim.Function('string') ! fd = vim.Function('F') ! fdel = vim.Function('D') ! vim.command('delfunction D') ! ! def subexpr_test(expr, name, subexprs): ! cb.append('>>> Testing %s using %s' % (name, expr)) ! for subexpr in subexprs: ! ee(expr % subexpr) ! cb.append('<<< Finished') ! ! def stringtochars_test(expr): ! return subexpr_test(expr, 'StringToChars', ( ! '1', # Fail type checks ! 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check ! '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check ! )) ! ! class Mapping(object): ! def __init__(self, d): ! self.d = d ! ! def __getitem__(self, key): ! return self.d[key] ! ! def keys(self): ! return self.d.keys() ! ! def items(self): ! return self.d.items() ! ! def convertfrompyobject_test(expr, recurse=True): ! # pydict_to_tv ! stringtochars_test(expr % '{%s : 1}') ! if recurse: ! convertfrompyobject_test(expr % '{"abcF" : %s}', False) ! # pymap_to_tv ! stringtochars_test(expr % 'Mapping({%s : 1})') ! if recurse: ! convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False) ! # pyseq_to_tv ! iter_test(expr) ! return subexpr_test(expr, 'ConvertFromPyObject', ( ! 'None', # Not conversible ! '{b"": 1}', # Empty key not allowed ! '{"": 1}', # Same, but with unicode object ! 'FailingMapping()', # ! 'FailingMappingKey()', # ! 'FailingNumber()', # ! )) ! ! def convertfrompymapping_test(expr): ! convertfrompyobject_test(expr) ! return subexpr_test(expr, 'ConvertFromPyMapping', ( ! '[]', ! )) ! ! def iter_test(expr): ! return subexpr_test(expr, '*Iter*', ( ! 'FailingIter()', ! 'FailingIterNext()', ! )) ! ! def number_test(expr, natural=False, unsigned=False): ! if natural: ! unsigned = True ! return subexpr_test(expr, 'NumberToLong', ( ! '[]', ! 'None', ! ) + (('-1',) if unsigned else ()) ! + (('0',) if natural else ())) ! ! class FailingTrue(object): ! def __bool__(self): ! raise NotImplementedError('bool') ! ! class FailingIter(object): ! def __iter__(self): ! raise NotImplementedError('iter') ! ! class FailingIterNext(object): ! def __iter__(self): ! return self ! ! def __next__(self): ! raise NotImplementedError('next') ! ! class FailingIterNextN(object): ! def __init__(self, n): ! self.n = n ! ! def __iter__(self): ! return self ! ! def __next__(self): ! if self.n: ! self.n -= 1 ! return 1 ! else: ! raise NotImplementedError('next N') ! ! class FailingMappingKey(object): ! def __getitem__(self, item): ! raise NotImplementedError('getitem:mappingkey') ! ! def keys(self): ! return list("abcH") ! ! class FailingMapping(object): ! def __getitem__(self): ! raise NotImplementedError('getitem:mapping') ! ! def keys(self): ! raise NotImplementedError('keys') ! ! class FailingList(list): ! def __getitem__(self, idx): ! if i == 2: ! raise NotImplementedError('getitem:list') ! else: ! return super(FailingList, self).__getitem__(idx) ! ! class NoArgsCall(object): ! def __call__(self): ! pass ! ! class FailingCall(object): ! def __call__(self, path): ! raise NotImplementedError('call') ! ! class FailingNumber(object): ! def __int__(self): ! raise NotImplementedError('int') ! ! cb.append("> Output") ! cb.append(">> OutputSetattr") ! ee('del sys.stdout.softspace') ! number_test('sys.stdout.softspace = %s', unsigned=True) ! number_test('sys.stderr.softspace = %s', unsigned=True) ! ee('assert sys.stdout.isatty()==False') ! ee('assert sys.stdout.seekable()==False') ! ee('sys.stdout.close()') ! ee('sys.stdout.flush()') ! ee('assert sys.stderr.isatty()==False') ! ee('assert sys.stderr.seekable()==False') ! ee('sys.stderr.close()') ! ee('sys.stderr.flush()') ! ee('sys.stdout.attr = None') ! cb.append(">> OutputWrite") ! ee('assert sys.stdout.writable()==True') ! ee('assert sys.stdout.readable()==False') ! ee('assert sys.stderr.writable()==True') ! ee('assert sys.stderr.readable()==False') ! ee('assert sys.stdout.closed()==False') ! ee('assert sys.stderr.closed()==False') ! ee('assert sys.stdout.errors=="strict"') ! ee('assert sys.stderr.errors=="strict"') ! ee('assert sys.stdout.encoding==sys.stderr.encoding') ! ee('sys.stdout.write(None)') ! cb.append(">> OutputWriteLines") ! ee('sys.stdout.writelines(None)') ! ee('sys.stdout.writelines([1])') ! iter_test('sys.stdout.writelines(%s)') ! cb.append("> VimCommand") ! stringtochars_test('vim.command(%s)') ! ee('vim.command("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimToPython") ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEval") ! stringtochars_test('vim.eval(%s)') ! ee('vim.eval("", FailingTrue())') ! #! Not checked: everything: needs errors in internal python functions ! cb.append("> VimEvalPy") ! stringtochars_test('vim.bindeval(%s)') ! ee('vim.eval("", 2)') ! #! Not checked: vim->python exceptions translating: checked later ! cb.append("> VimStrwidth") ! stringtochars_test('vim.strwidth(%s)') ! cb.append("> VimForeachRTP") ! ee('vim.foreach_rtp(None)') ! ee('vim.foreach_rtp(NoArgsCall())') ! ee('vim.foreach_rtp(FailingCall())') ! ee('vim.foreach_rtp(int, 2)') ! cb.append('> import') ! old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ! ee('import xxx_no_such_module_xxx') ! ee('import failing_import') ! ee('import failing') ! vim.options['rtp'] = old_rtp ! del old_rtp ! cb.append("> Options") ! cb.append(">> OptionsItem") ! ee('vim.options["abcQ"]') ! ee('vim.options[""]') ! stringtochars_test('vim.options[%s]') ! cb.append(">> OptionsContains") ! stringtochars_test('%s in vim.options') ! cb.append("> Dictionary") ! cb.append(">> DictionaryConstructor") ! ee('vim.Dictionary("abcI")') ! ##! Not checked: py_dict_alloc failure ! cb.append(">> DictionarySetattr") ! ee('del d.locked') ! ee('d.locked = FailingTrue()') ! ee('vim.vvars.locked = False') ! ee('d.scope = True') ! ee('d.xxx = True') ! cb.append(">> _DictionaryItem") ! ee('d.get("a", 2, 3)') ! stringtochars_test('d.get(%s)') ! ee('d.pop("a")') ! ee('dl.pop("a")') ! cb.append(">> DictionaryContains") ! ee('"" in d') ! ee('0 in d') ! cb.append(">> DictionaryIterNext") ! ee('for i in ned: ned["a"] = 1') ! del i ! cb.append(">> DictionaryAssItem") ! ee('dl["b"] = 1') ! stringtochars_test('d[%s] = 1') ! convertfrompyobject_test('d["a"] = %s') ! cb.append(">> DictionaryUpdate") ! cb.append(">>> kwargs") ! cb.append(">>> iter") ! ee('d.update(FailingMapping())') ! ee('d.update([FailingIterNext()])') ! ee('d.update([FailingIterNextN(1)])') ! iter_test('d.update(%s)') ! convertfrompyobject_test('d.update(%s)') ! stringtochars_test('d.update(((%s, 0),))') ! convertfrompyobject_test('d.update((("a", %s),))') ! cb.append(">> DictionaryPopItem") ! ee('d.popitem(1, 2)') ! cb.append(">> DictionaryHasKey") ! ee('d.has_key()') ! cb.append("> List") ! cb.append(">> ListConstructor") ! ee('vim.List(1, 2)') ! ee('vim.List(a=1)') ! iter_test('vim.List(%s)') ! convertfrompyobject_test('vim.List([%s])') ! cb.append(">> ListItem") ! ee('l[1000]') ! cb.append(">> ListAssItem") ! ee('ll[1] = 2') ! ee('l[1000] = 3') ! cb.append(">> ListAssSlice") ! ee('ll[1:100] = "abcJ"') ! iter_test('l[:] = %s') ! ee('nel[1:10:2] = "abcK"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:10:2] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[1:1:-1] = "a"') ! cb.append(repr(tuple(nel))) ! ee('nel[:] = FailingIterNextN(2)') ! cb.append(repr(tuple(nel))) ! convertfrompyobject_test('l[:] = [%s]') ! cb.append(">> ListConcatInPlace") ! iter_test('l.extend(%s)') ! convertfrompyobject_test('l.extend([%s])') ! cb.append(">> ListSetattr") ! ee('del l.locked') ! ee('l.locked = FailingTrue()') ! ee('l.xxx = True') ! cb.append("> Function") ! cb.append(">> FunctionConstructor") ! cb.append(">>> FunctionConstructor") ! ee('vim.Function("123")') ! ee('vim.Function("xxx_non_existent_function_xxx")') ! ee('vim.Function("xxx#non#existent#function#xxx")') ! ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') ! ee('vim.Function("xxx_non_existent_function_xxx3", self={})') ! ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') ! cb.append(">>> FunctionNew") ! ee('vim.Function("tr", self="abcFuncSelf")') ! ee('vim.Function("tr", args=427423)') ! ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') ! ee('vim.Function("tr", "")') ! cb.append(">> FunctionCall") ! convertfrompyobject_test('f(%s)') ! convertfrompymapping_test('fd(self=%s)') ! cb.append("> TabPage") ! cb.append(">> TabPageAttr") ! ee('vim.current.tabpage.xxx') ! cb.append("> TabList") ! cb.append(">> TabListItem") ! ee('vim.tabpages[1000]') ! cb.append("> Window") ! cb.append(">> WindowAttr") ! ee('vim.current.window.xxx') ! cb.append(">> WindowSetattr") ! ee('vim.current.window.buffer = 0') ! ee('vim.current.window.cursor = (100000000, 100000000)') ! ee('vim.current.window.cursor = True') ! number_test('vim.current.window.height = %s', unsigned=True) ! number_test('vim.current.window.width = %s', unsigned=True) ! ee('vim.current.window.xxxxxx = True') ! cb.append("> WinList") ! cb.append(">> WinListItem") ! ee('vim.windows[1000]') ! cb.append("> Buffer") ! cb.append(">> StringToLine (indirect)") ! ee('vim.current.buffer[0] = "\\na"') ! ee('vim.current.buffer[0] = b"\\na"') ! cb.append(">> SetBufferLine (indirect)") ! ee('vim.current.buffer[0] = True') ! cb.append(">> SetBufferLineList (indirect)") ! ee('vim.current.buffer[:] = True') ! ee('vim.current.buffer[:] = ["\\na", "bc"]') ! cb.append(">> InsertBufferLines (indirect)") ! ee('vim.current.buffer.append(None)') ! ee('vim.current.buffer.append(["\\na", "bc"])') ! ee('vim.current.buffer.append("\\nbc")') ! cb.append(">> RBItem") ! ee('vim.current.buffer[100000000]') ! cb.append(">> RBAsItem") ! ee('vim.current.buffer[100000000] = ""') ! cb.append(">> BufferAttr") ! ee('vim.current.buffer.xxx') ! cb.append(">> BufferSetattr") ! ee('vim.current.buffer.name = True') ! ee('vim.current.buffer.xxx = True') ! cb.append(">> BufferMark") ! ee('vim.current.buffer.mark(0)') ! ee('vim.current.buffer.mark("abcM")') ! ee('vim.current.buffer.mark("!")') ! cb.append(">> BufferRange") ! ee('vim.current.buffer.range(1, 2, 3)') ! cb.append("> BufMap") ! cb.append(">> BufMapItem") ! ee('vim.buffers[100000000]') ! number_test('vim.buffers[%s]', natural=True) ! cb.append("> Current") ! cb.append(">> CurrentGetattr") ! ee('vim.current.xxx') ! cb.append(">> CurrentSetattr") ! ee('vim.current.line = True') ! ee('vim.current.buffer = True') ! ee('vim.current.window = True') ! ee('vim.current.tabpage = True') ! ee('vim.current.xxx = True') ! del d ! del ned ! del dl ! del l ! del ll ! del nel ! del f ! del fd ! del fdel ! del subexpr_test ! del stringtochars_test ! del Mapping ! del convertfrompyobject_test ! del convertfrompymapping_test ! del iter_test ! del number_test ! del FailingTrue ! del FailingIter ! del FailingIterNext ! del FailingIterNextN ! del FailingMapping ! del FailingMappingKey ! del FailingList ! del NoArgsCall ! del FailingCall ! del FailingNumber EOF :delfunction F :" :" Test import ! py3 << trim EOF ! sys.path.insert(0, os.path.join(os.getcwd(), 'python_before')) ! sys.path.append(os.path.join(os.getcwd(), 'python_after')) ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ! l = [] ! def callback(path): ! l.append(os.path.relpath(path)) ! vim.foreach_rtp(callback) ! cb.append(repr(l)) ! del l ! def callback(path): ! return os.path.relpath(path) ! cb.append(repr(vim.foreach_rtp(callback))) ! del callback ! from module import dir as d ! from modulex import ddir ! cb.append(d + ',' + ddir) ! import before ! cb.append(before.dir) ! import after ! cb.append(after.dir) ! import topmodule as tm ! import topmodule.submodule as tms ! import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss ! cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):]) ! cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):]) ! cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):]) ! del before ! del after ! del d ! del ddir ! del tm ! del tms ! del tmsss EOF :" :" Test exceptions :fun Exe(e) : execute a:e :endfun ! py3 << trim EOF ! Exe = vim.bindeval('function("Exe")') ! ee('vim.command("throw \'abcN\'")') ! ee('Exe("throw \'def\'")') ! ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ! ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ! ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') ! ee('vim.eval("xxx_unknown_function_xxx()")') ! ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') ! del Exe EOF :delfunction Exe :" :" Regression: interrupting vim.command propagates to next vim.command ! py3 << trim EOF ! def test_keyboard_interrupt(): ! try: ! vim.command('while 1 | endwhile') ! except KeyboardInterrupt: ! cb.append('Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('!!!!!!!! No exception') ! try: ! vim.command('$ put =\'Running :put\'') ! except KeyboardInterrupt: ! cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) ! else: ! cb.append('No exception') EOF :debuggreedy :call inputsave() *************** *** 1682,1694 **** :py3 del test_keyboard_interrupt :" :" Cleanup ! py3 << EOF ! del cb ! del ee ! del emsg ! del sys ! del os ! del vim EOF :endfun :" --- 1682,1694 ---- :py3 del test_keyboard_interrupt :" :" Cleanup ! py3 << trim EOF ! del cb ! del ee ! del emsg ! del sys ! del os ! del vim EOF :endfun :" *** ../vim-8.2.0577/src/testdir/test_lua.vim 2020-01-30 18:24:47.001204003 +0100 --- src/testdir/test_lua.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 597,610 **** new call setline(1, ['first line', 'second line']) normal gg ! lua << EOF ! w = vim.window() ! w.line = 1 ! w.col = 5 ! EOF call assert_equal([1, 5], [line('.'), col('.')]) " Check that movement after setting cursor position keeps current column. normal j call assert_equal([2, 5], [line('.'), col('.')]) endfunc --- 597,629 ---- new call setline(1, ['first line', 'second line']) normal gg ! lua << trim EOF ! w = vim.window() ! w.line = 1 ! w.col = 5 ! EOF call assert_equal([1, 5], [line('.'), col('.')]) " Check that movement after setting cursor position keeps current column. normal j call assert_equal([2, 5], [line('.'), col('.')]) endfunc + + " Test for various heredoc syntax + func Test_lua_heredoc() + lua << END + vim.command('let s = "A"') + END + lua << + vim.command('let s ..= "B"') + . + lua << trim END + vim.command('let s ..= "C"') + END + lua << trim + vim.command('let s ..= "D"') + . + call assert_equal('ABCD', s) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_perl.vim 2019-09-04 19:46:20.000000000 +0200 --- src/testdir/test_perl.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 219,229 **** func Test_stdio() redir =>l:out ! perl <l:out ! perl << trim EOF VIM::Msg("&VIM::Msg"); print "STDOUT"; print STDERR "STDERR"; ! EOF redir END call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n")) endfunc *************** *** 290,292 **** --- 290,311 ---- normal j call assert_equal([2, 6], [line('.'), col('.')]) endfunc + + " Test for various heredoc syntax + func Test_perl_heredoc() + perl << END + VIM::DoCommand('let s = "A"') + END + perl << + VIM::DoCommand('let s ..= "B"') + . + perl << trim END + VIM::DoCommand('let s ..= "C"') + END + perl << trim + VIM::DoCommand('let s ..= "D"') + . + call assert_equal('ABCD', s) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_python2.vim 2019-12-11 20:10:03.000000000 +0100 --- src/testdir/test_python2.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 167,169 **** --- 167,188 ---- call assert_match( '^Vim(.*):RuntimeError: TEST$', v:exception ) endtry endfunc + + " Test for various heredoc syntax + func Test_python_heredoc() + python << END + s='A' + END + python << + s+='B' + . + python << trim END + s+='C' + END + python << trim + s+='D' + . + call assert_equal('ABCD', pyxeval('s')) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_python3.vim 2020-04-12 13:50:22.832171856 +0200 --- src/testdir/test_python3.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 295,303 **** " Set the global and buffer-local option values and then clear the " buffer-local option value. for opt in bopts ! py3 pyopt = vim.bindeval("opt") ! py3 vim.options[pyopt[0]] = pyopt[1] ! py3 curbuf.options[pyopt[0]] = pyopt[2] exe "call assert_equal(opt[2], &" .. opt[0] .. ")" exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")" exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")" --- 295,305 ---- " Set the global and buffer-local option values and then clear the " buffer-local option value. for opt in bopts ! py3 << trim END ! pyopt = vim.bindeval("opt") ! vim.options[pyopt[0]] = pyopt[1] ! curbuf.options[pyopt[0]] = pyopt[2] ! END exe "call assert_equal(opt[2], &" .. opt[0] .. ")" exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")" exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")" *************** *** 315,323 **** \ ['sidescrolloff', 6, 12, -1], \ ['statusline', '%<%f', '%<%F', '']] for opt in wopts ! py3 pyopt = vim.bindeval("opt") ! py3 vim.options[pyopt[0]] = pyopt[1] ! py3 curwin.options[pyopt[0]] = pyopt[2] exe "call assert_equal(opt[2], &" .. opt[0] .. ")" exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")" exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")" --- 317,327 ---- \ ['sidescrolloff', 6, 12, -1], \ ['statusline', '%<%f', '%<%F', '']] for opt in wopts ! py3 << trim ! pyopt = vim.bindeval("opt") ! vim.options[pyopt[0]] = pyopt[1] ! curwin.options[pyopt[0]] = pyopt[2] ! . exe "call assert_equal(opt[2], &" .. opt[0] .. ")" exe "call assert_equal(opt[1], &g:" .. opt[0] .. ")" exe "call assert_equal(opt[2], &l:" .. opt[0] .. ")" *************** *** 331,334 **** --- 335,355 ---- close! endfunc + " Test for various heredoc syntax + func Test_python3_heredoc() + python3 << END + s='A' + END + python3 << + s+='B' + . + python3 << trim END + s+='C' + END + python3 << trim + s+='D' + . + call assert_equal('ABCD', pyxeval('s')) + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_pyx2.vim 2019-09-04 20:03:06.000000000 +0200 --- src/testdir/test_pyx2.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 15,24 **** func Test_pyx() redir => var ! pyx << EOF ! import sys ! print(sys.version) ! EOF redir END call assert_match(s:py2pattern, split(var)[0]) endfunc --- 15,24 ---- func Test_pyx() redir => var ! pyx << trim EOF ! import sys ! print(sys.version) ! EOF redir END call assert_match(s:py2pattern, split(var)[0]) endfunc *************** *** 79,81 **** --- 79,100 ---- call assert_match( '^Vim(.*):RuntimeError: TEST$', v:exception ) endtry endfunc + + " Test for various heredoc syntaxes + func Test_pyx2_heredoc() + pyx << END + result='A' + END + pyx << + result+='B' + . + pyx << trim END + result+='C' + END + pyx << trim + result+='D' + . + call assert_equal('ABCD', pyxeval('result')) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_pyx3.vim 2019-06-15 17:39:26.000000000 +0200 --- src/testdir/test_pyx3.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 15,24 **** func Test_pyx() redir => var ! pyx << EOF ! import sys ! print(sys.version) ! EOF redir END call assert_match(s:py3pattern, split(var)[0]) endfunc --- 15,24 ---- func Test_pyx() redir => var ! pyx << trim EOF ! import sys ! print(sys.version) ! EOF redir END call assert_match(s:py3pattern, split(var)[0]) endfunc *************** *** 79,81 **** --- 79,100 ---- call assert_match( '^Vim(.*):RuntimeError: TEST$', v:exception ) endtry endfunc + + " Test for various heredoc syntaxes + func Test_pyx3_heredoc() + pyx << END + result='A' + END + pyx << + result+='B' + . + pyx << trim END + result+='C' + END + pyx << trim + result+='D' + . + call assert_equal('ABCD', pyxeval('result')) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_ruby.vim 2020-01-30 18:24:47.001204003 +0100 --- src/testdir/test_ruby.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 332,342 **** call setline(line('$'), ['2 line 2']) ruby Vim.command("normal /^2\n") let l = ["abc", "def"] ! ruby << EOF ! curline = $curbuf.line_number ! l = Vim.evaluate("l"); ! $curbuf.append(curline, l.join("\n")) ! EOF normal j .rubydo $_ = $_.gsub(/\n/, '/') call assert_equal('abc/def', getline('$')) --- 332,342 ---- call setline(line('$'), ['2 line 2']) ruby Vim.command("normal /^2\n") let l = ["abc", "def"] ! ruby << trim EOF ! curline = $curbuf.line_number ! l = Vim.evaluate("l"); ! $curbuf.append(curline, l.join("\n")) ! EOF normal j .rubydo $_ = $_.gsub(/\n/, '/') call assert_equal('abc/def', getline('$')) *************** *** 394,396 **** --- 394,415 ---- let messages = split(execute('message'), "\n") call assert_equal(0, len(messages)) endfunc + + " Test for various heredoc syntax + func Test_ruby_heredoc() + ruby << END + Vim.command('let s = "A"') + END + ruby << + Vim.command('let s ..= "B"') + . + ruby << trim END + Vim.command('let s ..= "C"') + END + ruby << trim + Vim.command('let s ..= "D"') + . + call assert_equal('ABCD', s) + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0577/src/testdir/test_tcl.vim 2020-03-22 14:41:19.167442574 +0100 --- src/testdir/test_tcl.vim 2020-04-14 20:04:20.137971185 +0200 *************** *** 67,77 **** " Test ::vim::buffer list call assert_equal('2', TclEval('llength [::vim::buffer list]')) call assert_equal(b1.' '.b2, TclEval('::vim::buffer list')) ! tcl <getline = heredoc_getline; eap->cookie = cctx; ! l = heredoc_get(eap, op + 3); // Push each line and the create the list. FOR_ALL_LIST_ITEMS(l, li) --- 4207,4213 ---- // [let] varname =<< [trim] {end} eap->getline = heredoc_getline; eap->cookie = cctx; ! l = heredoc_get(eap, op + 3, FALSE); // Push each line and the create the list. FOR_ALL_LIST_ITEMS(l, li) *** ../vim-8.2.0577/src/version.c 2020-04-13 21:16:18.039292270 +0200 --- src/version.c 2020-04-14 20:15:23.612611070 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 578, /**/ -- Looking at Perl through Lisp glasses, Perl looks atrocious. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///