Skip to content

Commit 447bd5a

Browse files
committed
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 #3162)
1 parent ee380ae commit 447bd5a

4 files changed

Lines changed: 63 additions & 30 deletions

File tree

src/if_py_both.h

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -544,27 +544,57 @@ PythonIO_Init_io(void)
544544
}
545545

546546
#if PY_VERSION_HEX < 0x030700f0
547+
static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
548+
547549
typedef struct
548550
{
549551
PyObject_HEAD
550-
PyObject *module;
552+
char *fullname;
553+
PyObject *result;
551554
} LoaderObject;
552555
static PyTypeObject LoaderType;
553556

554557
static void
555558
LoaderDestructor(LoaderObject *self)
556559
{
557-
Py_DECREF(self->module);
560+
vim_free(self->fullname);
561+
Py_XDECREF(self->result);
558562
DESTRUCTOR_FINISH(self);
559563
}
560564

561565
static PyObject *
562566
LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
563567
{
564-
PyObject *ret = self->module;
568+
char *fullname = self->fullname;
569+
PyObject *result = self->result;
570+
PyObject *module;
565571

566-
Py_INCREF(ret);
567-
return ret;
572+
if (!fullname)
573+
{
574+
module = result ? result : Py_None;
575+
Py_INCREF(module);
576+
return module;
577+
}
578+
579+
module = call_load_module(fullname, (int)STRLEN(fullname), result);
580+
581+
self->fullname = NULL;
582+
self->result = module;
583+
584+
vim_free(fullname);
585+
Py_DECREF(result);
586+
587+
if (!module)
588+
{
589+
if (PyErr_Occurred())
590+
return NULL;
591+
592+
Py_INCREF(Py_None);
593+
return Py_None;
594+
}
595+
596+
Py_INCREF(module);
597+
return module;
568598
}
569599

570600
static struct PyMethodDef LoaderMethods[] = {
@@ -1252,7 +1282,11 @@ find_module(char *fullname, char *tail, PyObject *new_path)
12521282

12531283
if (!(find_module_result = PyObject_CallFunction(py_find_module,
12541284
"s#O", tail, partlen, new_path)))
1285+
{
1286+
if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1287+
PyErr_Clear();
12551288
return NULL;
1289+
}
12561290

12571291
if (!(module = call_load_module(
12581292
fullname,
@@ -1273,38 +1307,31 @@ find_module(char *fullname, char *tail, PyObject *new_path)
12731307

12741308
Py_DECREF(module);
12751309

1276-
module = find_module(fullname, dot + 1, newest_path);
1310+
find_module_result = find_module(fullname, dot + 1, newest_path);
12771311

12781312
Py_DECREF(newest_path);
12791313

1280-
return module;
1314+
return find_module_result;
12811315
}
12821316
else
12831317
{
12841318
if (!(find_module_result = PyObject_CallFunction(py_find_module,
12851319
"sO", tail, new_path)))
1286-
return NULL;
1287-
1288-
if (!(module = call_load_module(
1289-
fullname,
1290-
(int)STRLEN(fullname),
1291-
find_module_result)))
12921320
{
1293-
Py_DECREF(find_module_result);
1321+
if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1322+
PyErr_Clear();
12941323
return NULL;
12951324
}
12961325

1297-
Py_DECREF(find_module_result);
1298-
1299-
return module;
1326+
return find_module_result;
13001327
}
13011328
}
13021329

13031330
static PyObject *
13041331
FinderFindModule(PyObject *self, PyObject *args)
13051332
{
13061333
char *fullname;
1307-
PyObject *module;
1334+
PyObject *result;
13081335
PyObject *new_path;
13091336
LoaderObject *loader;
13101337

@@ -1314,31 +1341,35 @@ FinderFindModule(PyObject *self, PyObject *args)
13141341
if (!(new_path = Vim_GetPaths(self)))
13151342
return NULL;
13161343

1317-
module = find_module(fullname, fullname, new_path);
1344+
result = find_module(fullname, fullname, new_path);
13181345

13191346
Py_DECREF(new_path);
13201347

1321-
if (!module)
1348+
if (!result)
13221349
{
13231350
if (PyErr_Occurred())
1324-
{
1325-
if (PyErr_ExceptionMatches(PyExc_ImportError))
1326-
PyErr_Clear();
1327-
else
1328-
return NULL;
1329-
}
1351+
return NULL;
13301352

13311353
Py_INCREF(Py_None);
13321354
return Py_None;
13331355
}
13341356

1357+
if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
1358+
{
1359+
Py_DECREF(result);
1360+
PyErr_NoMemory();
1361+
return NULL;
1362+
}
1363+
13351364
if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
13361365
{
1337-
Py_DECREF(module);
1366+
vim_free(fullname);
1367+
Py_DECREF(result);
13381368
return NULL;
13391369
}
13401370

1341-
loader->module = module;
1371+
loader->fullname = fullname;
1372+
loader->result = result;
13421373

13431374
return (PyObject *) loader;
13441375
}

src/testdir/test86.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):NotImplementedError:('call',)
701701
vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
702702
> import
703703
import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
704-
import failing_import:ImportError:('No module named failing_import',)
704+
import failing_import:ImportError:()
705705
import failing:NotImplementedError:()
706706
> Options
707707
>> OptionsItem

src/testdir/test87.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedErr
701701
vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
702702
> import
703703
import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
704-
import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
704+
import failing_import:(<class 'ImportError'>, ImportError())
705705
import failing:(<class 'NotImplementedError'>, NotImplementedError())
706706
> Options
707707
>> OptionsItem

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,8 @@ static char *(features[]) =
794794

795795
static int included_patches[] =
796796
{ /* Add new patch number below this line */
797+
/**/
798+
247,
797799
/**/
798800
246,
799801
/**/

0 commit comments

Comments
 (0)