#!/usr/bin/env '%interpreter%' import os import tempfile import shutil import signal import sys import subprocess import zipfile PYTHON_BINARY = '%interpreter%' MAIN_FILE = '%main%' PYTHON_PATH = 'PYTHONPATH' # Don't imply 'import site' on initialization PYTHON_ARG = '-S' def Main(): args = sys.argv[1:] runfiles_path = tempfile.mkdtemp(prefix="Soong.python_") try: zf = zipfile.ZipFile(os.path.dirname(__file__)) zf.extractall(runfiles_path) zf.close() new_python_path = runfiles_path old_python_path = os.environ.get(PYTHON_PATH) if old_python_path: os.environ.update({PYTHON_PATH: new_python_path + ":" + old_python_path}) else: os.environ.update({PYTHON_PATH: new_python_path}) # Now look for main python source file. main_filepath = os.path.join(runfiles_path, MAIN_FILE) assert os.path.exists(main_filepath), \ 'Cannot exec() %r: file not found.' % main_filepath assert os.access(main_filepath, os.R_OK), \ 'Cannot exec() %r: file not readable.' % main_filepath args = [PYTHON_BINARY, PYTHON_ARG, main_filepath] + args sys.stdout.flush() # close_fds=False so that you can run binaries with files provided on the command line: # my_python_app --file <(echo foo) p = subprocess.Popen(args, close_fds=False) def handler(sig, frame): p.send_signal(sig) # Redirect SIGINT and SIGTERM to subprocess signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGTERM, handler) p.wait() sys.exit(p.returncode) finally: shutil.rmtree(runfiles_path, ignore_errors=True) if __name__ == '__main__': Main()