]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1287 v7.3.1287
authorBram Moolenaar <Bram@vim.org>
Mon, 1 Jul 2013 20:03:04 +0000 (22:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 1 Jul 2013 20:03:04 +0000 (22:03 +0200)
Problem:    Python SystemExit exception is not handled properly.
Solution:   Catch the exception and give an error. (Yasuhiro Matsumoto, Ken
            Takata)

runtime/doc/if_pyth.txt
src/if_py_both.h
src/if_python.c
src/if_python3.c
src/version.c

index 055a5372df1a6d6dedac4307151fd5bac8a25cbc..29718b20ac6a63e3e01418972bb92429fea8254d 100644 (file)
@@ -740,6 +740,11 @@ To work around such problems there are these options:
 3. You undefine PY_NO_RTLD_GLOBAL in auto/config.h after configuration.  This
    may crash Vim though.
 
+                                                       *E880*
+Raising SystemExit exception in python isn't endorsed way to quit vim, use: >
+       :py vim.command("qall!")
+<
+
                                                        *has-python*
 You can test what Python version is available with: >
        if has('python')
index b564d24b5d623220865b740ac0b28d610f461389..7253fc72c49a4351b76715a20d3c043415a91997 100644 (file)
@@ -13,6 +13,8 @@
  * Common code for if_python.c and if_python3.c.
  */
 
+static char_u e_py_systemexit[]        = "E880: Can't handle SystemExit of %s exception in vim";
+
 #if PY_VERSION_HEX < 0x02050000
 typedef int Py_ssize_t;  /* Python 2.4 and earlier don't have this type. */
 #endif
@@ -275,7 +277,7 @@ ObjectDir(PyObject *self, char **attributes)
 
     if (self)
        for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
-           if (add_string(ret, (char *) method->ml_name))
+           if (add_string(ret, (char *)method->ml_name))
            {
                Py_DECREF(ret);
                return NULL;
@@ -549,8 +551,9 @@ VimTryStart(void)
 VimTryEnd(void)
 {
     --trylevel;
-    /* Without this it stops processing all subsequent VimL commands and 
-     * generates strange error messages if I e.g. try calling Test() in a cycle */
+    /* Without this it stops processing all subsequent VimL commands and
+     * generates strange error messages if I e.g. try calling Test() in a
+     * cycle */
     did_emsg = FALSE;
     /* Keyboard interrupt should be preferred over anything else */
     if (got_int)
@@ -570,7 +573,7 @@ VimTryEnd(void)
     /* Finally transform VimL exception to python one */
     else
     {
-       PyErr_SetVim((char *) current_exception->value);
+       PyErr_SetVim((char *)current_exception->value);
        discard_current_exception();
        return -1;
     }
@@ -667,7 +670,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
 
        /* For backwards compatibility numbers are stored as strings. */
        sprintf(buf, "%ld", (long)our_tv->vval.v_number);
-       ret = PyString_FromString((char *) buf);
+       ret = PyString_FromString((char *)buf);
     }
 # ifdef FEAT_FLOAT
     else if (our_tv->v_type == VAR_FLOAT)
@@ -675,7 +678,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
        char buf[NUMBUFLEN];
 
        sprintf(buf, "%f", our_tv->vval.v_float);
-       ret = PyString_FromString((char *) buf);
+       ret = PyString_FromString((char *)buf);
     }
 # endif
     else if (our_tv->v_type == VAR_LIST)
@@ -955,7 +958,7 @@ map_rtp_callback(char_u *path, void *_data)
     PyObject   *pathObject;
     map_rtp_data       *mr_data = *((map_rtp_data **) data);
 
-    if (!(pathObject = PyString_FromString((char *) path)))
+    if (!(pathObject = PyString_FromString((char *)path)))
     {
        *data = NULL;
        return;
@@ -1124,7 +1127,7 @@ find_module(char *fullname, char *tail, PyObject *new_path)
     PyObject   *module;
     char       *dot;
 
-    if ((dot = (char *) vim_strchr((char_u *) tail, '.')))
+    if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
     {
        /*
         * There is a dot in the name: call find_module recursively without the
@@ -1658,7 +1661,7 @@ DictionaryIterNext(dictiterinfo_T **dii)
 
     --((*dii)->todo);
 
-    if (!(ret = PyBytes_FromString((char *) (*dii)->hi->hi_key)))
+    if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
        return NULL;
 
     return ret;
@@ -2680,12 +2683,12 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
 FunctionRepr(FunctionObject *self)
 {
 #ifdef Py_TRACE_REFS
-    /* For unknown reason self->name may be NULL after calling 
+    /* For unknown reason self->name may be NULL after calling
      * Finalize */
     return PyString_FromFormat("<vim.Function '%s'>",
-           (self->name == NULL ? "<NULL>" : (char *) self->name));
+           (self->name == NULL ? "<NULL>" : (char *)self->name));
 #else
-    return PyString_FromFormat("<vim.Function '%s'>", (char *) self->name);
+    return PyString_FromFormat("<vim.Function '%s'>", (char *)self->name);
 #endif
 }
 
@@ -2809,7 +2812,7 @@ OptionsItem(OptionsObject *self, PyObject *keyObject)
     {
        if (stringval)
        {
-           PyObject    *ret = PyBytes_FromString((char *) stringval);
+           PyObject    *ret = PyBytes_FromString((char *)stringval);
            vim_free(stringval);
            return ret;
        }
@@ -4525,7 +4528,7 @@ BufferAttr(BufferObject *self, char *name)
 {
     if (strcmp(name, "name") == 0)
        return PyString_FromString((self->buf->b_ffname == NULL
-                                   ? "" : (char *) self->buf->b_ffname));
+                                   ? "" : (char *)self->buf->b_ffname));
     else if (strcmp(name, "number") == 0)
        return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
     else if (strcmp(name, "vars") == 0)
@@ -4961,7 +4964,19 @@ run_cmd(const char *cmd, void *arg UNUSED
 #endif
        )
 {
-    PyRun_SimpleString((char *) cmd);
+    PyObject   *run_ret;
+    run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
+    if (run_ret != NULL)
+    {
+       Py_DECREF(run_ret);
+    }
+    else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
+    {
+       EMSG2(_(e_py_systemexit), "python");
+       PyErr_Clear();
+    }
+    else
+       PyErr_PrintEx(1);
 }
 
 static const char      *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
@@ -4979,6 +4994,7 @@ run_do(const char *cmd, void *arg UNUSED
     char       *code;
     int                status;
     PyObject   *pyfunc, *pymain;
+    PyObject   *run_ret;
 
     if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
     {
@@ -4990,7 +5006,23 @@ run_do(const char *cmd, void *arg UNUSED
     code = PyMem_New(char, len + 1);
     memcpy(code, code_hdr, code_hdr_len);
     STRCPY(code + code_hdr_len, cmd);
-    status = PyRun_SimpleString(code);
+    run_ret = PyRun_String(code, Py_file_input, globals, globals);
+    status = -1;
+    if (run_ret != NULL)
+    {
+       status = 0;
+       Py_DECREF(run_ret);
+    }
+    else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
+    {
+       PyMem_Free(code);
+       EMSG2(_(e_py_systemexit), "python");
+       PyErr_Clear();
+       return;
+    }
+    else
+       PyErr_PrintEx(1);
+
     PyMem_Free(code);
 
     if (status)
@@ -5068,9 +5100,14 @@ run_eval(const char *cmd, typval_T *rettv
 {
     PyObject   *run_ret;
 
-    run_ret = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
+    run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
     if (run_ret == NULL)
     {
+       if (PyErr_ExceptionMatches(PyExc_SystemExit))
+       {
+           EMSG2(_(e_py_systemexit), "python");
+           PyErr_Clear();
+       }
        if (PyErr_Occurred() && !msg_silent)
            PyErr_PrintEx(0);
        EMSG(_("E858: Eval did not return a valid python object"));
index 5245485e33643cc5c230da553eab3398cc854da5..6e43b5dc3d955794f92bece4ef5322a74f05e263 100644 (file)
@@ -444,6 +444,7 @@ static PyObject *imp_PyExc_KeyError;
 static PyObject *imp_PyExc_KeyboardInterrupt;
 static PyObject *imp_PyExc_TypeError;
 static PyObject *imp_PyExc_ValueError;
+static PyObject *imp_PyExc_SystemExit;
 static PyObject *imp_PyExc_RuntimeError;
 static PyObject *imp_PyExc_ImportError;
 static PyObject *imp_PyExc_OverflowError;
@@ -454,6 +455,7 @@ static PyObject *imp_PyExc_OverflowError;
 # define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt
 # define PyExc_TypeError imp_PyExc_TypeError
 # define PyExc_ValueError imp_PyExc_ValueError
+# define PyExc_SystemExit imp_PyExc_SystemExit
 # define PyExc_RuntimeError imp_PyExc_RuntimeError
 # define PyExc_ImportError imp_PyExc_ImportError
 # define PyExc_OverflowError imp_PyExc_OverflowError
@@ -731,6 +733,7 @@ get_exceptions(void)
     imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
     imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
     imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
+    imp_PyExc_SystemExit = PyDict_GetItemString(exdict, "SystemExit");
     imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
     imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
     imp_PyExc_OverflowError = PyDict_GetItemString(exdict, "OverflowError");
@@ -740,6 +743,7 @@ get_exceptions(void)
     Py_XINCREF(imp_PyExc_KeyboardInterrupt);
     Py_XINCREF(imp_PyExc_TypeError);
     Py_XINCREF(imp_PyExc_ValueError);
+    Py_XINCREF(imp_PyExc_SystemExit);
     Py_XINCREF(imp_PyExc_RuntimeError);
     Py_XINCREF(imp_PyExc_ImportError);
     Py_XINCREF(imp_PyExc_OverflowError);
index badf015c20b9cfb695cf52969e47aaf0991b1a90..6849f1fb10b71e0f6a53c5fe1a6464bce24a84d7 100644 (file)
 # define PyErr_PrintEx py3_PyErr_PrintEx
 # define PyErr_NoMemory py3_PyErr_NoMemory
 # define PyErr_Occurred py3_PyErr_Occurred
-# define PyErr_PrintEx py3_PyErr_PrintEx
 # define PyErr_SetNone py3_PyErr_SetNone
 # define PyErr_SetString py3_PyErr_SetString
 # define PyErr_SetObject py3_PyErr_SetObject
@@ -403,6 +402,7 @@ static PyObject *p3imp_PyExc_KeyError;
 static PyObject *p3imp_PyExc_KeyboardInterrupt;
 static PyObject *p3imp_PyExc_TypeError;
 static PyObject *p3imp_PyExc_ValueError;
+static PyObject *p3imp_PyExc_SystemExit;
 static PyObject *p3imp_PyExc_RuntimeError;
 static PyObject *p3imp_PyExc_ImportError;
 static PyObject *p3imp_PyExc_OverflowError;
@@ -413,6 +413,7 @@ static PyObject *p3imp_PyExc_OverflowError;
 # define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
 # define PyExc_TypeError p3imp_PyExc_TypeError
 # define PyExc_ValueError p3imp_PyExc_ValueError
+# define PyExc_SystemExit p3imp_PyExc_SystemExit
 # define PyExc_RuntimeError p3imp_PyExc_RuntimeError
 # define PyExc_ImportError p3imp_PyExc_ImportError
 # define PyExc_OverflowError p3imp_PyExc_OverflowError
@@ -681,6 +682,7 @@ get_py3_exceptions()
     p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
     p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
     p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
+    p3imp_PyExc_SystemExit = PyDict_GetItemString(exdict, "SystemExit");
     p3imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
     p3imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
     p3imp_PyExc_OverflowError = PyDict_GetItemString(exdict, "OverflowError");
@@ -690,6 +692,7 @@ get_py3_exceptions()
     Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
     Py_XINCREF(p3imp_PyExc_TypeError);
     Py_XINCREF(p3imp_PyExc_ValueError);
+    Py_XINCREF(p3imp_PyExc_SystemExit);
     Py_XINCREF(p3imp_PyExc_RuntimeError);
     Py_XINCREF(p3imp_PyExc_ImportError);
     Py_XINCREF(p3imp_PyExc_OverflowError);
index d73254f5c5ebbd200ddd01f996d2b2bcd96a5190..830035f4352d09b438524bbc8e14753fcee8fe91 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1287,
 /**/
     1286,
 /**/