]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.997 v7.3.997
authorBram Moolenaar <Bram@vim.org>
Tue, 21 May 2013 18:40:40 +0000 (20:40 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 21 May 2013 18:40:40 +0000 (20:40 +0200)
Problem:    Vim and Python exceptions are different.
Solution:   Make Vim exceptions be Python exceptions. (ZyX)

src/if_py_both.h
src/testdir/test86.in
src/testdir/test86.ok
src/testdir/test87.in
src/testdir/test87.ok
src/version.c

index 957d6d5cd8a23c1c97222a774686542a4cf06b6a..b9ffcbb70b8cb0dcbc75c25a5b54c963bdd784e4 100644 (file)
@@ -272,20 +272,42 @@ static PyObject *VimError;
 /* Check to see whether a Vim error has been reported, or a keyboard
  * interrupt has been detected.
  */
+
+    static void
+VimTryStart(void)
+{
+    ++trylevel;
+}
+
     static int
-VimErrorCheck(void)
+VimTryEnd(void)
 {
+    --trylevel;
     if (got_int)
     {
        PyErr_SetNone(PyExc_KeyboardInterrupt);
        return 1;
     }
-    else if (did_emsg && !PyErr_Occurred())
+    else if (!did_throw)
+       return 0;
+    else if (PyErr_Occurred())
+       return 1;
+    else
     {
-       PyErr_SetNone(VimError);
+       PyErr_SetVim((char *) current_exception->value);
+       discard_current_exception();
        return 1;
     }
+}
 
+    static int
+VimCheckInterrupt(void)
+{
+    if (got_int)
+    {
+       PyErr_SetNone(PyExc_KeyboardInterrupt);
+       return 1;
+    }
     return 0;
 }
 
@@ -306,17 +328,19 @@ VimCommand(PyObject *self UNUSED, PyObject *args)
     Py_BEGIN_ALLOW_THREADS
     Python_Lock_Vim();
 
+    VimTryStart();
     do_cmdline_cmd((char_u *)cmd);
     update_screen(VALID);
 
     Python_Release_Vim();
     Py_END_ALLOW_THREADS
 
-    if (VimErrorCheck())
+    if (VimTryEnd())
        result = NULL;
     else
        result = Py_None;
 
+
     Py_XINCREF(result);
     return result;
 }
@@ -449,11 +473,14 @@ VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
 
     Py_BEGIN_ALLOW_THREADS
     Python_Lock_Vim();
+    VimTryStart();
     our_tv = eval_expr((char_u *)expr, NULL);
-
     Python_Release_Vim();
     Py_END_ALLOW_THREADS
 
+    if (VimTryEnd())
+       return NULL;
+
     if (our_tv == NULL)
     {
        PyErr_SetVim(_("invalid expression"));
@@ -490,11 +517,14 @@ VimEvalPy(PyObject *self UNUSED, PyObject *args)
 
     Py_BEGIN_ALLOW_THREADS
     Python_Lock_Vim();
+    VimTryStart();
     our_tv = eval_expr((char_u *)expr, NULL);
-
     Python_Release_Vim();
     Py_END_ALLOW_THREADS
 
+    if (VimTryEnd())
+       return NULL;
+
     if (our_tv == NULL)
     {
        PyErr_SetVim(_("invalid expression"));
@@ -1324,12 +1354,15 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
     Py_BEGIN_ALLOW_THREADS
     Python_Lock_Vim();
 
+    VimTryStart();
     error = func_call(name, &args, selfdict, &rettv);
 
     Python_Release_Vim();
     Py_END_ALLOW_THREADS
 
-    if (error != OK)
+    if (VimTryEnd())
+       result = NULL;
+    else if (error != OK)
     {
        result = NULL;
        PyErr_SetVim(_("failed to run function"));
@@ -1486,14 +1519,16 @@ set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
     win_T      *save_curwin;
     tabpage_T  *save_curtab;
     buf_T      *save_curbuf;
-    int                r = 0;
 
+    VimTryStart();
     switch (opt_type)
     {
        case SREQ_WIN:
            if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
                                     win_find_tabpage((win_T *)from)) == FAIL)
            {
+               if (VimTryEnd())
+                   return -1;
                PyErr_SetVim("Problem while switching windows.");
                return -1;
            }
@@ -1509,7 +1544,7 @@ set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
            set_option_value(key, numval, stringval, opt_flags);
            break;
     }
-    return r;
+    return VimTryEnd();
 }
 
     static int
@@ -1961,7 +1996,7 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
        }
 
        /* Check for keyboard interrupts */
