changeset 14467:16cccc953909 v8.1.0247

patch 8.1.0247: Python: error message for failing import is incorrect commit https://github.com/vim/vim/commit/447bd5a346b5c4bf4d91280700bdb4b45e0aa667 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Aug 7 19:45:27 2018 +0200 patch 8.1.0247: Python: error message for failing import is incorrect Problem: Python: error message for failing import is incorrect. Solution: Adjust how modules are loaded. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/3162)
author Christian Brabandt <cb@256bit.org>
date Tue, 07 Aug 2018 20:00:06 +0200
parents 23c6efafa95d
children 8b70108080f2
files src/if_py_both.h src/testdir/test86.ok src/testdir/test87.ok src/version.c
diffstat 4 files changed, 66 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -544,27 +544,57 @@ PythonIO_Init_io(void)
 }
 
 #if PY_VERSION_HEX < 0x030700f0
+static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
+
 typedef struct
 {
     PyObject_HEAD
-    PyObject	*module;
+    char	*fullname;
+    PyObject	*result;
 } LoaderObject;
 static PyTypeObject LoaderType;
 
     static void
 LoaderDestructor(LoaderObject *self)
 {
-    Py_DECREF(self->module);
+    vim_free(self->fullname);
+    Py_XDECREF(self->result);
     DESTRUCTOR_FINISH(self);
 }
 
     static PyObject *
 LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
 {
-    PyObject	*ret = self->module;
-
-    Py_INCREF(ret);
-    return ret;
+    char	*fullname = self->fullname;
+    PyObject	*result = self->result;
+    PyObject	*module;
+
+    if (!fullname)
+    {
+	module = result ? result : Py_None;
+	Py_INCREF(module);
+	return module;
+    }
+
+    module = call_load_module(fullname, (int)STRLEN(fullname), result);
+
+    self->fullname = NULL;
+    self->result = module;
+
+    vim_free(fullname);
+    Py_DECREF(result);
+
+    if (!module)
+    {
+	if (PyErr_Occurred())
+	    return NULL;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+
+    Py_INCREF(module);
+    return module;
 }
 
 static struct PyMethodDef LoaderMethods[] = {
@@ -1252,7 +1282,11 @@ find_module(char *fullname, char *tail, 
 
 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
 			"s#O", tail, partlen, new_path)))
+	{
+	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
+		PyErr_Clear();
 	    return NULL;
+	}
 
 	if (!(module = call_load_module(
 			fullname,
@@ -1273,30 +1307,23 @@ find_module(char *fullname, char *tail, 
 
 	Py_DECREF(module);
 
-	module = find_module(fullname, dot + 1, newest_path);
+	find_module_result = find_module(fullname, dot + 1, newest_path);
 
 	Py_DECREF(newest_path);
 
-	return module;
+	return find_module_result;
     }
     else
     {
 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
 			"sO", tail, new_path)))
-	    return NULL;
-
-	if (!(module = call_load_module(
-			fullname,
-			(int)STRLEN(fullname),
-			find_module_result)))
 	{
-	    Py_DECREF(find_module_result);
+	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
+		PyErr_Clear();
 	    return NULL;
 	}
 
-	Py_DECREF(find_module_result);
-
-	return module;
+	return find_module_result;
     }
 }
 
@@ -1304,7 +1331,7 @@ find_module(char *fullname, char *tail, 
 FinderFindModule(PyObject *self, PyObject *args)
 {
     char	*fullname;
-    PyObject	*module;
+    PyObject	*result;
     PyObject	*new_path;
     LoaderObject	*loader;
 
@@ -1314,31 +1341,35 @@ FinderFindModule(PyObject *self, PyObjec
     if (!(new_path = Vim_GetPaths(self)))
 	return NULL;
 
-    module = find_module(fullname, fullname, new_path);
+    result = find_module(fullname, fullname, new_path);
 
     Py_DECREF(new_path);
 
-    if (!module)
+    if (!result)
     {
 	if (PyErr_Occurred())
-	{
-	    if (PyErr_ExceptionMatches(PyExc_ImportError))
-		PyErr_Clear();
-	    else
-		return NULL;
-	}
+	    return NULL;
 
 	Py_INCREF(Py_None);
 	return Py_None;
     }
 
-    if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
-    {
-	Py_DECREF(module);
+    if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
+    {
+	Py_DECREF(result);
+	PyErr_NoMemory();
 	return NULL;
     }
 
-    loader->module = module;
+    if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
+    {
+	vim_free(fullname);
+	Py_DECREF(result);
+	return NULL;
+    }
+
+    loader->fullname = fullname;
+    loader->result = result;
 
     return (PyObject *) loader;
 }
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):NotImplem
 vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
 > import
 import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
-import failing_import:ImportError:('No module named failing_import',)
+import failing_import:ImportError:()
 import failing:NotImplementedError:()
 > Options
 >> OptionsItem
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):(<class '
 vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
 > import
 import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
-import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
+import failing_import:(<class 'ImportError'>, ImportError())
 import failing:(<class 'NotImplementedError'>, NotImplementedError())
 > Options
 >> OptionsItem
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    247,
+/**/
     246,
 /**/
     245,