xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/multiprocessing/spawn.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
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