-       if (VimErrorCheck())
+       if (VimCheckInterrupt())
            return -1;
 
        self->win->w_cursor.lnum = lnum;
@@ -1988,11 +2023,11 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
 #endif
        savewin = curwin;
        curwin = self->win;
+
+       VimTryStart();
        win_setheight(height);
        curwin = savewin;
-
-       /* Check for keyboard interrupts */
-       if (VimErrorCheck())
+       if (VimTryEnd())
            return -1;
 
        return 0;
@@ -2011,11 +2046,11 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
 #endif
        savewin = curwin;
        curwin = self->win;
+
+       VimTryStart();
        win_setwidth(width);
        curwin = savewin;
-
-       /* Check for keyboard interrupts */
-       if (VimErrorCheck())
+       if (VimTryEnd())
            return -1;
 
        return 0;
@@ -2304,6 +2339,8 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
        PyErr_Clear();
        switch_buffer(&savebuf, buf);
 
+       VimTryStart();
+
        if (u_savedel((linenr_T)n, 1L) == FAIL)
            PyErr_SetVim(_("cannot save undo information"));
        else if (ml_delete((linenr_T)n, FALSE) == FAIL)
@@ -2317,7 +2354,7 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
 
        restore_buffer(savebuf);
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2333,6 +2370,8 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
        if (save == NULL)
            return FAIL;
 
+       VimTryStart();
+
        /* We do not need to free "save" if ml_replace() consumes it. */
        PyErr_Clear();
        switch_buffer(&savebuf, buf);
@@ -2356,7 +2395,7 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
        if (buf == savebuf)
            check_cursor_col();
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2395,6 +2434,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
        buf_T   *savebuf;
 
        PyErr_Clear();
+       VimTryStart();
        switch_buffer(&savebuf, buf);
 
        if (u_savedel((linenr_T)lo, (long)n) == FAIL)
@@ -2416,7 +2456,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
 
        restore_buffer(savebuf);
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2459,6 +2499,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
            }
        }
 
+       VimTryStart();
        PyErr_Clear();
 
        // START of region without "return".  Must call restore_buffer()!
@@ -2545,7 +2586,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
        // END of region without "return".
        restore_buffer(savebuf);
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2583,6 +2624,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
            return FAIL;
 
        PyErr_Clear();
+       VimTryStart();
        switch_buffer(&savebuf, buf);
 
        if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
@@ -2596,7 +2638,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
        restore_buffer(savebuf);
        update_screen(VALID);
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2633,6 +2675,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
        }
 
        PyErr_Clear();
+       VimTryStart();
        switch_buffer(&savebuf, buf);
 
        if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
@@ -2666,7 +2709,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
        restore_buffer(savebuf);
        update_screen(VALID);
 
-       if (PyErr_Occurred() || VimErrorCheck())
+       if (VimTryEnd())
            return FAIL;
 
        if (len_change)
@@ -2896,7 +2939,7 @@ RangeNew(buf_T *buf, PyInt start, PyInt end)
     static void
 RangeDestructor(RangeObject *self)
 {
-    Py_DECREF(self->buf);
+    Py_XDECREF(self->buf);
     DESTRUCTOR_FINISH(self);
 }
 
@@ -3078,9 +3121,12 @@ BufferMark(BufferObject *self, PyObject *args)
        return NULL;
     mark = *pmark;
 
+    VimTryStart();
     switch_buffer(&savebuf, self->buf);
     posp = getmark(mark, FALSE);
     restore_buffer(savebuf);
+    if (VimTryEnd())
+       return NULL;
 
     if (posp == NULL)
     {
@@ -3088,10 +3134,6 @@ BufferMark(BufferObject *self, PyObject *args)
        return NULL;
     }
 
-    /* Check for keyboard interrupt */
-    if (VimErrorCheck())
-       return NULL;
-
     if (posp->lnum <= 0)
     {
        /* Or raise an error? */
@@ -3330,13 +3372,16 @@ CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
            return -1;
        count = ((BufferObject *)(value))->buf->b_fnum;
 
+       VimTryStart();
        if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
        {
+           if (VimTryEnd())
+               return -1;
            PyErr_SetVim(_("failed to switch to given buffer"));
            return -1;
        }
 
-       return 0;
+       return VimTryEnd();
     }
     else if (strcmp(name, "window") == 0)
     {
@@ -3359,15 +3404,18 @@ CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
            return -1;
        }
 
+       VimTryStart();
        win_goto(((WindowObject *)(value))->win);
        if (((WindowObject *)(value))->win != curwin)
        {
+           if (VimTryEnd())
+               return -1;
            PyErr_SetString(PyExc_RuntimeError,
                    _("did not switch to the specified window"));
            return -1;
        }
 
