From f0434e647aa3e7b82a740be4a820aec951a885ac Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 20 Apr 2012 15:22:50 -0400 Subject: Issue #14599: Generalize a test for ImportError.path and add support in Python/dynload_shlibs.c. This should fix the remaining importlib test failure on Windows. Support in AIX and HP-UX will be in a separate checkin. --- Lib/test/test_imp.py | 11 +++++++++++ Lib/test/test_import.py | 22 ---------------------- Python/dynload_shlib.c | 11 ++++++++++- Python/importdl.c | 9 +++++---- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 432ca41..9fe8f43 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -179,6 +179,17 @@ class ImportTests(unittest.TestCase): self.assertRaises(SyntaxError, imp.find_module, "badsyntax_pep3120", [path]) + def test_load_dynamic_ImportError_path(self): + # Issue #1559549 added `name` and `path` attributes to ImportError + # in order to provide better detail. Issue #10854 implemented those + # attributes on import failures of extensions on Windows. + path = 'bogus file path' + name = 'extension' + with self.assertRaises(ImportError) as err: + imp.load_dynamic(name, path) + self.assertIn(path, err.exception.path) + self.assertEqual(name, err.exception.name) + class ReloadTests(unittest.TestCase): diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py index 9e7c5c0..8510eb8 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -337,28 +337,6 @@ class ImportTests(unittest.TestCase): del sys.path[0] remove_files(TESTFN) - @unittest.skipUnless(sys.platform == "win32", "Windows-specific") - def test_extension_import_fail(self): - # Issue 1559549 added `name` and `path` attributes to ImportError - # in order to provide better detail. Issue 10854 implemented those - # attributes on import failures of extensions on Windows. - debug = True if sys.executable[-6:] == "_d.exe" else False - pkg_name = "extension" - pkg_file = pkg_name + "{}".format("_d.pyd" if debug else ".pyd") - with open(pkg_file, "w"): pass - importlib.invalidate_caches() - try: - with self.assertRaises(ImportError) as err: - import extension - self.assertEqual(err.exception.name, pkg_name) - # The path we get back has the dot-slash, e.g., ".\\extension.pyd" - self.assertIsNotNone(err.exception.path, - 'unexpected None for ImportError.path: ' - '{!r}'.format(err.exception)) - self.assertEqual(os.path.relpath(err.exception.path), pkg_file) - finally: - unlink(pkg_file) - class PycRewritingTests(unittest.TestCase): # Test that the `co_filename` attribute on code objects always points diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 94c6494..565faca 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -129,10 +129,19 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, handle = dlopen(pathname, dlopenflags); if (handle == NULL) { + PyObject *mod_name = NULL; + PyObject *path = NULL; + PyObject *error_ob = NULL; const char *error = dlerror(); if (error == NULL) error = "unknown dlopen() error"; - PyErr_SetString(PyExc_ImportError, error); + error_ob = PyUnicode_FromString(error); + path = PyUnicode_FromString(pathname); + mod_name = PyUnicode_FromString(shortname); + PyErr_SetImportError(error_ob, mod_name, path); + Py_DECREF(error_ob); + Py_DECREF(path); + Py_DECREF(mod_name); return NULL; } if (fp != NULL && nhandles < 128) diff --git a/Python/importdl.c b/Python/importdl.c index 734b35f..942e4b8 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -74,10 +74,11 @@ _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp) if (PyErr_Occurred()) goto error; if (p == NULL) { - PyErr_Format(PyExc_ImportError, - "dynamic module does not define init function" - " (PyInit_%s)", - shortname); + PyObject *msg = PyUnicode_FromFormat("dynamic module does not define " + "init function (PyInit_%s)", + shortname); + PyErr_SetImportError(msg, name, path); + Py_DECREF(msg); goto error; } oldcontext = _Py_PackageContext; -- cgit v0.12