diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -758,7 +758,7 @@ class _ImportLockContext: _IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder] -_ERR_MSG = 'No module named {}' +_ERR_MSG = 'No module named {!r}' def _gcd_import(name, package=None, level=0): """Import and return the module based on its name, the package the call is diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -186,8 +186,8 @@ class ModuleFinder: if q: self.msgout(4, "find_head_package ->", (q, tail)) return q, tail - self.msgout(4, "raise ImportError: No module named", qname) - raise ImportError("No module named " + qname) + self.msgout(4, "raise ImportError: No module named %r" % qname) + raise ImportError("No module named %r" % qname) def load_tail(self, q, tail): self.msgin(4, "load_tail", q, tail) @@ -199,8 +199,8 @@ class ModuleFinder: mname = "%s.%s" % (m.__name__, head) m = self.import_module(head, mname, m) if not m: - self.msgout(4, "raise ImportError: No module named", mname) - raise ImportError("No module named " + mname) + self.msgout(4, "raise ImportError: No module named %r" % mname) + raise ImportError("No module named %r" % mname) self.msgout(4, "load_tail ->", m) return m @@ -216,7 +216,7 @@ class ModuleFinder: subname = "%s.%s" % (m.__name__, sub) submod = self.import_module(sub, subname, m) if not submod: - raise ImportError("No module named " + subname) + raise ImportError("No module named %r" % subname) def find_all_submodules(self, m): if not m.__path__: diff --git a/Lib/runpy.py b/Lib/runpy.py --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -101,19 +101,19 @@ def _get_filename(loader, mod_name): def _get_module_details(mod_name): loader = get_loader(mod_name) if loader is None: - raise ImportError("No module named %s" % mod_name) + raise ImportError("No module named %r" % mod_name) if loader.is_package(mod_name): if mod_name == "__main__" or mod_name.endswith(".__main__"): - raise ImportError("Cannot use package as __main__ module") + raise ImportError("Cannot use package as '__main__' module") try: pkg_main_name = mod_name + ".__main__" return _get_module_details(pkg_main_name) except ImportError as e: raise ImportError(("%s; %r is a package and cannot " + - "be directly executed") %(e, mod_name)) + "be directly executed") % (e, mod_name)) code = loader.get_code(mod_name) if code is None: - raise ImportError("No code object available for %s" % mod_name) + raise ImportError("No code object available for %r" % mod_name) filename = _get_filename(loader, mod_name) return mod_name, loader, code, filename diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -226,7 +226,7 @@ class CmdLineTest(unittest.TestCase): make_pkg(pkg_dir) main_dir = os.path.join(pkg_dir, '__main__') make_pkg(main_dir) - msg = ("Cannot use package as __main__ module; " + msg = ("Cannot use package as '__main__' module; " "'test_pkg' is a package and cannot " "be directly executed") launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -5,8 +5,8 @@ test.support.import_module('_multiproces # Skip tests if sem_open implementation is broken. test.support.import_module('multiprocessing.synchronize') # import threading after _multiprocessing to raise a more revelant error -# message: "No module named _multiprocessing". _multiprocessing is not compiled -# without thread support. +# message: "No module named '_multiprocessing'". _multiprocessing is not +# compiled without thread support. test.support.import_module('threading') import io diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -24,8 +24,8 @@ _multiprocessing = test.support.import_m # Skip tests if sem_open implementation is broken. test.support.import_module('multiprocessing.synchronize') # import threading after _multiprocessing to raise a more revelant error -# message: "No module named _multiprocessing". _multiprocessing is not compiled -# without thread support. +# message: "No module named '_multiprocessing'". _multiprocessing is not +# compiled without thread support. import threading import multiprocessing.dummy diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -187,7 +187,7 @@ war missing_pattern = "no Python documentation found for '%s'" # output pattern for module with bad imports -badimport_pattern = "problem in %s - ImportError: No module named %s" +badimport_pattern = "problem in %s - ImportError: No module named %r" def run_pydoc(module_name, *args): """ diff --git a/Lib/unittest/test/test_loader.py b/Lib/unittest/test/test_loader.py --- a/Lib/unittest/test/test_loader.py +++ b/Lib/unittest/test/test_loader.py @@ -239,7 +239,7 @@ class Test_TestLoader(unittest.TestCase) try: loader.loadTestsFromName('sdasfasfasdf') except ImportError as e: - self.assertEqual(str(e), "No module named sdasfasfasdf") + self.assertEqual(str(e), "No module named 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromName failed to raise ImportError") @@ -619,7 +619,7 @@ class Test_TestLoader(unittest.TestCase) try: loader.loadTestsFromNames(['sdasfasfasdf']) except ImportError as e: - self.assertEqual(str(e), "No module named sdasfasfasdf") + self.assertEqual(str(e), "No module named 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromNames failed to raise ImportError") diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1489,7 +1489,7 @@ class XMLParser: import pyexpat as expat except ImportError: raise ImportError( - "No module named expat; use SimpleXMLTreeBuilder instead" + "No module named 'expat'; use SimpleXMLTreeBuilder instead" ) parser = expat.ParserCreate(encoding, "}") if target is None: diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -1559,7 +1559,7 @@ find_module(char *fullname, char *subnam struct filedescr *fdp = NULL; char *filemode; FILE *fp = NULL; - PyObject *path_hooks, *path_importer_cache; + PyObject *path_hooks, *path_importer_cache, *name_u, *name_r; struct stat statbuf; static struct filedescr fd_frozen = {"", "", PY_FROZEN}; static struct filedescr fd_builtin = {"", "", C_BUILTIN}; @@ -1817,8 +1817,14 @@ find_module(char *fullname, char *subnam break; } if (fp == NULL) { + name_u = PyUnicode_FromString(name); + if (name_u == NULL) + return 0; + name_r = PyObject_Repr(name_u); + if (name_r == NULL) + return 0; PyErr_Format(PyExc_ImportError, - "No module named %.200s", name); + "No module named %.200s", name_r); return NULL; } *p_fp = fp; @@ -2662,7 +2668,7 @@ load_next(PyObject *mod, PyObject *altmo char *dot = strchr(name, '.'); size_t len; char *p; - PyObject *result; + PyObject *result, *name_u, *name_r; if (strlen(name) == 0) { /* completely empty module name should only happen in @@ -2718,8 +2724,14 @@ load_next(PyObject *mod, PyObject *altmo if (result == Py_None) { Py_DECREF(result); + name_u = PyUnicode_FromString(name); + if (name_u == NULL) + return 0; + name_r = PyObject_Repr(name_u); + if (name_r == NULL) + return 0; PyErr_Format(PyExc_ImportError, - "No module named %.200s", name); + "No module named %.200s", name_r); return NULL; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -412,7 +412,7 @@ Py_Finalize(void) * XXX longer believes it's initialized. * XXX Fatal Python error: Interpreter not initialized (version mismatch?) * XXX is easy to provoke that way. I've also seen, e.g., - * XXX Exception exceptions.ImportError: 'No module named sha' + * XXX Exception exceptions.ImportError: "No module named 'sha'" * XXX in ignored * XXX but I'm unclear on exactly how that one happens. In any case, * XXX I haven't seen a real-life report of either of these.