-       return 0;
+       return VimTryEnd();
     }
     else if (strcmp(name, "tabpage") == 0)
     {
@@ -3380,15 +3428,18 @@ CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
        if (CheckTabPage((TabPageObject *)(value)))
            return -1;
 
+       VimTryStart();
        goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
        if (((TabPageObject *)(value))->tab != curtab)
        {
+           if (VimTryEnd())
+               return -1;
            PyErr_SetString(PyExc_RuntimeError,
                    _("did not switch to the specified tab page"));
            return -1;
        }
 
-       return 0;
+       return VimTryEnd();
     }
     else
     {
index c49eb3bade60255e46dafcb55336c206ce50a7a0..fac315e2d23e47a6691d51007c65ea9e5e092fa8 100644 (file)
@@ -380,20 +380,24 @@ def e(s, g=globals(), l=locals()):
     try:
         exec(s, g, l)
     except:
-        vim.command('throw ' + repr(sys.exc_type.__name__))
+        vim.command('return ' + repr(sys.exc_type.__name__))
 
 def ev(s, g=globals(), l=locals()):
     try:
         return eval(s, g, l)
     except:
-        vim.command('throw ' + repr(sys.exc_type.__name__))
+        vim.command('let exc=' + repr(sys.exc_type.__name__))
         return 0
 EOF
 :function E(s)
 :   python e(vim.eval('a:s'))
 :endfunction
 :function Ev(s)
-:   return pyeval('ev(vim.eval("a:s"))')
+:   let r=pyeval('ev(vim.eval("a:s"))')
+:   if exists('exc')
+:       throw exc
+:   endif
+:   return r
 :endfunction
 :py gopts1=vim.options
 :py wopts1=vim.windows[2].options
@@ -437,27 +441,24 @@ EOF
 :       catch
 :           put ='  p/'.v.'! '.v:exception
 :       endtry
-:       try
-:           call E(v.'["'.oname.'"]=invval')
-:       catch
-:           put ='  inv: '.string(invval).'! '.v:exception
-:       endtry
+:       let r=E(v.'['''.oname.''']=invval')
+:       if r isnot 0
+:           put ='  inv: '.string(invval).'! '.r
+:       endif
 :       for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
 :           let val=substitute(vv, '^.opts', 'oval', '')
-:           try
-:               call E(vv.'["'.oname.'"]='.val)
-:           catch
-:               put ='  '.vv.'! '.v:exception
-:           endtry
+:           let r=E(vv.'['''.oname.''']='.val)
+:           if r isnot 0
+:               put ='  '.vv.'! '.r
+:           endif
 :       endfor
 :   endfor
 :   call RecVars(oname)
 :   for v in ['wopts3', 'bopts3']
-:       try
-:           call E('del '.v.'["'.oname.'"]')
-:       catch
-:           put ='  del '.v.'! '.v:exception
-:       endtry
+:       let r=E('del '.v.'["'.oname.'"]')
+:       if r isnot 0
+:           put ='  del '.v.'! '.r
+:       endif
 :   endfor
 :   call RecVars(oname)
 :endfor
@@ -651,6 +652,25 @@ for expr, attr in (
 ):
     cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
 EOF
+:"
+:" Test exceptions
+:fun Exe(e)
+:   execute a:e
+:endfun
+py << EOF
+def ee(expr, g=globals(), l=locals()):
+    try:
+        exec(expr, g, l)
+    except:
+        cb.append(repr(sys.exc_info()[:2]))
+Exe = vim.bindeval('function("Exe")')
+ee('vim.command("throw \'abc\'")')
+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.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+EOF
 :endfun
 :"
 :call Test()
index c91f741a052c9a7d9c16556fdaf68c93ef90fa36..5602b2f103b271bb3b6e62b5731931a632791ca5 100644 (file)
@@ -333,7 +333,7 @@ Number of tabs: 4
 Current tab pages:
   <tabpage 0>(1): 1 windows, current is <window object (unknown)>
   Windows:
-    <window object (unknown)>(1): displays buffer <buffer test86.in>; cursor is at (970, 0)
+    <window object (unknown)>(1): displays buffer <buffer test86.in>; cursor is at (990, 0)
   <tabpage 1>(2): 1 windows, current is <window object (unknown)>
   Windows:
     <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
@@ -368,3 +368,9 @@ vim.current.buffer:Buffer:True
 vim.current.range:Range:True
 vim.current.window:Window:True
 vim.current.tabpage:TabPage:True
+(<class 'vim.error'>, error('abc',))
+(<class 'vim.error'>, error('def',))
+(<class 'vim.error'>, error('ghi',))
+(<class 'vim.error'>, error('Vim(echoerr):jkl',))
+(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
+(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
index 94c1ab5357836d2b093b6547b306e83b501f51d5..69af02eecbb0d87ad31b1521619d8ee960adc61f 100644 (file)
@@ -367,20 +367,24 @@ def e(s, g=globals(), l=locals()):
     try:
         exec(s, g, l)
     except Exception as e:
-        vim.command('throw ' + repr(e.__class__.__name__))
+        vim.command('return ' + repr(e.__class__.__name__))
 
 def ev(s, g=globals(), l=locals()):
     try:
         return eval(s, g, l)
     except Exception as e:
-        vim.command('throw ' + repr(e.__class__.__name__))
+        vim.command('let exc=' + repr(e.__class__.__name__))
         return 0
 EOF
 :function E(s)
 :   python3 e(vim.eval('a:s'))
 :endfunction
 :function Ev(s)
-:   return py3eval('ev(vim.eval("a:s"))')
+:   let r=py3eval('ev(vim.eval("a:s"))')
+:   if exists('exc')
+:       throw exc
+:   endif
+:   return r
 :endfunction
 :py3 gopts1=vim.options
 :py3 wopts1=vim.windows[2].options
@@ -424,27 +428,24 @@ EOF
 :       catch
 :           put ='  p/'.v.'! '.v:exception
 :       endtry
-:       try
-:           call E(v.'["'.oname.'"]=invval')
-:       catch
-:           put ='  inv: '.string(invval).'! '.v:exception
-:       endtry
+:       let r=E(v.'['''.oname.''']=invval')
+:       if r isnot 0
+:           put ='  inv: '.string(invval).'! '.r
+:       endif
 :       for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
 :           let val=substitute(vv, '^.opts', 'oval', '')
-:           try
-:               call E(vv.'["'.oname.'"]='.val)
-:           catch
-:               put ='  '.vv.'! '.v:exception
-:           endtry
+:           let r=E(vv.'['''.oname.''']='.val)
+:           if r isnot 0
+:               put ='  '.vv.'! '.r
+:           endif
 :       endfor
 :   endfor
 :   call RecVars(oname)
 :   for v in ['wopts3', 'bopts3']
-:       try
-:           call E('del '.v.'["'.oname.'"]')
-:       catch
-:           put ='  del '.v.'! '.v:exception
-:       endtry
+:       let r=E('del '.v.'["'.oname.'"]')
+:       if r isnot 0
+:           put ='  del '.v.'! '.r
+:       endif
 :   endfor
 :   call RecVars(oname)
 :endfor
@@ -638,6 +639,25 @@ for expr, attr in (
 ):
     cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
 EOF
+:"
+:" Test exceptions
+:fun Exe(e)
+:   execute a:e
+:endfun
+py3 << EOF
+def ee(expr, g=globals(), l=locals()):
+    try:
+        exec(expr, g, l)
+    except Exception as e:
+        cb.append(repr((e.__class__, e)))
+Exe = vim.bindeval('function("Exe")')
+ee('vim.command("throw \'abc\'")')
+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.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+EOF
 :endfun
 :"
 :call Test()
index 08cd590e243285c37515ed5e1f2c90f7d9c4d0d9..64ef57d5cceb4c1960a2fc19c61687008e95150c 100644 (file)
@@ -322,7 +322,7 @@ Number of tabs: 4
 Current tab pages:
   <tabpage 0>(1): 1 windows, current is <window object (unknown)>
   Windows:
-    <window object (unknown)>(1): displays buffer <buffer test87.in>; cursor is at (946, 0)
+    <window object (unknown)>(1): displays buffer <buffer test87.in>; cursor is at (966, 0)
   <tabpage 1>(2): 1 windows, current is <window object (unknown)>
   Windows:
     <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
@@ -357,3 +357,9 @@ vim.current.buffer:Buffer:True
 vim.current.range:Range:True
 vim.current.window:Window:True
 vim.current.tabpage:TabPage:True
+(<class 'vim.error'>, error('abc',))
+(<class 'vim.error'>, error('def',))
+(<class 'vim.error'>, error('ghi',))
+(<class 'vim.error'>, error('Vim(echoerr):jkl',))
+(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
+(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
index 817112427204764660a55352d4c5972cd3ca2443..411687e67f6597efb9370910b0b3af9c7fd5ac89 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    997,
 /**/
     996,
 /**/