--- python.eclass +++ python.eclass @@ -774,6 +774,8 @@ import sys EPYTHON_re = re.compile(r"^python(\d+\.\d+)$") +python_shebang_re = re.compile(r"^#!.*python") +python_verification_output_re = re.compile("^GENTOO_PYTHON_TARGET_SCRIPT_PATH supported\n$") EOF if [[ "$?" != "0" ]]; then @@ -798,16 +800,16 @@ sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n") sys.exit(1) - eselect_output = eselect_process.stdout.read() - if not isinstance(eselect_output, str): + EPYTHON = eselect_process.stdout.read().rstrip("\n") + if not isinstance(EPYTHON, str): # Python 3 - eselect_output = eselect_output.decode() + EPYTHON = EPYTHON.decode() - EPYTHON_matched = EPYTHON_re.match(eselect_output) + EPYTHON_matched = EPYTHON_re.match(EPYTHON) if EPYTHON_matched: PYTHON_ABI = EPYTHON_matched.group(1) else: - sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output) + sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % EPYTHON) sys.exit(1) EOF if [[ "$?" != "0" ]]; then @@ -823,16 +825,16 @@ sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n") sys.exit(1) -eselect_output = eselect_process.stdout.read() -if not isinstance(eselect_output, str): +EPYTHON = eselect_process.stdout.read().rstrip("\n") +if not isinstance(EPYTHON, str): # Python 3 - eselect_output = eselect_output.decode() + EPYTHON = EPYTHON.decode() -EPYTHON_matched = EPYTHON_re.match(eselect_output) +EPYTHON_matched = EPYTHON_re.match(EPYTHON) if EPYTHON_matched: PYTHON_ABI = EPYTHON_matched.group(1) else: - sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output) + sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % EPYTHON) sys.exit(1) EOF if [[ "$?" != "0" ]]; then @@ -841,13 +843,47 @@ fi cat << EOF >> "${file}" -os.environ["PYTHON_SCRIPT_NAME"] = sys.argv[0] -target_executable = "%s-%s" % (os.path.realpath(sys.argv[0]), PYTHON_ABI) -if not os.path.exists(target_executable): - sys.stderr.write("'%s' does not exist\n" % target_executable) +wrapper_script_path = os.path.realpath(sys.argv[0]) +target_executable_path = "%s-%s" % (wrapper_script_path, PYTHON_ABI) +os.environ["GENTOO_PYTHON_WRAPPER_SCRIPT_PATH"] = sys.argv[0] +os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH"] = target_executable_path +if not os.path.exists(target_executable_path): + sys.stderr.write("'%s' does not exist\n" % target_executable_path) sys.exit(1) -os.execv(target_executable, sys.argv) +target_executable = open(target_executable_path, "rb") +target_executable_first_line = target_executable.readline() +if not isinstance(target_executable_first_line, str): + # Python 3 + target_executable_first_line = target_executable_first_line.decode("utf_8", "replace") + +python_shebang_matched = python_shebang_re.match(target_executable_first_line) +target_executable.close() + +if python_shebang_matched: + try: + python_interpreter_path = "${EPREFIX}/usr/bin/%s" % EPYTHON + os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"] = "1" + python_verification_process = subprocess.Popen([python_interpreter_path, "-c", "pass"], stdout=subprocess.PIPE) + del os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"] + if python_verification_process.wait() != 0: + raise ValueError + + python_verification_output = python_verification_process.stdout.read() + if not isinstance(python_verification_output, str): + # Python 3 + python_verification_output = python_verification_output.decode() + + if not python_verification_output_re.match(python_verification_output): + raise ValueError + + os.execv(python_interpreter_path, [python_interpreter_path] + sys.argv) + except: + pass + if "GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION" in os.environ: + del os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"] + +os.execv(target_executable_path, sys.argv) EOF if [[ "$?" != "0" ]]; then die "${FUNCNAME}(): Generation of '$1' failed"