Index: Lib/unittest/loader.py =================================================================== --- Lib/unittest/loader.py (revision 79608) +++ Lib/unittest/loader.py (working copy) @@ -84,6 +84,31 @@ self.suiteClass) return tests + # The stack-walking code of this method was taken from-- + # + # http://twistedmatrix.com/trac/browser/trunk/twisted/python/reflect.py#L382 + def _importWithExceptionCheck(self, module_name, module_not_found): + """Import the given module while checking for a module not found. + + The module_not_found parameter should be an empty list. If this + method raises an exception due to a module not found, then the + method adds an element to module_not_found so it evaluates True. + This allows the original exception to bubble up untouched. + + """ + try: + return __import__(module_name) + except ImportError, err: + excType, excValue, excTraceback = sys.exc_info() + while excTraceback: + execName = excTraceback.tb_frame.f_globals["__name__"] + if (execName is None or # python 2.4+, post-cleanup + execName == module_name): # python 2.3, no cleanup + raise excType, excValue, excTraceback + excTraceback = excTraceback.tb_next + module_not_found.append(1) + raise excType, excValue, excTraceback + def loadTestsFromName(self, name, module=None): """Return a suite of all tests cases given a string specifier. @@ -98,11 +123,14 @@ parts_copy = parts[:] while parts_copy: try: - module = __import__('.'.join(parts_copy)) + import_name = '.'.join(parts_copy) + module_not_found = [] + module = self._importWithExceptionCheck(import_name, + module_not_found) break except ImportError: del parts_copy[-1] - if not parts_copy: + if not parts_copy or not module_not_found: raise parts = parts[1:] obj = module