1*cda5da8dSAndroid Build Coastguard Worker"""runpy.py - locating and running Python code using the module namespace 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerProvides support for locating and running Python scripts using the Python 4*cda5da8dSAndroid Build Coastguard Workermodule namespace instead of the native filesystem. 5*cda5da8dSAndroid Build Coastguard Worker 6*cda5da8dSAndroid Build Coastguard WorkerThis allows Python code to play nicely with non-filesystem based PEP 302 7*cda5da8dSAndroid Build Coastguard Workerimporters when locating support scripts as well as when importing modules. 8*cda5da8dSAndroid Build Coastguard Worker""" 9*cda5da8dSAndroid Build Coastguard Worker# Written by Nick Coghlan <ncoghlan at gmail.com> 10*cda5da8dSAndroid Build Coastguard Worker# to implement PEP 338 (Executing Modules as Scripts) 11*cda5da8dSAndroid Build Coastguard Worker 12*cda5da8dSAndroid Build Coastguard Worker 13*cda5da8dSAndroid Build Coastguard Workerimport sys 14*cda5da8dSAndroid Build Coastguard Workerimport importlib.machinery # importlib first so we can test #15386 via -m 15*cda5da8dSAndroid Build Coastguard Workerimport importlib.util 16*cda5da8dSAndroid Build Coastguard Workerimport io 17*cda5da8dSAndroid Build Coastguard Workerimport os 18*cda5da8dSAndroid Build Coastguard Worker 19*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 20*cda5da8dSAndroid Build Coastguard Worker "run_module", "run_path", 21*cda5da8dSAndroid Build Coastguard Worker] 22*cda5da8dSAndroid Build Coastguard Worker 23*cda5da8dSAndroid Build Coastguard Worker# avoid 'import types' just for ModuleType 24*cda5da8dSAndroid Build Coastguard WorkerModuleType = type(sys) 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Workerclass _TempModule(object): 27*cda5da8dSAndroid Build Coastguard Worker """Temporarily replace a module in sys.modules with an empty namespace""" 28*cda5da8dSAndroid Build Coastguard Worker def __init__(self, mod_name): 29*cda5da8dSAndroid Build Coastguard Worker self.mod_name = mod_name 30*cda5da8dSAndroid Build Coastguard Worker self.module = ModuleType(mod_name) 31*cda5da8dSAndroid Build Coastguard Worker self._saved_module = [] 32*cda5da8dSAndroid Build Coastguard Worker 33*cda5da8dSAndroid Build Coastguard Worker def __enter__(self): 34*cda5da8dSAndroid Build Coastguard Worker mod_name = self.mod_name 35*cda5da8dSAndroid Build Coastguard Worker try: 36*cda5da8dSAndroid Build Coastguard Worker self._saved_module.append(sys.modules[mod_name]) 37*cda5da8dSAndroid Build Coastguard Worker except KeyError: 38*cda5da8dSAndroid Build Coastguard Worker pass 39*cda5da8dSAndroid Build Coastguard Worker sys.modules[mod_name] = self.module 40*cda5da8dSAndroid Build Coastguard Worker return self 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, *args): 43*cda5da8dSAndroid Build Coastguard Worker if self._saved_module: 44*cda5da8dSAndroid Build Coastguard Worker sys.modules[self.mod_name] = self._saved_module[0] 45*cda5da8dSAndroid Build Coastguard Worker else: 46*cda5da8dSAndroid Build Coastguard Worker del sys.modules[self.mod_name] 47*cda5da8dSAndroid Build Coastguard Worker self._saved_module = [] 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Workerclass _ModifiedArgv0(object): 50*cda5da8dSAndroid Build Coastguard Worker def __init__(self, value): 51*cda5da8dSAndroid Build Coastguard Worker self.value = value 52*cda5da8dSAndroid Build Coastguard Worker self._saved_value = self._sentinel = object() 53*cda5da8dSAndroid Build Coastguard Worker 54*cda5da8dSAndroid Build Coastguard Worker def __enter__(self): 55*cda5da8dSAndroid Build Coastguard Worker if self._saved_value is not self._sentinel: 56*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("Already preserving saved value") 57*cda5da8dSAndroid Build Coastguard Worker self._saved_value = sys.argv[0] 58*cda5da8dSAndroid Build Coastguard Worker sys.argv[0] = self.value 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, *args): 61*cda5da8dSAndroid Build Coastguard Worker self.value = self._sentinel 62*cda5da8dSAndroid Build Coastguard Worker sys.argv[0] = self._saved_value 63*cda5da8dSAndroid Build Coastguard Worker 64*cda5da8dSAndroid Build Coastguard Worker# TODO: Replace these helpers with importlib._bootstrap_external functions. 65*cda5da8dSAndroid Build Coastguard Workerdef _run_code(code, run_globals, init_globals=None, 66*cda5da8dSAndroid Build Coastguard Worker mod_name=None, mod_spec=None, 67*cda5da8dSAndroid Build Coastguard Worker pkg_name=None, script_name=None): 68*cda5da8dSAndroid Build Coastguard Worker """Helper to run code in nominated namespace""" 69*cda5da8dSAndroid Build Coastguard Worker if init_globals is not None: 70*cda5da8dSAndroid Build Coastguard Worker run_globals.update(init_globals) 71*cda5da8dSAndroid Build Coastguard Worker if mod_spec is None: 72*cda5da8dSAndroid Build Coastguard Worker loader = None 73*cda5da8dSAndroid Build Coastguard Worker fname = script_name 74*cda5da8dSAndroid Build Coastguard Worker cached = None 75*cda5da8dSAndroid Build Coastguard Worker else: 76*cda5da8dSAndroid Build Coastguard Worker loader = mod_spec.loader 77*cda5da8dSAndroid Build Coastguard Worker fname = mod_spec.origin 78*cda5da8dSAndroid Build Coastguard Worker cached = mod_spec.cached 79*cda5da8dSAndroid Build Coastguard Worker if pkg_name is None: 80*cda5da8dSAndroid Build Coastguard Worker pkg_name = mod_spec.parent 81*cda5da8dSAndroid Build Coastguard Worker run_globals.update(__name__ = mod_name, 82*cda5da8dSAndroid Build Coastguard Worker __file__ = fname, 83*cda5da8dSAndroid Build Coastguard Worker __cached__ = cached, 84*cda5da8dSAndroid Build Coastguard Worker __doc__ = None, 85*cda5da8dSAndroid Build Coastguard Worker __loader__ = loader, 86*cda5da8dSAndroid Build Coastguard Worker __package__ = pkg_name, 87*cda5da8dSAndroid Build Coastguard Worker __spec__ = mod_spec) 88*cda5da8dSAndroid Build Coastguard Worker exec(code, run_globals) 89*cda5da8dSAndroid Build Coastguard Worker return run_globals 90*cda5da8dSAndroid Build Coastguard Worker 91*cda5da8dSAndroid Build Coastguard Workerdef _run_module_code(code, init_globals=None, 92*cda5da8dSAndroid Build Coastguard Worker mod_name=None, mod_spec=None, 93*cda5da8dSAndroid Build Coastguard Worker pkg_name=None, script_name=None): 94*cda5da8dSAndroid Build Coastguard Worker """Helper to run code in new namespace with sys modified""" 95*cda5da8dSAndroid Build Coastguard Worker fname = script_name if mod_spec is None else mod_spec.origin 96*cda5da8dSAndroid Build Coastguard Worker with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): 97*cda5da8dSAndroid Build Coastguard Worker mod_globals = temp_module.module.__dict__ 98*cda5da8dSAndroid Build Coastguard Worker _run_code(code, mod_globals, init_globals, 99*cda5da8dSAndroid Build Coastguard Worker mod_name, mod_spec, pkg_name, script_name) 100*cda5da8dSAndroid Build Coastguard Worker # Copy the globals of the temporary module, as they 101*cda5da8dSAndroid Build Coastguard Worker # may be cleared when the temporary module goes away 102*cda5da8dSAndroid Build Coastguard Worker return mod_globals.copy() 103*cda5da8dSAndroid Build Coastguard Worker 104*cda5da8dSAndroid Build Coastguard Worker# Helper to get the full name, spec and code for a module 105*cda5da8dSAndroid Build Coastguard Workerdef _get_module_details(mod_name, error=ImportError): 106*cda5da8dSAndroid Build Coastguard Worker if mod_name.startswith("."): 107*cda5da8dSAndroid Build Coastguard Worker raise error("Relative module names not supported") 108*cda5da8dSAndroid Build Coastguard Worker pkg_name, _, _ = mod_name.rpartition(".") 109*cda5da8dSAndroid Build Coastguard Worker if pkg_name: 110*cda5da8dSAndroid Build Coastguard Worker # Try importing the parent to avoid catching initialization errors 111*cda5da8dSAndroid Build Coastguard Worker try: 112*cda5da8dSAndroid Build Coastguard Worker __import__(pkg_name) 113*cda5da8dSAndroid Build Coastguard Worker except ImportError as e: 114*cda5da8dSAndroid Build Coastguard Worker # If the parent or higher ancestor package is missing, let the 115*cda5da8dSAndroid Build Coastguard Worker # error be raised by find_spec() below and then be caught. But do 116*cda5da8dSAndroid Build Coastguard Worker # not allow other errors to be caught. 117*cda5da8dSAndroid Build Coastguard Worker if e.name is None or (e.name != pkg_name and 118*cda5da8dSAndroid Build Coastguard Worker not pkg_name.startswith(e.name + ".")): 119*cda5da8dSAndroid Build Coastguard Worker raise 120*cda5da8dSAndroid Build Coastguard Worker # Warn if the module has already been imported under its normal name 121*cda5da8dSAndroid Build Coastguard Worker existing = sys.modules.get(mod_name) 122*cda5da8dSAndroid Build Coastguard Worker if existing is not None and not hasattr(existing, "__path__"): 123*cda5da8dSAndroid Build Coastguard Worker from warnings import warn 124*cda5da8dSAndroid Build Coastguard Worker msg = "{mod_name!r} found in sys.modules after import of " \ 125*cda5da8dSAndroid Build Coastguard Worker "package {pkg_name!r}, but prior to execution of " \ 126*cda5da8dSAndroid Build Coastguard Worker "{mod_name!r}; this may result in unpredictable " \ 127*cda5da8dSAndroid Build Coastguard Worker "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) 128*cda5da8dSAndroid Build Coastguard Worker warn(RuntimeWarning(msg)) 129*cda5da8dSAndroid Build Coastguard Worker 130*cda5da8dSAndroid Build Coastguard Worker try: 131*cda5da8dSAndroid Build Coastguard Worker spec = importlib.util.find_spec(mod_name) 132*cda5da8dSAndroid Build Coastguard Worker except (ImportError, AttributeError, TypeError, ValueError) as ex: 133*cda5da8dSAndroid Build Coastguard Worker # This hack fixes an impedance mismatch between pkgutil and 134*cda5da8dSAndroid Build Coastguard Worker # importlib, where the latter raises other errors for cases where 135*cda5da8dSAndroid Build Coastguard Worker # pkgutil previously raised ImportError 136*cda5da8dSAndroid Build Coastguard Worker msg = "Error while finding module specification for {!r} ({}: {})" 137*cda5da8dSAndroid Build Coastguard Worker if mod_name.endswith(".py"): 138*cda5da8dSAndroid Build Coastguard Worker msg += (f". Try using '{mod_name[:-3]}' instead of " 139*cda5da8dSAndroid Build Coastguard Worker f"'{mod_name}' as the module name.") 140*cda5da8dSAndroid Build Coastguard Worker raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex 141*cda5da8dSAndroid Build Coastguard Worker if spec is None: 142*cda5da8dSAndroid Build Coastguard Worker raise error("No module named %s" % mod_name) 143*cda5da8dSAndroid Build Coastguard Worker if spec.submodule_search_locations is not None: 144*cda5da8dSAndroid Build Coastguard Worker if mod_name == "__main__" or mod_name.endswith(".__main__"): 145*cda5da8dSAndroid Build Coastguard Worker raise error("Cannot use package as __main__ module") 146*cda5da8dSAndroid Build Coastguard Worker try: 147*cda5da8dSAndroid Build Coastguard Worker pkg_main_name = mod_name + ".__main__" 148*cda5da8dSAndroid Build Coastguard Worker return _get_module_details(pkg_main_name, error) 149*cda5da8dSAndroid Build Coastguard Worker except error as e: 150*cda5da8dSAndroid Build Coastguard Worker if mod_name not in sys.modules: 151*cda5da8dSAndroid Build Coastguard Worker raise # No module loaded; being a package is irrelevant 152*cda5da8dSAndroid Build Coastguard Worker raise error(("%s; %r is a package and cannot " + 153*cda5da8dSAndroid Build Coastguard Worker "be directly executed") %(e, mod_name)) 154*cda5da8dSAndroid Build Coastguard Worker loader = spec.loader 155*cda5da8dSAndroid Build Coastguard Worker if loader is None: 156*cda5da8dSAndroid Build Coastguard Worker raise error("%r is a namespace package and cannot be executed" 157*cda5da8dSAndroid Build Coastguard Worker % mod_name) 158*cda5da8dSAndroid Build Coastguard Worker try: 159*cda5da8dSAndroid Build Coastguard Worker code = loader.get_code(mod_name) 160*cda5da8dSAndroid Build Coastguard Worker except ImportError as e: 161*cda5da8dSAndroid Build Coastguard Worker raise error(format(e)) from e 162*cda5da8dSAndroid Build Coastguard Worker if code is None: 163*cda5da8dSAndroid Build Coastguard Worker raise error("No code object available for %s" % mod_name) 164*cda5da8dSAndroid Build Coastguard Worker return mod_name, spec, code 165*cda5da8dSAndroid Build Coastguard Worker 166*cda5da8dSAndroid Build Coastguard Workerclass _Error(Exception): 167*cda5da8dSAndroid Build Coastguard Worker """Error that _run_module_as_main() should report without a traceback""" 168*cda5da8dSAndroid Build Coastguard Worker 169*cda5da8dSAndroid Build Coastguard Worker# XXX ncoghlan: Should this be documented and made public? 170*cda5da8dSAndroid Build Coastguard Worker# (Current thoughts: don't repeat the mistake that lead to its 171*cda5da8dSAndroid Build Coastguard Worker# creation when run_module() no longer met the needs of 172*cda5da8dSAndroid Build Coastguard Worker# mainmodule.c, but couldn't be changed because it was public) 173*cda5da8dSAndroid Build Coastguard Workerdef _run_module_as_main(mod_name, alter_argv=True): 174*cda5da8dSAndroid Build Coastguard Worker """Runs the designated module in the __main__ namespace 175*cda5da8dSAndroid Build Coastguard Worker 176*cda5da8dSAndroid Build Coastguard Worker Note that the executed module will have full access to the 177*cda5da8dSAndroid Build Coastguard Worker __main__ namespace. If this is not desirable, the run_module() 178*cda5da8dSAndroid Build Coastguard Worker function should be used to run the module code in a fresh namespace. 179*cda5da8dSAndroid Build Coastguard Worker 180*cda5da8dSAndroid Build Coastguard Worker At the very least, these variables in __main__ will be overwritten: 181*cda5da8dSAndroid Build Coastguard Worker __name__ 182*cda5da8dSAndroid Build Coastguard Worker __file__ 183*cda5da8dSAndroid Build Coastguard Worker __cached__ 184*cda5da8dSAndroid Build Coastguard Worker __loader__ 185*cda5da8dSAndroid Build Coastguard Worker __package__ 186*cda5da8dSAndroid Build Coastguard Worker """ 187*cda5da8dSAndroid Build Coastguard Worker try: 188*cda5da8dSAndroid Build Coastguard Worker if alter_argv or mod_name != "__main__": # i.e. -m switch 189*cda5da8dSAndroid Build Coastguard Worker mod_name, mod_spec, code = _get_module_details(mod_name, _Error) 190*cda5da8dSAndroid Build Coastguard Worker else: # i.e. directory or zipfile execution 191*cda5da8dSAndroid Build Coastguard Worker mod_name, mod_spec, code = _get_main_module_details(_Error) 192*cda5da8dSAndroid Build Coastguard Worker except _Error as exc: 193*cda5da8dSAndroid Build Coastguard Worker msg = "%s: %s" % (sys.executable, exc) 194*cda5da8dSAndroid Build Coastguard Worker sys.exit(msg) 195*cda5da8dSAndroid Build Coastguard Worker main_globals = sys.modules["__main__"].__dict__ 196*cda5da8dSAndroid Build Coastguard Worker if alter_argv: 197*cda5da8dSAndroid Build Coastguard Worker sys.argv[0] = mod_spec.origin 198*cda5da8dSAndroid Build Coastguard Worker return _run_code(code, main_globals, None, 199*cda5da8dSAndroid Build Coastguard Worker "__main__", mod_spec) 200*cda5da8dSAndroid Build Coastguard Worker 201*cda5da8dSAndroid Build Coastguard Workerdef run_module(mod_name, init_globals=None, 202*cda5da8dSAndroid Build Coastguard Worker run_name=None, alter_sys=False): 203*cda5da8dSAndroid Build Coastguard Worker """Execute a module's code without importing it. 204*cda5da8dSAndroid Build Coastguard Worker 205*cda5da8dSAndroid Build Coastguard Worker mod_name -- an absolute module name or package name. 206*cda5da8dSAndroid Build Coastguard Worker 207*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 208*cda5da8dSAndroid Build Coastguard Worker init_globals -- dictionary used to pre-populate the module’s 209*cda5da8dSAndroid Build Coastguard Worker globals dictionary before the code is executed. 210*cda5da8dSAndroid Build Coastguard Worker 211*cda5da8dSAndroid Build Coastguard Worker run_name -- if not None, this will be used for setting __name__; 212*cda5da8dSAndroid Build Coastguard Worker otherwise, __name__ will be set to mod_name + '__main__' if the 213*cda5da8dSAndroid Build Coastguard Worker named module is a package and to just mod_name otherwise. 214*cda5da8dSAndroid Build Coastguard Worker 215*cda5da8dSAndroid Build Coastguard Worker alter_sys -- if True, sys.argv[0] is updated with the value of 216*cda5da8dSAndroid Build Coastguard Worker __file__ and sys.modules[__name__] is updated with a temporary 217*cda5da8dSAndroid Build Coastguard Worker module object for the module being executed. Both are 218*cda5da8dSAndroid Build Coastguard Worker restored to their original values before the function returns. 219*cda5da8dSAndroid Build Coastguard Worker 220*cda5da8dSAndroid Build Coastguard Worker Returns the resulting module globals dictionary. 221*cda5da8dSAndroid Build Coastguard Worker """ 222*cda5da8dSAndroid Build Coastguard Worker mod_name, mod_spec, code = _get_module_details(mod_name) 223*cda5da8dSAndroid Build Coastguard Worker if run_name is None: 224*cda5da8dSAndroid Build Coastguard Worker run_name = mod_name 225*cda5da8dSAndroid Build Coastguard Worker if alter_sys: 226*cda5da8dSAndroid Build Coastguard Worker return _run_module_code(code, init_globals, run_name, mod_spec) 227*cda5da8dSAndroid Build Coastguard Worker else: 228*cda5da8dSAndroid Build Coastguard Worker # Leave the sys module alone 229*cda5da8dSAndroid Build Coastguard Worker return _run_code(code, {}, init_globals, run_name, mod_spec) 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Workerdef _get_main_module_details(error=ImportError): 232*cda5da8dSAndroid Build Coastguard Worker # Helper that gives a nicer error message when attempting to 233*cda5da8dSAndroid Build Coastguard Worker # execute a zipfile or directory by invoking __main__.py 234*cda5da8dSAndroid Build Coastguard Worker # Also moves the standard __main__ out of the way so that the 235*cda5da8dSAndroid Build Coastguard Worker # preexisting __loader__ entry doesn't cause issues 236*cda5da8dSAndroid Build Coastguard Worker main_name = "__main__" 237*cda5da8dSAndroid Build Coastguard Worker saved_main = sys.modules[main_name] 238*cda5da8dSAndroid Build Coastguard Worker del sys.modules[main_name] 239*cda5da8dSAndroid Build Coastguard Worker try: 240*cda5da8dSAndroid Build Coastguard Worker return _get_module_details(main_name) 241*cda5da8dSAndroid Build Coastguard Worker except ImportError as exc: 242*cda5da8dSAndroid Build Coastguard Worker if main_name in str(exc): 243*cda5da8dSAndroid Build Coastguard Worker raise error("can't find %r module in %r" % 244*cda5da8dSAndroid Build Coastguard Worker (main_name, sys.path[0])) from exc 245*cda5da8dSAndroid Build Coastguard Worker raise 246*cda5da8dSAndroid Build Coastguard Worker finally: 247*cda5da8dSAndroid Build Coastguard Worker sys.modules[main_name] = saved_main 248*cda5da8dSAndroid Build Coastguard Worker 249*cda5da8dSAndroid Build Coastguard Worker 250*cda5da8dSAndroid Build Coastguard Workerdef _get_code_from_file(run_name, fname): 251*cda5da8dSAndroid Build Coastguard Worker # Check for a compiled file first 252*cda5da8dSAndroid Build Coastguard Worker from pkgutil import read_code 253*cda5da8dSAndroid Build Coastguard Worker decoded_path = os.path.abspath(os.fsdecode(fname)) 254*cda5da8dSAndroid Build Coastguard Worker with io.open_code(decoded_path) as f: 255*cda5da8dSAndroid Build Coastguard Worker code = read_code(f) 256*cda5da8dSAndroid Build Coastguard Worker if code is None: 257*cda5da8dSAndroid Build Coastguard Worker # That didn't work, so try it as normal source code 258*cda5da8dSAndroid Build Coastguard Worker with io.open_code(decoded_path) as f: 259*cda5da8dSAndroid Build Coastguard Worker code = compile(f.read(), fname, 'exec') 260*cda5da8dSAndroid Build Coastguard Worker return code, fname 261*cda5da8dSAndroid Build Coastguard Worker 262*cda5da8dSAndroid Build Coastguard Workerdef run_path(path_name, init_globals=None, run_name=None): 263*cda5da8dSAndroid Build Coastguard Worker """Execute code located at the specified filesystem location. 264*cda5da8dSAndroid Build Coastguard Worker 265*cda5da8dSAndroid Build Coastguard Worker path_name -- filesystem location of a Python script, zipfile, 266*cda5da8dSAndroid Build Coastguard Worker or directory containing a top level __main__.py script. 267*cda5da8dSAndroid Build Coastguard Worker 268*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 269*cda5da8dSAndroid Build Coastguard Worker init_globals -- dictionary used to pre-populate the module’s 270*cda5da8dSAndroid Build Coastguard Worker globals dictionary before the code is executed. 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Worker run_name -- if not None, this will be used to set __name__; 273*cda5da8dSAndroid Build Coastguard Worker otherwise, '<run_path>' will be used for __name__. 274*cda5da8dSAndroid Build Coastguard Worker 275*cda5da8dSAndroid Build Coastguard Worker Returns the resulting module globals dictionary. 276*cda5da8dSAndroid Build Coastguard Worker """ 277*cda5da8dSAndroid Build Coastguard Worker if run_name is None: 278*cda5da8dSAndroid Build Coastguard Worker run_name = "<run_path>" 279*cda5da8dSAndroid Build Coastguard Worker pkg_name = run_name.rpartition(".")[0] 280*cda5da8dSAndroid Build Coastguard Worker from pkgutil import get_importer 281*cda5da8dSAndroid Build Coastguard Worker importer = get_importer(path_name) 282*cda5da8dSAndroid Build Coastguard Worker # Trying to avoid importing imp so as to not consume the deprecation warning. 283*cda5da8dSAndroid Build Coastguard Worker is_NullImporter = False 284*cda5da8dSAndroid Build Coastguard Worker if type(importer).__module__ == 'imp': 285*cda5da8dSAndroid Build Coastguard Worker if type(importer).__name__ == 'NullImporter': 286*cda5da8dSAndroid Build Coastguard Worker is_NullImporter = True 287*cda5da8dSAndroid Build Coastguard Worker if isinstance(importer, type(None)) or is_NullImporter: 288*cda5da8dSAndroid Build Coastguard Worker # Not a valid sys.path entry, so run the code directly 289*cda5da8dSAndroid Build Coastguard Worker # execfile() doesn't help as we want to allow compiled files 290*cda5da8dSAndroid Build Coastguard Worker code, fname = _get_code_from_file(run_name, path_name) 291*cda5da8dSAndroid Build Coastguard Worker return _run_module_code(code, init_globals, run_name, 292*cda5da8dSAndroid Build Coastguard Worker pkg_name=pkg_name, script_name=fname) 293*cda5da8dSAndroid Build Coastguard Worker else: 294*cda5da8dSAndroid Build Coastguard Worker # Finder is defined for path, so add it to 295*cda5da8dSAndroid Build Coastguard Worker # the start of sys.path 296*cda5da8dSAndroid Build Coastguard Worker sys.path.insert(0, path_name) 297*cda5da8dSAndroid Build Coastguard Worker try: 298*cda5da8dSAndroid Build Coastguard Worker # Here's where things are a little different from the run_module 299*cda5da8dSAndroid Build Coastguard Worker # case. There, we only had to replace the module in sys while the 300*cda5da8dSAndroid Build Coastguard Worker # code was running and doing so was somewhat optional. Here, we 301*cda5da8dSAndroid Build Coastguard Worker # have no choice and we have to remove it even while we read the 302*cda5da8dSAndroid Build Coastguard Worker # code. If we don't do this, a __loader__ attribute in the 303*cda5da8dSAndroid Build Coastguard Worker # existing __main__ module may prevent location of the new module. 304*cda5da8dSAndroid Build Coastguard Worker mod_name, mod_spec, code = _get_main_module_details() 305*cda5da8dSAndroid Build Coastguard Worker with _TempModule(run_name) as temp_module, \ 306*cda5da8dSAndroid Build Coastguard Worker _ModifiedArgv0(path_name): 307*cda5da8dSAndroid Build Coastguard Worker mod_globals = temp_module.module.__dict__ 308*cda5da8dSAndroid Build Coastguard Worker return _run_code(code, mod_globals, init_globals, 309*cda5da8dSAndroid Build Coastguard Worker run_name, mod_spec, pkg_name).copy() 310*cda5da8dSAndroid Build Coastguard Worker finally: 311*cda5da8dSAndroid Build Coastguard Worker try: 312*cda5da8dSAndroid Build Coastguard Worker sys.path.remove(path_name) 313*cda5da8dSAndroid Build Coastguard Worker except ValueError: 314*cda5da8dSAndroid Build Coastguard Worker pass 315*cda5da8dSAndroid Build Coastguard Worker 316*cda5da8dSAndroid Build Coastguard Worker 317*cda5da8dSAndroid Build Coastguard Workerif __name__ == "__main__": 318*cda5da8dSAndroid Build Coastguard Worker # Run the module specified as the next command line argument 319*cda5da8dSAndroid Build Coastguard Worker if len(sys.argv) < 2: 320*cda5da8dSAndroid Build Coastguard Worker print("No module specified for execution", file=sys.stderr) 321*cda5da8dSAndroid Build Coastguard Worker else: 322*cda5da8dSAndroid Build Coastguard Worker del sys.argv[0] # Make the requested module sys.argv[0] 323*cda5da8dSAndroid Build Coastguard Worker _run_module_as_main(sys.argv[0]) 324