(mod_name, error=ImportError)
| 132 | |
| 133 | # Helper to get the full name, spec and code for a module |
| 134 | def _get_module_details(mod_name, error=ImportError): |
| 135 | if mod_name.startswith("."): |
| 136 | raise error("Relative module names not supported") |
| 137 | pkg_name, _, _ = mod_name.rpartition(".") |
| 138 | if pkg_name: |
| 139 | # Try importing the parent to avoid catching initialization errors |
| 140 | try: |
| 141 | __import__(pkg_name) |
| 142 | except ImportError as e: |
| 143 | # If the parent or higher ancestor package is missing, let the |
| 144 | # error be raised by find_spec() below and then be caught. But do |
| 145 | # not allow other errors to be caught. |
| 146 | if e.name is None or (e.name != pkg_name and not pkg_name.startswith(e.name + ".")): |
| 147 | raise |
| 148 | # Warn if the module has already been imported under its normal name |
| 149 | existing = sys.modules.get(mod_name) |
| 150 | if existing is not None and not hasattr(existing, "__path__"): |
| 151 | from warnings import warn |
| 152 | |
| 153 | msg = ( |
| 154 | "{mod_name!r} found in sys.modules after import of " |
| 155 | "package {pkg_name!r}, but prior to execution of " |
| 156 | "{mod_name!r}; this may result in unpredictable " |
| 157 | "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) |
| 158 | ) |
| 159 | warn(RuntimeWarning(msg)) |
| 160 | |
| 161 | try: |
| 162 | spec = importlib.util.find_spec(mod_name) |
| 163 | except (ImportError, AttributeError, TypeError, ValueError) as ex: |
| 164 | # This hack fixes an impedance mismatch between pkgutil and |
| 165 | # importlib, where the latter raises other errors for cases where |
| 166 | # pkgutil previously raised ImportError |
| 167 | msg = "Error while finding module specification for {!r} ({}: {})" |
| 168 | if mod_name.endswith(".py"): |
| 169 | msg += f". Try using '{mod_name[:-3]}' instead of '{mod_name}' as the module name." |
| 170 | raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex |
| 171 | if spec is None: |
| 172 | raise error("No module named %s" % mod_name) |
| 173 | if spec.submodule_search_locations is not None: |
| 174 | if mod_name == "__main__" or mod_name.endswith(".__main__"): |
| 175 | raise error("Cannot use package as __main__ module") |
| 176 | try: |
| 177 | pkg_main_name = mod_name + ".__main__" |
| 178 | return _get_module_details(pkg_main_name, error) |
| 179 | except error as e: |
| 180 | if mod_name not in sys.modules: |
| 181 | raise # No module loaded; being a package is irrelevant |
| 182 | raise error(("%s; %r is a package and cannot " + "be directly executed") % (e, mod_name)) |
| 183 | loader = spec.loader |
| 184 | if loader is None: |
| 185 | raise error("%r is a namespace package and cannot be executed" % mod_name) |
| 186 | try: |
| 187 | code = loader.get_code(mod_name) |
| 188 | except ImportError as e: |
| 189 | raise error(format(e)) from e |
| 190 | if code is None: |
| 191 | raise error("No code object available for %s" % mod_name) |
no test coverage detected