From: Arfrever Frehtes Taifersar Arahesis Date: Sat, 13 Mar 2010 13:46:20 +0000 (+0000) Subject: Improve phase functions. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=08d48e43e56da8751fab9eeca1195d4c51afaf87;p=gentoo.git Improve phase functions. Simplify and improve validate_PYTHON_ABIS(). Fix handling of ${S} ending in '/' in python_copy_sources() (bug #307943). Improve python_generate_wrapper_scripts(). Improve python_convert_shebangs(). Add python_clean_sitedirs(). Simplify python_mod_cleanup(). Improve deprecation warnings in python_version(), python_mod_exists() and python_tkinter_exists(). --- diff --git a/eclass/python.eclass b/eclass/python.eclass index a88c297311f2..bdfcbb549886 100644 --- a/eclass/python.eclass +++ b/eclass/python.eclass @@ -1,6 +1,6 @@ # Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.93 2010/03/12 18:27:01 betelgeuse Exp $ +# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.94 2010/03/13 13:46:20 arfrever Exp $ # @ECLASS: python.eclass # @MAINTAINER: @@ -273,13 +273,15 @@ unset _PYTHON_ATOMS # @DESCRIPTION: # Set this to export phase functions for the following ebuild phases: # src_prepare, src_configure, src_compile, src_test, src_install. -if ! has "${EAPI:-0}" 0 1 && [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then +if ! has "${EAPI:-0}" 0 1; then python_src_prepare() { python_copy_sources } for python_default_function in src_configure src_compile src_test src_install; do - eval "python_${python_default_function}() { python_execute_function -d -s; }" + eval "python_${python_default_function}() { + python_execute_function -d -s \"\$@\" + }" done unset python_default_function @@ -308,7 +310,7 @@ validate_PYTHON_ABIS() { PYTHON_ABI_SUPPORTED_VALUES="${_CPYTHON2_SUPPORTED_ABIS[@]} ${_CPYTHON3_SUPPORTED_ABIS[@]} ${_JYTHON_SUPPORTED_ABIS[@]}" if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then - local python2_enabled="0" python3_enabled="0" + local cpython_enabled="0" if [[ -z "${USE_PYTHON}" ]]; then die "USE_PYTHON variable is empty" @@ -319,11 +321,8 @@ validate_PYTHON_ABIS() { die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'" fi - if has "${PYTHON_ABI}" "${_CPYTHON2_SUPPORTED_ABIS[@]}"; then - python2_enabled="1" - fi - if has "${PYTHON_ABI}" "${_CPYTHON3_SUPPORTED_ABIS[@]}"; then - python3_enabled="1" + if has "${PYTHON_ABI}" "${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}"; then + cpython_enabled="1" fi support_ABI="1" @@ -340,13 +339,7 @@ validate_PYTHON_ABIS() { die "USE_PYTHON variable does not enable any version of Python supported by ${CATEGORY}/${PF}" fi - if [[ "${python2_enabled}" == "0" ]]; then - ewarn "USE_PYTHON variable does not enable any version of Python 2. This configuration is unsupported." - fi - if [[ "${python3_enabled}" == "0" ]]; then - ewarn "USE_PYTHON variable does not enable any version of Python 3. This configuration is unsupported." - fi - if [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "0" ]]; then + if [[ "${cpython_enabled}" == "0" ]]; then die "USE_PYTHON variable does not enable any version of CPython" fi else @@ -496,9 +489,6 @@ python_execute_function() { die "${FUNCNAME}(): '${function}' function is not defined" fi else - if [[ "$#" -ne 0 ]]; then - die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously" - fi if has "${EAPI:-0}" 0 1; then die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI" fi @@ -506,28 +496,28 @@ python_execute_function() { if [[ "${EBUILD_PHASE}" == "configure" ]]; then if has "${EAPI}" 2 3; then python_default_function() { - econf + econf "$@" } else python_default_function() { - nonfatal econf + nonfatal econf "$@" } fi elif [[ "${EBUILD_PHASE}" == "compile" ]]; then python_default_function() { - emake + emake "$@" } elif [[ "${EBUILD_PHASE}" == "test" ]]; then python_default_function() { if emake -j1 -n check &> /dev/null; then - emake -j1 check + emake -j1 check "$@" elif emake -j1 -n test &> /dev/null; then - emake -j1 test + emake -j1 test "$@" fi } elif [[ "${EBUILD_PHASE}" == "install" ]]; then python_default_function() { - emake DESTDIR="${D}" install + emake DESTDIR="${D}" install "$@" } else die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase" @@ -665,7 +655,7 @@ python_copy_sources() { if [[ "${WORKDIR}" == "${S}" ]]; then die "${FUNCNAME}() cannot be used" fi - dirs=("${S}") + dirs=("${S%/}") else dirs=("$@") fi @@ -761,12 +751,12 @@ python_generate_wrapper_scripts() { fi if [[ "${quiet}" == "0" ]]; then - einfo "Generating '${file#${D%/}}' wrapper script" + einfo "Generating '${file#${ED%/}}' wrapper script" fi cat << EOF > "${file}" #!/usr/bin/env python -# Gentoo '${file##*/}' wrapper script +# Gentoo '${file##*/}' wrapper script generated by python_generate_wrapper_scripts() import os import re @@ -774,6 +764,8 @@ import subprocess import sys EPYTHON_re = re.compile(r"^python(\d+\.\d+)$") +python_shebang_re = re.compile(r"^#! *(${EPREFIX}/usr/bin/python|(${EPREFIX})?/usr/bin/env +(${EPREFIX}/usr/bin/)?python)") +python_verification_output_re = re.compile("^GENTOO_PYTHON_TARGET_SCRIPT_PATH supported\n$") EOF if [[ "$?" != "0" ]]; then @@ -798,16 +790,16 @@ else: 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 +815,16 @@ except (OSError, ValueError): 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 +833,47 @@ EOF 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" @@ -1019,7 +1045,7 @@ PYTHON() { elif [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then PYTHON_ABI="$("${EPREFIX}/usr/bin/python" -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")" elif [[ -z "${PYTHON_ABI}" ]]; then - die "${FUNCNAME}(): Invalid usage: Python ABI not specified" + die "${FUNCNAME}(): Invalid usage: ${FUNCNAME}() should be used in ABI-specific local scope" fi elif [[ "$#" -eq 1 ]]; then if [[ "${final_ABI}" == "1" ]]; then @@ -1487,9 +1513,12 @@ python_convert_shebangs() { [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then + [[ "$(sed -ne "2p" "${file}")" =~ ^"# Gentoo '".*"' wrapper script generated by python_generate_wrapper_scripts()"$ ]] && continue + if [[ "${quiet}" == "0" ]]; then einfo "Converting shebang in '${file}'" fi + sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed" # Delete potential whitespace after "#!". @@ -1498,6 +1527,15 @@ python_convert_shebangs() { done } +# @FUNCTION: python_clean_sitedirs +# @DESCRIPTION: +# Delete needless files in site-packages directories in ${ED}. +python_clean_sitedirs() { + _python_initialize_prefix_variables + + find "${ED}"usr/$(get_libdir)/python*/site-packages "(" -name "*.c" -o -name "*.h" -o -name "*.la" ")" -type f -print0 | xargs -0 rm -f +} + # ================================================================================================ # ================================ FUNCTIONS FOR RUNNING OF TESTS ================================ # ================================================================================================ @@ -1984,27 +2022,27 @@ python_mod_cleanup() { if [[ "${REPLY}" == *[co] ]]; then py_file="${REPLY%[co]}" [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue - einfo "${_BLUE}<<< ${py_file}[co]${_NORMAL}" + echo "${_BLUE}<<< ${py_file}[co]${_NORMAL}" rm -f "${py_file}"[co] elif [[ "${REPLY}" == *\$py.class ]]; then py_file="${REPLY%\$py.class}.py" [[ -f "${py_file}" || ! -f "${py_file%.py}\$py.class" ]] && continue - einfo "${_BLUE}<<< ${py_file%.py}\$py.class${_NORMAL}" + echo "${_BLUE}<<< ${py_file%.py}\$py.class${_NORMAL}" rm -f "${py_file%.py}\$py.class" fi done # Attempt to delete directories, which may be empty. find "${path}" -type d | sort -r | while read -r dir; do - rmdir "${dir}" 2>/dev/null && einfo "${_CYAN}<<< ${dir}${_NORMAL}" + rmdir "${dir}" 2>/dev/null && echo "${_CYAN}<<< ${dir}${_NORMAL}" done elif [[ "${path}" == *.py && ! -f "${path}" ]]; then if [[ (-f "${path}c" || -f "${path}o") ]]; then - einfo "${_BLUE}<<< ${path}[co]${_NORMAL}" + echo "${_BLUE}<<< ${path}[co]${_NORMAL}" rm -f "${path}"[co] fi if [[ -f "${path%.py}\$py.class" ]]; then - einfo "${_BLUE}<<< ${path%.py}\$py.class${_NORMAL}" + echo "${_BLUE}<<< ${path%.py}\$py.class${_NORMAL}" rm -f "${path%.py}\$py.class" fi fi @@ -2029,6 +2067,7 @@ python_version() { einfo einfo "Deprecation Warning: ${FUNCNAME}() is deprecated and will be banned on 2010-07-01." einfo "Use PYTHON() instead of python variable. Use python_get_*() instead of PYVER* variables." + einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." einfo fi @@ -2066,6 +2105,7 @@ python_mod_exists() { einfo einfo "Deprecation Warning: ${FUNCNAME}() is deprecated and will be banned on 2010-07-01." einfo "Use USE dependencies and/or has_version() instead of ${FUNCNAME}()." + einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." einfo if [[ "$#" -ne 1 ]]; then @@ -2088,6 +2128,7 @@ python_tkinter_exists() { einfo einfo "Deprecation Warning: ${FUNCNAME}() is deprecated and will be banned on 2010-07-01." einfo "Use PYTHON_USE_WITH=\"xml\" and python_pkg_setup() instead of ${FUNCNAME}()." + einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." einfo fi