When :py raise SystemExit, vim exit immediately. I know this is a spec of python. But most of users don't want this behavior. Below is a patch.
https://gist.github.com/mattn/5385037 diff -r 73bdb401d109 src/if_python.c --- a/src/if_python.c Fri Apr 12 12:27:30 2013 +0200 +++ b/src/if_python.c Mon Apr 15 10:22:23 2013 +0900 @@ -151,6 +151,7 @@ # define PyErr_PrintEx dll_PyErr_PrintEx # define PyErr_NoMemory dll_PyErr_NoMemory # define PyErr_Occurred dll_PyErr_Occurred +# define PyErr_ExceptionMatches dll_PyErr_ExceptionMatches # define PyErr_SetNone dll_PyErr_SetNone # define PyErr_SetString dll_PyErr_SetString # define PyEval_InitThreads dll_PyEval_InitThreads @@ -255,6 +256,7 @@ static void(*dll_PyErr_PrintEx)(int); static PyObject*(*dll_PyErr_NoMemory)(void); static PyObject*(*dll_PyErr_Occurred)(void); +static PyObject*(*dll_PyErr_ExceptionMatches)(PyObject *); static void(*dll_PyErr_SetNone)(PyObject *); static void(*dll_PyErr_SetString)(PyObject *, const char *); static void(*dll_PyEval_InitThreads)(void); @@ -351,12 +353,14 @@ static PyObject *imp_PyExc_KeyboardInterrupt; static PyObject *imp_PyExc_TypeError; static PyObject *imp_PyExc_ValueError; +static PyObject *imp_PyExc_SystemExit; # define PyExc_AttributeError imp_PyExc_AttributeError # define PyExc_IndexError imp_PyExc_IndexError # define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt # define PyExc_TypeError imp_PyExc_TypeError # define PyExc_ValueError imp_PyExc_ValueError +# define PyExc_SystemExit imp_PyExc_SystemExit /* * Table of name to function pointer of python. @@ -385,6 +389,7 @@ {"PyErr_PrintEx", (PYTHON_PROC*)&dll_PyErr_PrintEx}, {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory}, {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred}, + {"PyErr_ExceptionMatches", (PYTHON_PROC*)&dll_PyErr_ExceptionMatches}, {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone}, {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString}, {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads}, @@ -582,11 +587,13 @@ 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"); Py_XINCREF(imp_PyExc_AttributeError); Py_XINCREF(imp_PyExc_IndexError); Py_XINCREF(imp_PyExc_KeyboardInterrupt); Py_XINCREF(imp_PyExc_TypeError); Py_XINCREF(imp_PyExc_ValueError); + Py_XINCREF(imp_PyExc_SystemExit); Py_XDECREF(exmod); } #endif /* DYNAMIC_PYTHON */ @@ -805,6 +812,7 @@ #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) char *saved_locale; #endif + PyObject *r; #ifndef PY_CAN_RECURSE if (recursive) @@ -851,27 +859,29 @@ Python_RestoreThread(); /* enter python */ - if (rettv == NULL) - PyRun_SimpleString((char *)(cmd)); + r = PyRun_String((char *)(cmd), Py_single_input, globals, globals); + if (r == NULL) + { + if (PyErr_Occurred()) + { + if (PyErr_ExceptionMatches(PyExc_SystemExit)) + { + EMSG(_("E863: Can't handle SystemExit of python exception in vim")); + PyErr_Clear(); + } + if (!msg_silent) + PyErr_PrintEx(0); + } + if (rettv != NULL) + EMSG(_("E858: Eval did not return a valid python object")); + } else { - PyObject *r; - - r = PyRun_String((char *)(cmd), Py_eval_input, globals, globals); - if (r == NULL) - { - if (PyErr_Occurred() && !msg_silent) - PyErr_PrintEx(0); - EMSG(_("E858: Eval did not return a valid python object")); - } - else - { - if (ConvertFromPyObject(r, rettv) == -1) - EMSG(_("E859: Failed to convert returned python object to vim value")); - Py_DECREF(r); - } - PyErr_Clear(); + if (rettv != NULL && ConvertFromPyObject(r, rettv) == -1) + EMSG(_("E859: Failed to convert returned python object to vim value")); + Py_DECREF(r); } + PyErr_Clear(); Python_SaveThread(); /* leave python */ diff -r 73bdb401d109 src/if_python3.c --- a/src/if_python3.c Fri Apr 12 12:27:30 2013 +0200 +++ b/src/if_python3.c Mon Apr 15 10:22:23 2013 +0900 @@ -125,6 +125,7 @@ # define PyErr_PrintEx py3_PyErr_PrintEx # define PyErr_NoMemory py3_PyErr_NoMemory # define PyErr_Occurred py3_PyErr_Occurred +# define PyErr_ExceptionMatches py3_PyErr_ExceptionMatches # define PyErr_SetNone py3_PyErr_SetNone # define PyErr_SetString py3_PyErr_SetString # define PyEval_InitThreads py3_PyEval_InitThreads @@ -255,6 +256,7 @@ static PyObject* (*py3_PyImport_AddModule)(const char *); static int (*py3_PyErr_BadArgument)(void); static PyObject* (*py3_PyErr_Occurred)(void); +static PyObject* (*py3_PyErr_ExceptionMatches)(PyObject *); static PyObject* (*py3_PyModule_GetDict)(PyObject *); static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *); static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *); @@ -330,12 +332,14 @@ static PyObject *p3imp_PyExc_KeyboardInterrupt; static PyObject *p3imp_PyExc_TypeError; static PyObject *p3imp_PyExc_ValueError; +static PyObject *p3imp_PyExc_SystemExit; # define PyExc_AttributeError p3imp_PyExc_AttributeError # define PyExc_IndexError p3imp_PyExc_IndexError # define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt # define PyExc_TypeError p3imp_PyExc_TypeError # define PyExc_ValueError p3imp_PyExc_ValueError +# define PyExc_SystemExit p3imp_PyExc_SystemExit /* * Table of name to function pointer of python. @@ -381,6 +385,7 @@ {"PyImport_AddModule", (PYTHON_PROC*)&py3_PyImport_AddModule}, {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument}, {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred}, + {"PyErr_ExceptionMatches", (PYTHON_PROC*)&py3_PyErr_ExceptionMatches}, {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict}, {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem}, {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString}, @@ -570,11 +575,13 @@ 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"); Py_XINCREF(p3imp_PyExc_AttributeError); Py_XINCREF(p3imp_PyExc_IndexError); Py_XINCREF(p3imp_PyExc_KeyboardInterrupt); Py_XINCREF(p3imp_PyExc_TypeError); Py_XINCREF(p3imp_PyExc_ValueError); + Py_XINCREF(p3imp_PyExc_SystemExit); Py_XDECREF(exmod); } #endif /* DYNAMIC_PYTHON3 */ @@ -793,6 +800,7 @@ #endif PyObject *cmdstr; PyObject *cmdbytes; + PyObject *r; #if defined(MACOS) && !defined(MACOS_X_UNIX) GetPort(&oldPort); @@ -836,28 +844,32 @@ (char *)ENC_OPT, CODEC_ERROR_HANDLER); cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER); Py_XDECREF(cmdstr); - if (rettv == NULL) - PyRun_SimpleString(PyBytes_AsString(cmdbytes)); + + r = PyRun_String(PyBytes_AsString(cmdbytes), Py_single_input, + globals, globals); + if (r == NULL) + { + if (PyErr_Occurred()) + { + if (PyErr_ExceptionMatches(PyExc_SystemExit)) + { + EMSG(_("E864: Can't handle SystemExit of python 3 exception in vim")); + PyErr_Clear(); + } + if (!msg_silent) + PyErr_PrintEx(0); + } + if (rettv != NULL) + EMSG(_("E860: Eval did not return a valid python 3 object")); + } else { - PyObject *r; + if (rettv != NULL && ConvertFromPyObject(r, rettv) == -1) + EMSG(_("E861: Failed to convert returned python 3 object to vim value")); + Py_DECREF(r); + } + PyErr_Clear(); - r = PyRun_String(PyBytes_AsString(cmdbytes), Py_eval_input, - globals, globals); - if (r == NULL) - { - if (PyErr_Occurred() && !msg_silent) - PyErr_PrintEx(0); - EMSG(_("E860: Eval did not return a valid python 3 object")); - } - else - { - if (ConvertFromPyObject(r, rettv) == -1) - EMSG(_("E861: Failed to convert returned python 3 object to vim value")); - Py_DECREF(r); - } - PyErr_Clear(); - } Py_XDECREF(cmdbytes); PyGILState_Release(pygilstate); -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
