1*cda5da8dSAndroid Build Coastguard Worker# 2*cda5da8dSAndroid Build Coastguard Worker# Code used to start processes when using the spawn or forkserver 3*cda5da8dSAndroid Build Coastguard Worker# start methods. 4*cda5da8dSAndroid Build Coastguard Worker# 5*cda5da8dSAndroid Build Coastguard Worker# multiprocessing/spawn.py 6*cda5da8dSAndroid Build Coastguard Worker# 7*cda5da8dSAndroid Build Coastguard Worker# Copyright (c) 2006-2008, R Oudkerk 8*cda5da8dSAndroid Build Coastguard Worker# Licensed to PSF under a Contributor Agreement. 9*cda5da8dSAndroid Build Coastguard Worker# 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard Workerimport os 12*cda5da8dSAndroid Build Coastguard Workerimport sys 13*cda5da8dSAndroid Build Coastguard Workerimport runpy 14*cda5da8dSAndroid Build Coastguard Workerimport types 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Workerfrom . import get_start_method, set_start_method 17*cda5da8dSAndroid Build Coastguard Workerfrom . import process 18*cda5da8dSAndroid Build Coastguard Workerfrom .context import reduction 19*cda5da8dSAndroid Build Coastguard Workerfrom . import util 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Worker__all__ = ['_main', 'freeze_support', 'set_executable', 'get_executable', 22*cda5da8dSAndroid Build Coastguard Worker 'get_preparation_data', 'get_command_line', 'import_main_path'] 23*cda5da8dSAndroid Build Coastguard Worker 24*cda5da8dSAndroid Build Coastguard Worker# 25*cda5da8dSAndroid Build Coastguard Worker# _python_exe is the assumed path to the python executable. 26*cda5da8dSAndroid Build Coastguard Worker# People embedding Python want to modify it. 27*cda5da8dSAndroid Build Coastguard Worker# 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Workerif sys.platform != 'win32': 30*cda5da8dSAndroid Build Coastguard Worker WINEXE = False 31*cda5da8dSAndroid Build Coastguard Worker WINSERVICE = False 32*cda5da8dSAndroid Build Coastguard Workerelse: 33*cda5da8dSAndroid Build Coastguard Worker WINEXE = getattr(sys, 'frozen', False) 34*cda5da8dSAndroid Build Coastguard Worker WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") 35*cda5da8dSAndroid Build Coastguard Worker 36*cda5da8dSAndroid Build Coastguard Workerdef set_executable(exe): 37*cda5da8dSAndroid Build Coastguard Worker global _python_exe 38*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'win32': 39*cda5da8dSAndroid Build Coastguard Worker _python_exe = os.fsdecode(exe) 40*cda5da8dSAndroid Build Coastguard Worker else: 41*cda5da8dSAndroid Build Coastguard Worker _python_exe = os.fsencode(exe) 42*cda5da8dSAndroid Build Coastguard Worker 43*cda5da8dSAndroid Build Coastguard Workerdef get_executable(): 44*cda5da8dSAndroid Build Coastguard Worker return _python_exe 45*cda5da8dSAndroid Build Coastguard Worker 46*cda5da8dSAndroid Build Coastguard Workerif WINSERVICE: 47*cda5da8dSAndroid Build Coastguard Worker set_executable(os.path.join(sys.exec_prefix, 'python.exe')) 48*cda5da8dSAndroid Build Coastguard Workerelse: 49*cda5da8dSAndroid Build Coastguard Worker set_executable(sys.executable) 50*cda5da8dSAndroid Build Coastguard Worker 51*cda5da8dSAndroid Build Coastguard Worker# 52*cda5da8dSAndroid Build Coastguard Worker# 53*cda5da8dSAndroid Build Coastguard Worker# 54*cda5da8dSAndroid Build Coastguard Worker 55*cda5da8dSAndroid Build Coastguard Workerdef is_forking(argv): 56*cda5da8dSAndroid Build Coastguard Worker ''' 57*cda5da8dSAndroid Build Coastguard Worker Return whether commandline indicates we are forking 58*cda5da8dSAndroid Build Coastguard Worker ''' 59*cda5da8dSAndroid Build Coastguard Worker if len(argv) >= 2 and argv[1] == '--multiprocessing-fork': 60*cda5da8dSAndroid Build Coastguard Worker return True 61*cda5da8dSAndroid Build Coastguard Worker else: 62*cda5da8dSAndroid Build Coastguard Worker return False 63*cda5da8dSAndroid Build Coastguard Worker 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard Workerdef freeze_support(): 66*cda5da8dSAndroid Build Coastguard Worker ''' 67*cda5da8dSAndroid Build Coastguard Worker Run code for process object if this in not the main process 68*cda5da8dSAndroid Build Coastguard Worker ''' 69*cda5da8dSAndroid Build Coastguard Worker if is_forking(sys.argv): 70*cda5da8dSAndroid Build Coastguard Worker kwds = {} 71*cda5da8dSAndroid Build Coastguard Worker for arg in sys.argv[2:]: 72*cda5da8dSAndroid Build Coastguard Worker name, value = arg.split('=') 73*cda5da8dSAndroid Build Coastguard Worker if value == 'None': 74*cda5da8dSAndroid Build Coastguard Worker kwds[name] = None 75*cda5da8dSAndroid Build Coastguard Worker else: 76*cda5da8dSAndroid Build Coastguard Worker kwds[name] = int(value) 77*cda5da8dSAndroid Build Coastguard Worker spawn_main(**kwds) 78*cda5da8dSAndroid Build Coastguard Worker sys.exit() 79*cda5da8dSAndroid Build Coastguard Worker 80*cda5da8dSAndroid Build Coastguard Worker 81*cda5da8dSAndroid Build Coastguard Workerdef get_command_line(**kwds): 82*cda5da8dSAndroid Build Coastguard Worker ''' 83*cda5da8dSAndroid Build Coastguard Worker Returns prefix of command line used for spawning a child process 84*cda5da8dSAndroid Build Coastguard Worker ''' 85*cda5da8dSAndroid Build Coastguard Worker if getattr(sys, 'frozen', False): 86*cda5da8dSAndroid Build Coastguard Worker return ([sys.executable, '--multiprocessing-fork'] + 87*cda5da8dSAndroid Build Coastguard Worker ['%s=%r' % item for item in kwds.items()]) 88*cda5da8dSAndroid Build Coastguard Worker else: 89*cda5da8dSAndroid Build Coastguard Worker prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' 90*cda5da8dSAndroid Build Coastguard Worker prog %= ', '.join('%s=%r' % item for item in kwds.items()) 91*cda5da8dSAndroid Build Coastguard Worker opts = util._args_from_interpreter_flags() 92*cda5da8dSAndroid Build Coastguard Worker exe = get_executable() 93*cda5da8dSAndroid Build Coastguard Worker return [exe] + opts + ['-c', prog, '--multiprocessing-fork'] 94*cda5da8dSAndroid Build Coastguard Worker 95*cda5da8dSAndroid Build Coastguard Worker 96*cda5da8dSAndroid Build Coastguard Workerdef spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): 97*cda5da8dSAndroid Build Coastguard Worker ''' 98*cda5da8dSAndroid Build Coastguard Worker Run code specified by data received over pipe 99*cda5da8dSAndroid Build Coastguard Worker ''' 100*cda5da8dSAndroid Build Coastguard Worker assert is_forking(sys.argv), "Not forking" 101*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'win32': 102*cda5da8dSAndroid Build Coastguard Worker import msvcrt 103*cda5da8dSAndroid Build Coastguard Worker import _winapi 104*cda5da8dSAndroid Build Coastguard Worker 105*cda5da8dSAndroid Build Coastguard Worker if parent_pid is not None: 106*cda5da8dSAndroid Build Coastguard Worker source_process = _winapi.OpenProcess( 107*cda5da8dSAndroid Build Coastguard Worker _winapi.SYNCHRONIZE | _winapi.PROCESS_DUP_HANDLE, 108*cda5da8dSAndroid Build Coastguard Worker False, parent_pid) 109*cda5da8dSAndroid Build Coastguard Worker else: 110*cda5da8dSAndroid Build Coastguard Worker source_process = None 111*cda5da8dSAndroid Build Coastguard Worker new_handle = reduction.duplicate(pipe_handle, 112*cda5da8dSAndroid Build Coastguard Worker source_process=source_process) 113*cda5da8dSAndroid Build Coastguard Worker fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY) 114*cda5da8dSAndroid Build Coastguard Worker parent_sentinel = source_process 115*cda5da8dSAndroid Build Coastguard Worker else: 116*cda5da8dSAndroid Build Coastguard Worker from . import resource_tracker 117*cda5da8dSAndroid Build Coastguard Worker resource_tracker._resource_tracker._fd = tracker_fd 118*cda5da8dSAndroid Build Coastguard Worker fd = pipe_handle 119*cda5da8dSAndroid Build Coastguard Worker parent_sentinel = os.dup(pipe_handle) 120*cda5da8dSAndroid Build Coastguard Worker exitcode = _main(fd, parent_sentinel) 121*cda5da8dSAndroid Build Coastguard Worker sys.exit(exitcode) 122*cda5da8dSAndroid Build Coastguard Worker 123*cda5da8dSAndroid Build Coastguard Worker 124*cda5da8dSAndroid Build Coastguard Workerdef _main(fd, parent_sentinel): 125*cda5da8dSAndroid Build Coastguard Worker with os.fdopen(fd, 'rb', closefd=True) as from_parent: 126*cda5da8dSAndroid Build Coastguard Worker process.current_process()._inheriting = True 127*cda5da8dSAndroid Build Coastguard Worker try: 128*cda5da8dSAndroid Build Coastguard Worker preparation_data = reduction.pickle.load(from_parent) 129*cda5da8dSAndroid Build Coastguard Worker prepare(preparation_data) 130*cda5da8dSAndroid Build Coastguard Worker self = reduction.pickle.load(from_parent) 131*cda5da8dSAndroid Build Coastguard Worker finally: 132*cda5da8dSAndroid Build Coastguard Worker del process.current_process()._inheriting 133*cda5da8dSAndroid Build Coastguard Worker return self._bootstrap(parent_sentinel) 134*cda5da8dSAndroid Build Coastguard Worker 135*cda5da8dSAndroid Build Coastguard Worker 136*cda5da8dSAndroid Build Coastguard Workerdef _check_not_importing_main(): 137*cda5da8dSAndroid Build Coastguard Worker if getattr(process.current_process(), '_inheriting', False): 138*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError(''' 139*cda5da8dSAndroid Build Coastguard Worker An attempt has been made to start a new process before the 140*cda5da8dSAndroid Build Coastguard Worker current process has finished its bootstrapping phase. 141*cda5da8dSAndroid Build Coastguard Worker 142*cda5da8dSAndroid Build Coastguard Worker This probably means that you are not using fork to start your 143*cda5da8dSAndroid Build Coastguard Worker child processes and you have forgotten to use the proper idiom 144*cda5da8dSAndroid Build Coastguard Worker in the main module: 145*cda5da8dSAndroid Build Coastguard Worker 146*cda5da8dSAndroid Build Coastguard Worker if __name__ == '__main__': 147*cda5da8dSAndroid Build Coastguard Worker freeze_support() 148*cda5da8dSAndroid Build Coastguard Worker ... 149*cda5da8dSAndroid Build Coastguard Worker 150*cda5da8dSAndroid Build Coastguard Worker The "freeze_support()" line can be omitted if the program 151*cda5da8dSAndroid Build Coastguard Worker is not going to be frozen to produce an executable.''') 152*cda5da8dSAndroid Build Coastguard Worker 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Workerdef get_preparation_data(name): 155*cda5da8dSAndroid Build Coastguard Worker ''' 156*cda5da8dSAndroid Build Coastguard Worker Return info about parent needed by child to unpickle process object 157*cda5da8dSAndroid Build Coastguard Worker ''' 158*cda5da8dSAndroid Build Coastguard Worker _check_not_importing_main() 159*cda5da8dSAndroid Build Coastguard Worker d = dict( 160*cda5da8dSAndroid Build Coastguard Worker log_to_stderr=util._log_to_stderr, 161*cda5da8dSAndroid Build Coastguard Worker authkey=process.current_process().authkey, 162*cda5da8dSAndroid Build Coastguard Worker ) 163*cda5da8dSAndroid Build Coastguard Worker 164*cda5da8dSAndroid Build Coastguard Worker if util._logger is not None: 165*cda5da8dSAndroid Build Coastguard Worker d['log_level'] = util._logger.getEffectiveLevel() 166*cda5da8dSAndroid Build Coastguard Worker 167*cda5da8dSAndroid Build Coastguard Worker sys_path=sys.path.copy() 168*cda5da8dSAndroid Build Coastguard Worker try: 169*cda5da8dSAndroid Build Coastguard Worker i = sys_path.index('') 170*cda5da8dSAndroid Build Coastguard Worker except ValueError: 171*cda5da8dSAndroid Build Coastguard Worker pass 172*cda5da8dSAndroid Build Coastguard Worker else: 173*cda5da8dSAndroid Build Coastguard Worker sys_path[i] = process.ORIGINAL_DIR 174*cda5da8dSAndroid Build Coastguard Worker 175*cda5da8dSAndroid Build Coastguard Worker d.update( 176*cda5da8dSAndroid Build Coastguard Worker name=name, 177*cda5da8dSAndroid Build Coastguard Worker sys_path=sys_path, 178*cda5da8dSAndroid Build Coastguard Worker sys_argv=sys.argv, 179*cda5da8dSAndroid Build Coastguard Worker orig_dir=process.ORIGINAL_DIR, 180*cda5da8dSAndroid Build Coastguard Worker dir=os.getcwd(), 181*cda5da8dSAndroid Build Coastguard Worker start_method=get_start_method(), 182*cda5da8dSAndroid Build Coastguard Worker ) 183*cda5da8dSAndroid Build Coastguard Worker 184*cda5da8dSAndroid Build Coastguard Worker # Figure out whether to initialise main in the subprocess as a module 185*cda5da8dSAndroid Build Coastguard Worker # or through direct execution (or to leave it alone entirely) 186*cda5da8dSAndroid Build Coastguard Worker main_module = sys.modules['__main__'] 187*cda5da8dSAndroid Build Coastguard Worker main_mod_name = getattr(main_module.__spec__, "name", None) 188*cda5da8dSAndroid Build Coastguard Worker if main_mod_name is not None: 189*cda5da8dSAndroid Build Coastguard Worker d['init_main_from_name'] = main_mod_name 190*cda5da8dSAndroid Build Coastguard Worker elif sys.platform != 'win32' or (not WINEXE and not WINSERVICE): 191*cda5da8dSAndroid Build Coastguard Worker main_path = getattr(main_module, '__file__', None) 192*cda5da8dSAndroid Build Coastguard Worker if main_path is not None: 193*cda5da8dSAndroid Build Coastguard Worker if (not os.path.isabs(main_path) and 194*cda5da8dSAndroid Build Coastguard Worker process.ORIGINAL_DIR is not None): 195*cda5da8dSAndroid Build Coastguard Worker main_path = os.path.join(process.ORIGINAL_DIR, main_path) 196*cda5da8dSAndroid Build Coastguard Worker d['init_main_from_path'] = os.path.normpath(main_path) 197*cda5da8dSAndroid Build Coastguard Worker 198*cda5da8dSAndroid Build Coastguard Worker return d 199*cda5da8dSAndroid Build Coastguard Worker 200*cda5da8dSAndroid Build Coastguard Worker# 201*cda5da8dSAndroid Build Coastguard Worker# Prepare current process 202*cda5da8dSAndroid Build Coastguard Worker# 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Workerold_main_modules = [] 205*cda5da8dSAndroid Build Coastguard Worker 206*cda5da8dSAndroid Build Coastguard Workerdef prepare(data): 207*cda5da8dSAndroid Build Coastguard Worker ''' 208*cda5da8dSAndroid Build Coastguard Worker Try to get current process ready to unpickle process object 209*cda5da8dSAndroid Build Coastguard Worker ''' 210*cda5da8dSAndroid Build Coastguard Worker if 'name' in data: 211*cda5da8dSAndroid Build Coastguard Worker process.current_process().name = data['name'] 212*cda5da8dSAndroid Build Coastguard Worker 213*cda5da8dSAndroid Build Coastguard Worker if 'authkey' in data: 214*cda5da8dSAndroid Build Coastguard Worker process.current_process().authkey = data['authkey'] 215*cda5da8dSAndroid Build Coastguard Worker 216*cda5da8dSAndroid Build Coastguard Worker if 'log_to_stderr' in data and data['log_to_stderr']: 217*cda5da8dSAndroid Build Coastguard Worker util.log_to_stderr() 218*cda5da8dSAndroid Build Coastguard Worker 219*cda5da8dSAndroid Build Coastguard Worker if 'log_level' in data: 220*cda5da8dSAndroid Build Coastguard Worker util.get_logger().setLevel(data['log_level']) 221*cda5da8dSAndroid Build Coastguard Worker 222*cda5da8dSAndroid Build Coastguard Worker if 'sys_path' in data: 223*cda5da8dSAndroid Build Coastguard Worker sys.path = data['sys_path'] 224*cda5da8dSAndroid Build Coastguard Worker 225*cda5da8dSAndroid Build Coastguard Worker if 'sys_argv' in data: 226*cda5da8dSAndroid Build Coastguard Worker sys.argv = data['sys_argv'] 227*cda5da8dSAndroid Build Coastguard Worker 228*cda5da8dSAndroid Build Coastguard Worker if 'dir' in data: 229*cda5da8dSAndroid Build Coastguard Worker os.chdir(data['dir']) 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Worker if 'orig_dir' in data: 232*cda5da8dSAndroid Build Coastguard Worker process.ORIGINAL_DIR = data['orig_dir'] 233*cda5da8dSAndroid Build Coastguard Worker 234*cda5da8dSAndroid Build Coastguard Worker if 'start_method' in data: 235*cda5da8dSAndroid Build Coastguard Worker set_start_method(data['start_method'], force=True) 236*cda5da8dSAndroid Build Coastguard Worker 237*cda5da8dSAndroid Build Coastguard Worker if 'init_main_from_name' in data: 238*cda5da8dSAndroid Build Coastguard Worker _fixup_main_from_name(data['init_main_from_name']) 239*cda5da8dSAndroid Build Coastguard Worker elif 'init_main_from_path' in data: 240*cda5da8dSAndroid Build Coastguard Worker _fixup_main_from_path(data['init_main_from_path']) 241*cda5da8dSAndroid Build Coastguard Worker 242*cda5da8dSAndroid Build Coastguard Worker# Multiprocessing module helpers to fix up the main module in 243*cda5da8dSAndroid Build Coastguard Worker# spawned subprocesses 244*cda5da8dSAndroid Build Coastguard Workerdef _fixup_main_from_name(mod_name): 245*cda5da8dSAndroid Build Coastguard Worker # __main__.py files for packages, directories, zip archives, etc, run 246*cda5da8dSAndroid Build Coastguard Worker # their "main only" code unconditionally, so we don't even try to 247*cda5da8dSAndroid Build Coastguard Worker # populate anything in __main__, nor do we make any changes to 248*cda5da8dSAndroid Build Coastguard Worker # __main__ attributes 249*cda5da8dSAndroid Build Coastguard Worker current_main = sys.modules['__main__'] 250*cda5da8dSAndroid Build Coastguard Worker if mod_name == "__main__" or mod_name.endswith(".__main__"): 251*cda5da8dSAndroid Build Coastguard Worker return 252*cda5da8dSAndroid Build Coastguard Worker 253*cda5da8dSAndroid Build Coastguard Worker # If this process was forked, __main__ may already be populated 254*cda5da8dSAndroid Build Coastguard Worker if getattr(current_main.__spec__, "name", None) == mod_name: 255*cda5da8dSAndroid Build Coastguard Worker return 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Worker # Otherwise, __main__ may contain some non-main code where we need to 258*cda5da8dSAndroid Build Coastguard Worker # support unpickling it properly. We rerun it as __mp_main__ and make 259*cda5da8dSAndroid Build Coastguard Worker # the normal __main__ an alias to that 260*cda5da8dSAndroid Build Coastguard Worker old_main_modules.append(current_main) 261*cda5da8dSAndroid Build Coastguard Worker main_module = types.ModuleType("__mp_main__") 262*cda5da8dSAndroid Build Coastguard Worker main_content = runpy.run_module(mod_name, 263*cda5da8dSAndroid Build Coastguard Worker run_name="__mp_main__", 264*cda5da8dSAndroid Build Coastguard Worker alter_sys=True) 265*cda5da8dSAndroid Build Coastguard Worker main_module.__dict__.update(main_content) 266*cda5da8dSAndroid Build Coastguard Worker sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module 267*cda5da8dSAndroid Build Coastguard Worker 268*cda5da8dSAndroid Build Coastguard Worker 269*cda5da8dSAndroid Build Coastguard Workerdef _fixup_main_from_path(main_path): 270*cda5da8dSAndroid Build Coastguard Worker # If this process was forked, __main__ may already be populated 271*cda5da8dSAndroid Build Coastguard Worker current_main = sys.modules['__main__'] 272*cda5da8dSAndroid Build Coastguard Worker 273*cda5da8dSAndroid Build Coastguard Worker # Unfortunately, the main ipython launch script historically had no 274*cda5da8dSAndroid Build Coastguard Worker # "if __name__ == '__main__'" guard, so we work around that 275*cda5da8dSAndroid Build Coastguard Worker # by treating it like a __main__.py file 276*cda5da8dSAndroid Build Coastguard Worker # See https://github.com/ipython/ipython/issues/4698 277*cda5da8dSAndroid Build Coastguard Worker main_name = os.path.splitext(os.path.basename(main_path))[0] 278*cda5da8dSAndroid Build Coastguard Worker if main_name == 'ipython': 279*cda5da8dSAndroid Build Coastguard Worker return 280*cda5da8dSAndroid Build Coastguard Worker 281*cda5da8dSAndroid Build Coastguard Worker # Otherwise, if __file__ already has the setting we expect, 282*cda5da8dSAndroid Build Coastguard Worker # there's nothing more to do 283*cda5da8dSAndroid Build Coastguard Worker if getattr(current_main, '__file__', None) == main_path: 284*cda5da8dSAndroid Build Coastguard Worker return 285*cda5da8dSAndroid Build Coastguard Worker 286*cda5da8dSAndroid Build Coastguard Worker # If the parent process has sent a path through rather than a module 287*cda5da8dSAndroid Build Coastguard Worker # name we assume it is an executable script that may contain 288*cda5da8dSAndroid Build Coastguard Worker # non-main code that needs to be executed 289*cda5da8dSAndroid Build Coastguard Worker old_main_modules.append(current_main) 290*cda5da8dSAndroid Build Coastguard Worker main_module = types.ModuleType("__mp_main__") 291*cda5da8dSAndroid Build Coastguard Worker main_content = runpy.run_path(main_path, 292*cda5da8dSAndroid Build Coastguard Worker run_name="__mp_main__") 293*cda5da8dSAndroid Build Coastguard Worker main_module.__dict__.update(main_content) 294*cda5da8dSAndroid Build Coastguard Worker sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module 295*cda5da8dSAndroid Build Coastguard Worker 296*cda5da8dSAndroid Build Coastguard Worker 297*cda5da8dSAndroid Build Coastguard Workerdef import_main_path(main_path): 298*cda5da8dSAndroid Build Coastguard Worker ''' 299*cda5da8dSAndroid Build Coastguard Worker Set sys.modules['__main__'] to module at main_path 300*cda5da8dSAndroid Build Coastguard Worker ''' 301*cda5da8dSAndroid Build Coastguard Worker _fixup_main_from_path(main_path) 302