(mod_name, error=ImportError)
| 103 | |
| 104 | # Helper to get the full name, spec and code for a module |
| 105 | def _get_module_details(mod_name, error=ImportError): |
| 106 | if mod_name.startswith("."): |
| 107 | raise error("Relative module names not supported") |
| 108 | pkg_name, _, _ = mod_name.rpartition(".") |
| 109 | if pkg_name: |
| 110 | # Try importing the parent to avoid catching initialization errors |
| 111 | try: |
| 112 | __import__(pkg_name) |
| 113 | except ImportError as e: |
| 114 | # If the parent or higher ancestor package is missing, let the |
| 115 | # error be raised by find_spec() below and then be caught. But do |
| 116 | # not allow other errors to be caught. |
| 117 | if e.name is None or (e.name != pkg_name and |
| 118 | not pkg_name.startswith(e.name + ".")): |
| 119 | raise |
| 120 | # Warn if the module has already been imported under its normal name |
| 121 | existing = sys.modules.get(mod_name) |
| 122 | if existing is not None and not hasattr(existing, "__path__"): |
| 123 | from warnings import warn |
| 124 | msg = "{mod_name!r} found in sys.modules after import of " \ |
| 125 | "package {pkg_name!r}, but prior to execution of " \ |
| 126 | "{mod_name!r}; this may result in unpredictable " \ |
| 127 | "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) |
| 128 | warn(RuntimeWarning(msg)) |
| 129 | |
| 130 | try: |
| 131 | spec = importlib.util.find_spec(mod_name) |
| 132 | except (ImportError, AttributeError, TypeError, ValueError) as ex: |
| 133 | # This hack fixes an impedance mismatch between pkgutil and |
| 134 | # importlib, where the latter raises other errors for cases where |
| 135 | # pkgutil previously raised ImportError |
| 136 | msg = "Error while finding module specification for {!r} ({}: {})" |
| 137 | if mod_name.endswith(".py"): |
| 138 | msg += (f". Try using '{mod_name[:-3]}' instead of " |
| 139 | f"'{mod_name}' as the module name.") |
| 140 | raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex |
| 141 | if spec is None: |
| 142 | raise error("No module named %s" % mod_name) |
| 143 | if spec.submodule_search_locations is not None: |
| 144 | if mod_name == "__main__" or mod_name.endswith(".__main__"): |
| 145 | raise error("Cannot use package as __main__ module") |
| 146 | try: |
| 147 | pkg_main_name = mod_name + ".__main__" |
| 148 | return _get_module_details(pkg_main_name, error) |
| 149 | except error as e: |
| 150 | if mod_name not in sys.modules: |
| 151 | raise # No module loaded; being a package is irrelevant |
| 152 | raise error(("%s; %r is a package and cannot " + |
| 153 | "be directly executed") %(e, mod_name)) |
| 154 | loader = spec.loader |
| 155 | if loader is None: |
| 156 | raise error("%r is a namespace package and cannot be executed" |
| 157 | % mod_name) |
| 158 | try: |
| 159 | code = loader.get_code(mod_name) |
| 160 | except ImportError as e: |
| 161 | raise error(format(e)) from e |
| 162 | if code is None: |
no test coverage detected