diff --git a/sdk_container/src/third_party/portage-stable/eclass/python-any-r1.eclass b/sdk_container/src/third_party/portage-stable/eclass/python-any-r1.eclass index 42fd3c7f57..c6dfc9c7ae 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python-any-r1.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python-any-r1.eclass @@ -1,8 +1,8 @@ -# Copyright 1999-2014 Gentoo Foundation +# Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python-any-r1.eclass,v 1.18 2014/11/09 22:27:58 mgorny Exp $ +# $Id$ -# @ECLASS: python-any-r1 +# @ECLASS: python-any-r1.eclass # @MAINTAINER: # Python team # @AUTHOR: @@ -33,12 +33,11 @@ # packages using python-any-r1, and there is no need ever to inherit # both. # -# For more information, please see the python-r1 Developer's Guide: -# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml +# For more information, please see the wiki: +# https://wiki.gentoo.org/wiki/Project:Python/python-any-r1 case "${EAPI:-0}" in - 0|1|2|3|4|5) - # EAPI=4 needed by python-r1 + 0|1|2|3|4|5|6) ;; *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" @@ -72,9 +71,24 @@ if [[ ! ${_PYTHON_ANY_R1} ]]; then # @CODE # PYTHON_COMPAT=( python{2_5,2_6,2_7} ) # @CODE -if ! declare -p PYTHON_COMPAT &>/dev/null; then - die 'PYTHON_COMPAT not declared.' -fi + +# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE +# @INTERNAL +# @DESCRIPTION: +# This variable can be used when working with ebuilds to override +# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation +# which will be used to build the package. It needs to be specified +# in the calling environment, and not in ebuilds. +# +# It should be noted that in order to preserve metadata immutability, +# PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of +# EPYTHON and eselect-python preferences are ignored. Dependencies need +# to be satisfied manually. +# +# Example: +# @CODE +# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar +# @CODE # @ECLASS-VARIABLE: PYTHON_REQ_USE # @DEFAULT_UNSET @@ -113,27 +127,23 @@ fi # dev-lang/python:2.6[gdbm] ) # @CODE -_python_build_set_globals() { +_python_any_set_globals() { local usestr i PYTHON_PKG_DEP [[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]" - # check for invalid PYTHON_COMPAT - for i in "${PYTHON_COMPAT[@]}"; do - # the function simply dies on invalid impl - _python_impl_supported "${i}" - done + _python_set_impls PYTHON_DEPS= - for i in "${_PYTHON_ALL_IMPLS[@]}"; do - has "${i}" "${PYTHON_COMPAT[@]}" || continue - + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do python_export "${i}" PYTHON_PKG_DEP PYTHON_DEPS="${PYTHON_PKG_DEP} ${PYTHON_DEPS}" done PYTHON_DEPS="|| ( ${PYTHON_DEPS})" + readonly PYTHON_DEPS } -_python_build_set_globals +_python_any_set_globals +unset -f _python_any_set_globals # @ECLASS-VARIABLE: PYTHON_USEDEP # @DESCRIPTION: @@ -191,10 +201,10 @@ _python_build_set_globals # dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] ) # ) # ( -# dev-lang/python:2.6 -# dev-python/foo[python_targets_python2_6(-)?,python_single_target_python2_6(+)?] -# || ( dev-python/bar[python_targets_python2_6(-)?,python_single_target_python2_6(+)?] -# dev-python/baz[python_targets_python2_6(-)?,python_single_target_python2_6(+)?] ) +# dev-lang/python:3.3 +# dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] +# || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] +# dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] ) # ) # ) # @CODE @@ -205,9 +215,7 @@ python_gen_any_dep() { [[ ${depstr} ]] || die "No dependency string provided" local PYTHON_PKG_DEP out= - for i in "${_PYTHON_ALL_IMPLS[@]}"; do - has "${i}" "${PYTHON_COMPAT[@]}" || continue - + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)" python_export "${i}" PYTHON_PKG_DEP @@ -238,7 +246,7 @@ _python_EPYTHON_supported() { ;; esac - if has "${i}" "${PYTHON_COMPAT[@]}"; then + if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then if python_is_installed "${i}"; then if declare -f python_check_deps >/dev/null; then local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)" @@ -263,6 +271,23 @@ _python_EPYTHON_supported() { python_setup() { debug-print-function ${FUNCNAME} "${@}" + # support developer override + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then + local impls=( ${PYTHON_COMPAT_OVERRIDE} ) + [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r1" + + ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python" + ewarn "implementation will be used:" + ewarn + ewarn " ${PYTHON_COMPAT_OVERRIDE}" + ewarn + ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored." + + python_export "${impls[0]}" EPYTHON PYTHON + python_wrapper_setup + return + fi + # first, try ${EPYTHON}... maybe it's good enough for us. if [[ ${EPYTHON} ]]; then if _python_EPYTHON_supported "${EPYTHON}"; then @@ -288,15 +313,9 @@ python_setup() { done # fallback to best installed impl. - local rev_impls=() - for i in "${_PYTHON_ALL_IMPLS[@]}"; do - if has "${i}" "${PYTHON_COMPAT[@]}"; then - rev_impls=( "${i}" "${rev_impls[@]}" ) - fi - done - - for i in "${rev_impls[@]}"; do - python_export "${i}" EPYTHON PYTHON + # (reverse iteration over _PYTHON_SUPPORTED_IMPLS) + for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do + python_export "${_PYTHON_SUPPORTED_IMPLS[i]}" EPYTHON PYTHON if _python_EPYTHON_supported "${EPYTHON}"; then python_wrapper_setup return diff --git a/sdk_container/src/third_party/portage-stable/eclass/python-r1.eclass b/sdk_container/src/third_party/portage-stable/eclass/python-r1.eclass index 0a509a00a4..610657776d 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python-r1.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python-r1.eclass @@ -1,8 +1,8 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python-r1.eclass,v 1.90 2015/03/21 14:55:33 mgorny Exp $ +# $Id$ -# @ECLASS: python-r1 +# @ECLASS: python-r1.eclass # @MAINTAINER: # Python team # @AUTHOR: @@ -26,8 +26,8 @@ # in the packages using python-r1, and there is no need ever to inherit # both. # -# For more information, please see the python-r1 Developer's Guide: -# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml +# For more information, please see the wiki: +# https://wiki.gentoo.org/wiki/Project:Python/python-r1 case "${EAPI:-0}" in 0|1|2|3) @@ -47,7 +47,7 @@ case "${EAPI:-0}" in die "Unsupported EAPI=${EAPI:-4} (too old, allowed only on restricted set of packages) for ${ECLASS}" fi ;; - 5) + 5|6) # EAPI=5 is required for sane USE_EXPAND dependencies ;; *) @@ -63,6 +63,7 @@ elif [[ ${_PYTHON_ANY_R1} ]]; then die 'python-r1.eclass can not be used with python-any-r1.eclass.' fi +[[ ${EAPI} == [45] ]] && inherit eutils inherit multibuild python-utils-r1 # @ECLASS-VARIABLE: PYTHON_COMPAT @@ -74,16 +75,13 @@ inherit multibuild python-utils-r1 # # Example: # @CODE -# PYTHON_COMPAT=( python2_5 python2_6 python2_7 ) +# PYTHON_COMPAT=( python2_7 python3_3 python3_4} ) # @CODE # # Please note that you can also use bash brace expansion if you like: # @CODE -# PYTHON_COMPAT=( python{2_5,2_6,2_7} ) +# PYTHON_COMPAT=( python2_7 python3_{3,4} ) # @CODE -if ! declare -p PYTHON_COMPAT &>/dev/null; then - die 'PYTHON_COMPAT not declared.' -fi # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE # @INTERNAL @@ -139,8 +137,8 @@ fi # Example value: # @CODE # dev-lang/python-exec:= -# python_targets_python2_6? ( dev-lang/python:2.6[gdbm] ) # python_targets_python2_7? ( dev-lang/python:2.7[gdbm] ) +# python_targets_pypy? ( virtual/pypy[gdbm] ) # @CODE # @ECLASS-VARIABLE: PYTHON_USEDEP @@ -160,7 +158,7 @@ fi # # Example value: # @CODE -# python_targets_python2_6(-)?,python_targets_python2_7(-)? +# python_targets_python2_7(-)?,python_targets_python3_4(-)? # @CODE # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE @@ -178,28 +176,21 @@ fi # # Example value: # @CODE -# || ( python_targets_python2_6 python_targets_python2_7 ) +# || ( python_targets_python2_7 python_targets_python3_4 ) # @CODE _python_set_globals() { - local impls=() - PYTHON_DEPS= local i PYTHON_PKG_DEP - for i in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${i}" || continue + _python_set_impls + + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do python_export "${i}" PYTHON_PKG_DEP PYTHON_DEPS+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) " - - impls+=( "${i}" ) done - if [[ ${#impls[@]} -eq 0 ]]; then - die "No supported implementation in PYTHON_COMPAT." - fi - - local flags=( "${impls[@]/#/python_targets_}" ) + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" ) local optflags=${flags[@]/%/(-)?} # A nice QA trick here. Since a python-single-r1 package has to have @@ -208,7 +199,7 @@ _python_set_globals() { # it should prevent developers from mistakenly depending on packages # not supporting multiple Python implementations. - local flags_st=( "${impls[@]/#/-python_single_target_}" ) + local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" ) optflags+=,${flags_st[@]/%/(-)} IUSE=${flags[*]} @@ -228,8 +219,10 @@ _python_set_globals() { else PYTHON_DEPS+="dev-lang/python-exec:2[${PYTHON_USEDEP}]" fi + readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP } _python_set_globals +unset -f _python_set_globals # @FUNCTION: _python_validate_useflags # @INTERNAL @@ -240,9 +233,7 @@ _python_validate_useflags() { local i - for i in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${i}" || continue - + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do use "python_targets_${i}" && return 0 done @@ -284,9 +275,7 @@ python_gen_usedep() { local impl pattern local matches=() - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then matches+=( @@ -327,9 +316,7 @@ python_gen_useflags() { local impl pattern local matches=() - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then matches+=( "python_targets_${impl}" ) @@ -355,17 +342,17 @@ python_gen_useflags() { # # Example: # @CODE -# PYTHON_COMPAT=( python{2_5,2_6,2_7} ) +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy ) # RDEPEND="$(python_gen_cond_dep \ -# 'dev-python/unittest2[${PYTHON_USEDEP}]' python{2_5,2_6})" +# 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )" # @CODE # # It will cause the variable to look like: # @CODE -# RDEPEND="python_targets_python2_5? ( -# dev-python/unittest2[python_targets_python2_5?] ) -# python_targets_python2_6? ( -# dev-python/unittest2[python_targets_python2_6?] )" +# RDEPEND="python_targets_python2_7? ( +# dev-python/unittest2[python_targets_python2_7?] ) +# python_targets_pypy? ( +# dev-python/unittest2[python_targets_pypy?] )" # @CODE python_gen_cond_dep() { debug-print-function ${FUNCNAME} "${@}" @@ -376,17 +363,15 @@ python_gen_cond_dep() { local dep=${1} shift - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then # substitute ${PYTHON_USEDEP} if used # (since python_gen_usedep() will not return ${PYTHON_USEDEP} # the code is run at most once) if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then - local PYTHON_USEDEP=$(python_gen_usedep "${@}") - dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}} + local usedep=$(python_gen_usedep "${@}") + dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}} fi matches+=( "python_targets_${impl}? ( ${dep} )" ) @@ -398,6 +383,58 @@ python_gen_cond_dep() { echo "${matches[@]}" } +# @FUNCTION: python_gen_impl_dep +# @USAGE: [ [...]] +# @DESCRIPTION: +# Output a dependency on Python implementations with the specified USE +# dependency string appended, or no USE dependency string if called +# without the argument (or with empty argument). If any implementation +# patterns are passed, the output dependencies will be generated only +# for the implementations matching them. +# +# Use this function when you need to request different USE flags +# on the Python interpreter depending on package's USE flags. If you +# only need a single set of interpreter USE flags, just set +# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally. +# +# Example: +# @CODE +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy ) +# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )" +# @CODE +# +# It will cause the variable to look like: +# @CODE +# RDEPEND="foo? ( +# python_targets_python2_7? ( +# dev-lang/python:2.7[xml(+)] ) +# python_targets_pypy? ( +# dev-python/pypy[xml(+)] ) )" +# @CODE +python_gen_impl_dep() { + debug-print-function ${FUNCNAME} "${@}" + + local impl pattern + local matches=() + + local PYTHON_REQ_USE=${1} + shift + + local patterns=( "${@-*}" ) + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do + for pattern in "${patterns[@]}"; do + if [[ ${impl} == ${pattern} ]]; then + local PYTHON_PKG_DEP + python_export "${impl}" PYTHON_PKG_DEP + matches+=( "python_targets_${impl}? ( ${PYTHON_PKG_DEP} )" ) + break + fi + done + done + + echo "${matches[@]}" +} + # @ECLASS-VARIABLE: BUILD_DIR # @DESCRIPTION: # The current build directory. In global scope, it is supposed to @@ -410,7 +447,7 @@ python_gen_cond_dep() { # # Example value: # @CODE -# ${WORKDIR}/foo-1.3-python2_6 +# ${WORKDIR}/foo-1.3-python2_7 # @CODE # @FUNCTION: python_copy_sources @@ -430,220 +467,6 @@ python_copy_sources() { multibuild_copy_sources } -# @FUNCTION: _python_check_USE_PYTHON -# @INTERNAL -# @DESCRIPTION: -# Check whether USE_PYTHON and PYTHON_TARGETS are in sync. Output -# warnings if they are not. -_python_check_USE_PYTHON() { - debug-print-function ${FUNCNAME} "${@}" - - if [[ ! ${_PYTHON_USE_PYTHON_CHECKED} ]]; then - _PYTHON_USE_PYTHON_CHECKED=1 - - # python-exec has profile-forced flags. - if [[ ${CATEGORY}/${PN} == dev-lang/python-exec ]]; then - return - fi - - _try_eselect() { - # The eselect solution will work only with one py2 & py3. - - local impl py2 py3 dis_py2 dis_py3 - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - - if use "python_targets_${impl}"; then - case "${impl}" in - python2_*) - if [[ ${py2+1} ]]; then - debug-print "${FUNCNAME}: -> more than one py2: ${py2} ${impl}" - return 1 - fi - py2=${impl/_/.} - ;; - python3_4) - debug-print "${FUNCNAME}: python3.4 found, not using eselect" - return 1 - ;; - python3_*) - if [[ ${py3+1} ]]; then - debug-print "${FUNCNAME}: -> more than one py3: ${py3} ${impl}" - return 1 - fi - py3=${impl/_/.} - ;; - *) - return 1 - ;; - esac - else - case "${impl}" in - python2_*) - dis_py2=1 - ;; - python3_*) - dis_py3=1 - ;; - esac - fi - done - - # The eselect solution won't work if the disabled Python version - # is installed. - if [[ ! ${py2+1} && ${dis_py2} ]]; then - debug-print "${FUNCNAME}: -> all py2 versions disabled" - if ! has python2_7 "${PYTHON_COMPAT[@]}"; then - debug-print "${FUNCNAME}: ---> package does not support 2.7" - return 0 - fi - if has_version '=dev-lang/python-2*'; then - debug-print "${FUNCNAME}: ---> but =python-2* installed!" - return 1 - fi - fi - if [[ ! ${py3+1} && ${dis_py3} ]]; then - debug-print "${FUNCNAME}: -> all py3 versions disabled" - if ! has python3_2 "${PYTHON_COMPAT[@]}"; then - debug-print "${FUNCNAME}: ---> package does not support 3.2" - return 0 - fi - if has_version '=dev-lang/python-3*'; then - debug-print "${FUNCNAME}: ---> but =python-3* installed!" - return 1 - fi - fi - - local warned - - # Now check whether the correct implementations are active. - if [[ ${py2+1} ]]; then - local sel_py2=$(eselect python show --python2) - - debug-print "${FUNCNAME}: -> py2 built: ${py2}, active: ${sel_py2}" - if [[ ${py2} != ${sel_py2} ]]; then - ewarn "Building package for ${py2} only while ${sel_py2} is active." - ewarn "Please consider switching the active Python 2 interpreter:" - ewarn - ewarn " eselect python set --python2 ${py2}" - warned=1 - fi - fi - - - if [[ ${py3+1} ]]; then - local sel_py3=$(eselect python show --python3) - - debug-print "${FUNCNAME}: -> py3 built: ${py3}, active: ${sel_py3}" - if [[ ${py3} != ${sel_py3} ]]; then - [[ ${warned} ]] && ewarn - ewarn "Building package for ${py3} only while ${sel_py3} is active." - ewarn "Please consider switching the active Python 3 interpreter:" - ewarn - ewarn " eselect python set --python3 ${py3}" - warned=1 - fi - fi - - if [[ ${warned} ]]; then - ewarn - ewarn "Please note that after switching the active Python interpreter," - ewarn "you may need to run 'python-updater' to rebuild affected packages." - ewarn - ewarn "For more information on PYTHON_TARGETS and python.eclass" - ewarn "compatibility, please see the relevant Wiki article [1]." - ewarn - ewarn "[1] https://wiki.gentoo.org/wiki/Project:Python/PYTHON_TARGETS" - fi - } - - # If user has no USE_PYTHON, try to avoid it. - if [[ ! ${USE_PYTHON} ]]; then - debug-print "${FUNCNAME}: trying eselect solution ..." - _try_eselect && return - fi - - debug-print "${FUNCNAME}: trying USE_PYTHON solution ..." - debug-print "${FUNCNAME}: -> USE_PYTHON=${USE_PYTHON}" - - local impl old=${USE_PYTHON} new=() removed=() - - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - - local abi - case "${impl}" in - pypy|pypy3|python3_4) - # unsupported in python.eclass - continue - ;; - python*) - abi=${impl#python} - ;; - jython*) - abi=${impl#jython}-jython - ;; - *) - die "Unexpected Python implementation: ${impl}" - ;; - esac - abi=${abi/_/.} - - has "${abi}" ${USE_PYTHON} - local has_abi=${?} - use "python_targets_${impl}" - local has_impl=${?} - - # 0 = has, 1 = does not have - if [[ ${has_abi} == 0 && ${has_impl} == 1 ]]; then - debug-print "${FUNCNAME}: ---> remove ${abi}" - # remove from USE_PYTHON - old=${old/${abi}/} - removed+=( ${abi} ) - elif [[ ${has_abi} == 1 && ${has_impl} == 0 ]]; then - debug-print "${FUNCNAME}: ---> add ${abi}" - # add to USE_PYTHON - new+=( ${abi} ) - fi - done - - if [[ ${removed[@]} || ${new[@]} ]]; then - old=( ${old} ) - - debug-print "${FUNCNAME}: -> old: ${old[@]}" - debug-print "${FUNCNAME}: -> new: ${new[@]}" - debug-print "${FUNCNAME}: -> removed: ${removed[@]}" - - if [[ ${USE_PYTHON} ]]; then - ewarn "It seems that your USE_PYTHON setting lists different Python" - ewarn "implementations than your PYTHON_TARGETS variable. Please consider" - ewarn "using the following value instead:" - ewarn - ewarn " USE_PYTHON='\033[35m${old[@]}${new[@]+ \033[1m${new[@]}}\033[0m'" - - if [[ ${removed[@]} ]]; then - ewarn - ewarn "(removed \033[31m${removed[@]}\033[0m)" - fi - else - ewarn "It seems that you need to set USE_PYTHON to make sure that legacy" - ewarn "packages will be built with respect to PYTHON_TARGETS correctly:" - ewarn - ewarn " USE_PYTHON='\033[35;1m${new[@]}\033[0m'" - fi - - ewarn - ewarn "Please note that after changing the USE_PYTHON variable, you may need" - ewarn "to run 'python-updater' to rebuild affected packages." - ewarn - ewarn "For more information on PYTHON_TARGETS and python.eclass" - ewarn "compatibility, please see the relevant Wiki article [1]." - ewarn - ewarn "[1] https://wiki.gentoo.org/wiki/Project:Python/PYTHON_TARGETS" - fi - fi -} - # @FUNCTION: _python_obtain_impls # @INTERNAL # @DESCRIPTION: @@ -665,16 +488,12 @@ _python_obtain_impls() { fi _python_validate_useflags - _python_check_USE_PYTHON MULTIBUILD_VARIANTS=() - for impl in "${_PYTHON_ALL_IMPLS[@]}"; do - if has "${impl}" "${PYTHON_COMPAT[@]}" \ - && use "python_targets_${impl}" - then - MULTIBUILD_VARIANTS+=( "${impl}" ) - fi + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do + has "${impl}" "${PYTHON_COMPAT[@]}" && \ + use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" ) done } @@ -738,6 +557,8 @@ python_foreach_impl() { python_parallel_foreach_impl() { debug-print-function ${FUNCNAME} "${@}" + [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}" + if [[ ! ${_PYTHON_PARALLEL_WARNED} ]]; then eqawarn "python_parallel_foreach_impl() is no longer meaningful. All runs" eqawarn "are non-parallel now. Please replace the call with python_foreach_impl." @@ -790,6 +611,7 @@ python_setup() { done } python_foreach_impl _python_try_impl + unset -f _python_try_impl if [[ ! ${best_impl} ]]; then eerror "${FUNCNAME}: none of the enabled implementation matched the patterns." @@ -813,6 +635,8 @@ python_setup() { python_export_best() { debug-print-function ${FUNCNAME} "${@}" + [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}" + eqawarn "python_export_best() is deprecated. Please use python_setup instead," eqawarn "combined with python_export if necessary." @@ -825,6 +649,7 @@ python_export_best() { best=${MULTIBUILD_VARIANT} } multibuild_for_best_variant _python_set_best + unset -f _python_set_best debug-print "${FUNCNAME}: Best implementation is: ${best}" python_export "${best}" "${@}" @@ -859,6 +684,7 @@ python_replicate_script() { local files=( "${@}" ) python_foreach_impl _python_replicate_script + unset -f _python_replicate_script # install the wrappers local f diff --git a/sdk_container/src/third_party/portage-stable/eclass/python-single-r1.eclass b/sdk_container/src/third_party/portage-stable/eclass/python-single-r1.eclass index 9480512ac8..9e80866bfb 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python-single-r1.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python-single-r1.eclass @@ -1,8 +1,8 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python-single-r1.eclass,v 1.38 2015/03/22 13:41:16 mgorny Exp $ +# $Id$ -# @ECLASS: python-single-r1 +# @ECLASS: python-single-r1.eclass # @MAINTAINER: # Python team # @AUTHOR: @@ -28,8 +28,8 @@ # in the packages using python-single-r1, and there is no need ever # to inherit both. # -# For more information, please see the python-r1 Developer's Guide: -# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml +# For more information, please see the wiki: +# https://wiki.gentoo.org/wiki/Project:Python/python-single-r1 case "${EAPI:-0}" in 0|1|2|3) @@ -55,7 +55,7 @@ case "${EAPI:-0}" in die "Unsupported EAPI=${EAPI:-4} (too old, allowed only on restricted set of packages) for ${ECLASS}" fi ;; - 5) + 5|6) # EAPI=5 is required for sane USE_EXPAND dependencies ;; *) @@ -88,11 +88,32 @@ if [[ ! ${_PYTHON_SINGLE_R1} ]]; then # # Example: # @CODE -# PYTHON_COMPAT=( python{2_5,2_6,2_7} ) +# PYTHON_COMPAT=( python2_7 python3_3 python3_4} ) +# @CODE +# +# Please note that you can also use bash brace expansion if you like: +# @CODE +# PYTHON_COMPAT=( python2_7 python3_{3,4} ) +# @CODE + +# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE +# @INTERNAL +# @DESCRIPTION: +# This variable can be used when working with ebuilds to override +# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation +# which package will be built for. It needs to be specified +# in the calling environment, and not in ebuilds. +# +# It should be noted that in order to preserve metadata immutability, +# PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies. +# The state of PYTHON_TARGETS and PYTHON_SINGLE_TARGET is ignored, +# and the implementation in PYTHON_COMPAT_OVERRIDE is built instead. +# Dependencies need to be satisfied manually. +# +# Example: +# @CODE +# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar # @CODE -if ! declare -p PYTHON_COMPAT &>/dev/null; then - die 'PYTHON_COMPAT not declared.' -fi # @ECLASS-VARIABLE: PYTHON_REQ_USE # @DEFAULT_UNSET @@ -131,8 +152,8 @@ fi # Example value: # @CODE # dev-lang/python-exec:= -# python_single_target_python2_6? ( dev-lang/python:2.6[gdbm] ) # python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] ) +# python_single_target_pypy? ( virtual/pypy[gdbm] ) # @CODE # @ECLASS-VARIABLE: PYTHON_USEDEP @@ -152,7 +173,7 @@ fi # # Example value: # @CODE -# python_targets_python2_7(-)?,python_single_target_python2_7(+)? +# python_targets_python2_7(-)?,python_single_target_python3_4(+)? # @CODE # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE @@ -172,40 +193,30 @@ fi # # Example value: # @CODE -# python_single_target_python2_6? ( python_targets_python2_6 ) # python_single_target_python2_7? ( python_targets_python2_7 ) -# ^^ ( python_single_target_python2_6 python_single_target_python2_7 ) +# python_single_target_python3_3? ( python_targets_python3_3 ) +# ^^ ( python_single_target_python2_7 python_single_target_python3_3 ) # @CODE _python_single_set_globals() { - local impls=() - local unimpls=() + _python_set_impls PYTHON_DEPS= local i PYTHON_PKG_DEP - for i in "${_PYTHON_ALL_IMPLS[@]}"; do - has "${i}" "${PYTHON_COMPAT[@]}" \ - && impls+=( "${i}" ) \ - || unimpls+=( "${i}" ) - done - if [[ ${#impls[@]} -eq 0 ]]; then - die "No supported implementation in PYTHON_COMPAT." - fi - - local flags_mt=( "${impls[@]/#/python_targets_}" ) - local flags=( "${impls[@]/#/python_single_target_}" ) - local unflags=( "${unimpls[@]/#/-python_single_target_}" ) + local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" ) + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" ) + local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" ) local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)} IUSE="${flags_mt[*]}" - if [[ ${#impls[@]} -eq 1 ]]; then + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then # There is only one supported implementation; set IUSE and other # variables without PYTHON_SINGLE_TARGET. PYTHON_REQUIRED_USE="${flags_mt[*]}" - python_export "${impls[0]}" PYTHON_PKG_DEP + python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP PYTHON_DEPS="${PYTHON_PKG_DEP} " # Force on the python_single_target_* flag for this impl, so # that any dependencies that inherit python-single-r1 and @@ -220,7 +231,7 @@ _python_single_set_globals() { # on this package. optflags+=,${flags[@]/%/(+)?} - for i in "${impls[@]}"; do + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do # The chosen targets need to be in PYTHON_TARGETS as well. # This is in order to enforce correct dependencies on packages # supporting multiple implementations. @@ -245,8 +256,10 @@ _python_single_set_globals() { else PYTHON_DEPS+="dev-lang/python-exec:2[${PYTHON_USEDEP}]" fi + readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_USEDEP } _python_single_set_globals +unset -f _python_single_set_globals # @FUNCTION: python_gen_usedep # @USAGE: [...] @@ -278,9 +291,7 @@ python_gen_usedep() { local impl pattern local matches=() - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then matches+=( @@ -318,15 +329,19 @@ python_gen_usedep() { python_gen_useflags() { debug-print-function ${FUNCNAME} "${@}" - local impl pattern + local flag_prefix impl pattern local matches=() - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + flag_prefix=python_targets + else + flag_prefix=python_single_target + fi + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then - matches+=( "python_single_target_${impl}" ) + matches+=( "${flag_prefix}_${impl}" ) break fi done @@ -349,41 +364,103 @@ python_gen_useflags() { # # Example: # @CODE -# PYTHON_COMPAT=( python{2_5,2_6,2_7} ) +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy ) # RDEPEND="$(python_gen_cond_dep \ -# 'dev-python/unittest2[${PYTHON_USEDEP}]' python{2_5,2_6})" +# 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )" # @CODE # # It will cause the variable to look like: # @CODE -# RDEPEND="python_single_target_python2_5? ( -# dev-python/unittest2[python_targets_python2_5(-)?,...] ) -# python_single_target_python2_6? ( -# dev-python/unittest2[python_targets_python2_6(-)?,...] )" +# RDEPEND="python_single_target_python2_7? ( +# dev-python/unittest2[python_targets_python2_7(-)?,...] ) +# python_single_target_pypy? ( +# dev-python/unittest2[python_targets_pypy(-)?,...] )" # @CODE python_gen_cond_dep() { debug-print-function ${FUNCNAME} "${@}" - local impl pattern + local flag_prefix impl pattern local matches=() + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + flag_prefix=python_targets + else + flag_prefix=python_single_target + fi + local dep=${1} shift - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do for pattern; do if [[ ${impl} == ${pattern} ]]; then # substitute ${PYTHON_USEDEP} if used # (since python_gen_usedep() will not return ${PYTHON_USEDEP} # the code is run at most once) if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then - local PYTHON_USEDEP=$(python_gen_usedep "${@}") - dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}} + local usedep=$(python_gen_usedep "${@}") + dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}} fi - matches+=( "python_single_target_${impl}? ( ${dep} )" ) + matches+=( "${flag_prefix}_${impl}? ( ${dep} )" ) + break + fi + done + done + + echo "${matches[@]}" +} + +# @FUNCTION: python_gen_impl_dep +# @USAGE: [ [...]] +# @DESCRIPTION: +# Output a dependency on Python implementations with the specified USE +# dependency string appended, or no USE dependency string if called +# without the argument (or with empty argument). If any implementation +# patterns are passed, the output dependencies will be generated only +# for the implementations matching them. +# +# Use this function when you need to request different USE flags +# on the Python interpreter depending on package's USE flags. If you +# only need a single set of interpreter USE flags, just set +# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally. +# +# Example: +# @CODE +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy ) +# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )" +# @CODE +# +# It will cause the variable to look like: +# @CODE +# RDEPEND="foo? ( +# python_single_target_python2_7? ( +# dev-lang/python:2.7[xml(+)] ) +# python_single_target_pypy? ( +# dev-python/pypy[xml(+)] ) )" +# @CODE +python_gen_impl_dep() { + debug-print-function ${FUNCNAME} "${@}" + + local impl pattern + local matches=() + + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + flag_prefix=python_targets + else + flag_prefix=python_single_target + fi + + local PYTHON_REQ_USE=${1} + shift + + local patterns=( "${@-*}" ) + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do + for pattern in "${patterns[@]}"; do + if [[ ${impl} == ${pattern} ]]; then + local PYTHON_PKG_DEP + python_export "${impl}" PYTHON_PKG_DEP + matches+=( "${flag_prefix}_${impl}? ( ${PYTHON_PKG_DEP} )" ) break fi done @@ -401,20 +478,32 @@ python_setup() { unset EPYTHON - local impl impls=() - for impl in "${PYTHON_COMPAT[@]}"; do - _python_impl_supported "${impl}" || continue - impls+=( "${impl}" ) - done + # support developer override + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then + local impls=( ${PYTHON_COMPAT_OVERRIDE} ) + [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r1" - if [[ ${#impls[@]} -eq 1 ]]; then - if use "python_targets_${impls[0]}"; then + ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python" + ewarn "implementation will be used:" + ewarn + ewarn " ${PYTHON_COMPAT_OVERRIDE}" + ewarn + ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored." + + python_export "${impls[0]}" EPYTHON PYTHON + python_wrapper_setup + return + fi + + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then + if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then # Only one supported implementation, enable it explicitly - python_export "${impls[0]}" EPYTHON PYTHON + python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON python_wrapper_setup fi else - for impl in "${impls[@]}"; do + local impl + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do if use "python_single_target_${impl}"; then if [[ ${EPYTHON} ]]; then eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python" @@ -442,14 +531,14 @@ python_setup() { if [[ ! ${EPYTHON} ]]; then eerror "No Python implementation selected for the build. Please set" - if [[ ${#impls[@]} -eq 1 ]]; then + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then eerror "the PYTHON_TARGETS variable in your make.conf to include one" else eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one" fi eerror "of the following values:" eerror - eerror "${impls[@]}" + eerror "${_PYTHON_SUPPORTED_IMPLS[@]}" echo die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS." fi diff --git a/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass b/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass index 576132d8bd..89a7cbf2a1 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass @@ -1,8 +1,8 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python-utils-r1.eclass,v 1.82 2015/03/21 14:55:33 mgorny Exp $ +# $Id$ -# @ECLASS: python-utils-r1 +# @ECLASS: python-utils-r1.eclass # @MAINTAINER: # Python team # @AUTHOR: @@ -16,11 +16,11 @@ # This eclass does not set any metadata variables nor export any phase # functions. It can be inherited safely. # -# For more information, please see the python-r1 Developer's Guide: -# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml +# For more information, please see the wiki: +# https://wiki.gentoo.org/wiki/Project:Python/python-utils-r1 case "${EAPI:-0}" in - 0|1|2|3|4|5) + 0|1|2|3|4|5|6) ;; *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" @@ -33,18 +33,20 @@ fi if [[ ! ${_PYTHON_UTILS_R1} ]]; then -inherit eutils multilib toolchain-funcs +[[ ${EAPI:-0} == [012345] ]] && inherit eutils multilib +inherit toolchain-funcs # @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS # @INTERNAL # @DESCRIPTION: # All supported Python implementations, most preferred last. _PYTHON_ALL_IMPLS=( - jython2_5 jython2_7 - pypy pypy3 - python3_3 python3_4 python3_5 python2_7 + python3_3 python3_4 python3_5 + pypy pypy3 + jython2_7 ) +readonly _PYTHON_ALL_IMPLS # @FUNCTION: _python_impl_supported # @USAGE: @@ -66,7 +68,7 @@ _python_impl_supported() { # keep in sync with _PYTHON_ALL_IMPLS! # (not using that list because inline patterns shall be faster) case "${impl}" in - python2_7|python3_[345]|jython2_[57]) + python2_7|python3_[345]|jython2_7) return 0 ;; pypy1_[89]|pypy2_0|python2_[56]|python3_[12]) @@ -82,6 +84,55 @@ _python_impl_supported() { esac } +# @FUNCTION: _python_set_impls +# @INTERNAL +# @DESCRIPTION: +# Check PYTHON_COMPAT for well-formedness and validity, then set +# two global variables: +# +# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported +# by the ebuild (PYTHON_COMPAT - dead implementations), +# +# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that +# are not supported by the ebuild. +# +# Implementations in both variables are ordered using the pre-defined +# eclass implementation ordering. +# +# This function must be called once in global scope by an eclass +# utilizing PYTHON_COMPAT. +_python_set_impls() { + local i + + if ! declare -p PYTHON_COMPAT &>/dev/null; then + die 'PYTHON_COMPAT not declared.' + fi + if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then + die 'PYTHON_COMPAT must be an array.' + fi + for i in "${PYTHON_COMPAT[@]}"; do + # trigger validity checks + _python_impl_supported "${i}" + done + + _PYTHON_SUPPORTED_IMPLS=() + _PYTHON_UNSUPPORTED_IMPLS=() + + for i in "${_PYTHON_ALL_IMPLS[@]}"; do + if has "${i}" "${PYTHON_COMPAT[@]}"; then + _PYTHON_SUPPORTED_IMPLS+=( "${i}" ) + else + _PYTHON_UNSUPPORTED_IMPLS+=( "${i}" ) + fi + done + + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 0 ]]; then + die "No supported implementation in PYTHON_COMPAT." + fi + + readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS +} + # @ECLASS-VARIABLE: PYTHON # @DEFAULT_UNSET # @DESCRIPTION: @@ -126,6 +177,7 @@ _python_impl_supported() { # The path to Python site-packages directory. # # Set and exported on request using python_export(). +# Requires a proper build-time dependency on the Python implementation. # # Example value: # @CODE @@ -138,6 +190,7 @@ _python_impl_supported() { # The path to Python include directory. # # Set and exported on request using python_export(). +# Requires a proper build-time dependency on the Python implementation. # # Example value: # @CODE @@ -150,7 +203,8 @@ _python_impl_supported() { # The path to Python library. # # Set and exported on request using python_export(). -# Valid only for CPython. +# Valid only for CPython. Requires a proper build-time dependency +# on the Python implementation. # # Example value: # @CODE @@ -187,6 +241,20 @@ _python_impl_supported() { # -lpython2.7 # @CODE +# @ECLASS-VARIABLE: PYTHON_CONFIG +# @DEFAULT_UNSET +# @DESCRIPTION: +# Path to the python-config executable. +# +# Set and exported on request using python_export(). +# Valid only for CPython. Requires a proper build-time dependency +# on the Python implementation and on pkg-config. +# +# Example value: +# @CODE +# /usr/bin/python2.7-config +# @CODE + # @ECLASS-VARIABLE: PYTHON_PKG_DEP # @DEFAULT_UNSET # @DESCRIPTION: @@ -259,51 +327,34 @@ python_export() { debug-print "${FUNCNAME}: PYTHON = ${PYTHON}" ;; PYTHON_SITEDIR) - local dir - case "${impl}" in - python*|pypy|pypy3) - dir=/usr/$(get_libdir)/${impl} - ;; - jython*) - dir=/usr/share/${impl/n/n-}/Lib - ;; - esac - - export PYTHON_SITEDIR=${EPREFIX}${dir}/site-packages + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" + # sysconfig can't be used because: + # 1) pypy doesn't give site-packages but stdlib + # 2) jython gives paths with wrong case + PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die + export PYTHON_SITEDIR debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}" ;; PYTHON_INCLUDEDIR) - local dir - case "${impl}" in - python*) - dir=/usr/include/${impl} - ;; - pypy|pypy3) - dir=/usr/$(get_libdir)/${impl}/include - ;; - *) - die "${impl} lacks header files" - ;; - esac - - export PYTHON_INCLUDEDIR=${EPREFIX}${dir} + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" + PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die + export PYTHON_INCLUDEDIR debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}" + + # Jython gives a non-existing directory + if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then + die "${impl} does not install any header files!" + fi ;; PYTHON_LIBPATH) - local libname - case "${impl}" in - python*) - libname=lib${impl} - ;; - *) - die "${impl} lacks a dynamic library" - ;; - esac - - local path=${EPREFIX}/usr/$(get_libdir) - - export PYTHON_LIBPATH=${path}/${libname}$(get_libname) + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" + PYTHON_LIBPATH=$("${PYTHON}" -c 'import os.path, sysconfig; print(os.path.join(sysconfig.get_config_var("LIBDIR"), sysconfig.get_config_var("LDLIBRARY")) if sysconfig.get_config_var("LDLIBRARY") else "")') || die + export PYTHON_LIBPATH debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}" + + if [[ ! ${PYTHON_LIBPATH} ]]; then + die "${impl} lacks a (usable) dynamic library" + fi ;; PYTHON_CFLAGS) local val @@ -311,7 +362,7 @@ python_export() { case "${impl}" in python*) # python-2.7, python-3.2, etc. - val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) + val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die ;; *) die "${impl}: obtaining ${var} not supported" @@ -327,7 +378,7 @@ python_export() { case "${impl}" in python*) # python-2.7, python-3.2, etc. - val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) + val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die ;; *) die "${impl}: obtaining ${var} not supported" @@ -337,6 +388,23 @@ python_export() { export PYTHON_LIBS=${val} debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}" ;; + PYTHON_CONFIG) + local flags val + + case "${impl}" in + python*) + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" + flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die + val=${PYTHON}${flags}-config + ;; + *) + die "${impl}: obtaining ${var} not supported" + ;; + esac + + export PYTHON_CONFIG=${val} + debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}" + ;; PYTHON_PKG_DEP) local d case ${impl} in @@ -350,8 +418,6 @@ python_export() { PYTHON_PKG_DEP='virtual/pypy:0=';; pypy3) PYTHON_PKG_DEP='virtual/pypy3:0=';; - jython2.5) - PYTHON_PKG_DEP='>=dev-java/jython-2.5.3-r2:2.5';; jython2.7) PYTHON_PKG_DEP='dev-java/jython:2.7';; *) @@ -457,6 +523,23 @@ python_get_LIBS() { echo "${PYTHON_LIBS}" } +# @FUNCTION: python_get_PYTHON_CONFIG +# @USAGE: [] +# @DESCRIPTION: +# Obtain and print the PYTHON_CONFIG location for the given +# implementation. If no implementation is provided, ${EPYTHON} will be +# used. +# +# Please note that this function can be used with CPython only. +# It requires Python installed, and therefore proper build-time +# dependencies need be added to the ebuild. +python_get_PYTHON_CONFIG() { + debug-print-function ${FUNCNAME} "${@}" + + python_export "${@}" PYTHON_CONFIG + echo "${PYTHON_CONFIG}" +} + # @FUNCTION: python_get_scriptdir # @USAGE: [] # @DESCRIPTION: @@ -533,9 +616,6 @@ python_optimize() { local PYTHON=${PYTHON} [[ ${PYTHON} ]] || python_export PYTHON - # Note: python2.6 can't handle passing files to compileall... - # TODO: we do not support 2.6 any longer - # default to sys.path if [[ ${#} -eq 0 ]]; then local f @@ -548,7 +628,7 @@ python_optimize() { if [[ ${f} == /* && -d ${D}${f} ]]; then set -- "${D}${f}" "${@}" fi - done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))') + done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))' || die) debug-print "${FUNCNAME}: using sys.path: ${*/%/;}" fi @@ -634,6 +714,9 @@ python_newexe() { [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).' [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} " + if [[ ${EAPI:-0} == [0123] ]]; then + die "python_do* and python_new* helpers are banned in EAPIs older than 4." + fi local wrapd=${python_scriptroot:-${DESTTREE}/bin} @@ -647,7 +730,7 @@ python_newexe() { ( dodir "${wrapd}" exeinto "${d}" - newexe "${f}" "${newfn}" || die + newexe "${f}" "${newfn}" || return ${?} ) # install the wrapper @@ -761,6 +844,9 @@ python_domodule() { debug-print-function ${FUNCNAME} "${@}" [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).' + if [[ ${EAPI:-0} == [0123] ]]; then + die "python_do* and python_new* helpers are banned in EAPIs older than 4." + fi local d if [[ ${python_moduleroot} == /* ]]; then @@ -774,10 +860,10 @@ python_domodule() { d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot} fi - local INSDESTTREE - - insinto "${d}" - doins -r "${@}" || die + ( + insinto "${d}" + doins -r "${@}" || return ${?} + ) python_optimize "${ED}/${d}" } @@ -799,16 +885,19 @@ python_doheader() { debug-print-function ${FUNCNAME} "${@}" [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).' + if [[ ${EAPI:-0} == [0123] ]]; then + die "python_do* and python_new* helpers are banned in EAPIs older than 4." + fi local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR} [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR d=${PYTHON_INCLUDEDIR#${EPREFIX}} - local INSDESTTREE - - insinto "${d}" - doins -r "${@}" || die + ( + insinto "${d}" + doins -r "${@}" || return ${?} + ) } # @FUNCTION: python_wrapper_setup @@ -840,29 +929,47 @@ python_wrapper_setup() { mkdir -p "${workdir}"/{bin,pkgconfig} || die # Clean up, in case we were supposed to do a cheap update. - rm -f "${workdir}"/bin/python{,2,3,-config} - rm -f "${workdir}"/bin/2to3 - rm -f "${workdir}"/pkgconfig/python{,2,3}.pc + rm -f "${workdir}"/bin/python{,2,3,-config} || die + rm -f "${workdir}"/bin/2to3 || die + rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die - local EPYTHON PYTHON + local EPYTHON PYTHON PYTHON_CONFIG python_export "${impl}" EPYTHON PYTHON - local pyver + local pyver pyother if python_is_python3; then pyver=3 + pyother=2 else pyver=2 + pyother=3 fi # Python interpreter - ln -s "${PYTHON}" "${workdir}"/bin/python || die - ln -s python "${workdir}"/bin/python${pyver} || die + # note: we don't use symlinks because python likes to do some + # symlink reading magic that breaks stuff + # https://bugs.gentoo.org/show_bug.cgi?id=555752 + cat > "${workdir}/bin/python" <<-_EOF_ || die + #!/bin/sh + exec "${PYTHON}" "\${@}" + _EOF_ + cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die + chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die - local nonsupp=() + local nonsupp=( "python${pyother}" "python${pyother}-config" ) # CPython-specific if [[ ${EPYTHON} == python* ]]; then - ln -s "${PYTHON}-config" "${workdir}"/bin/python-config || die + python_export "${impl}" PYTHON_CONFIG + + cat > "${workdir}/bin/python-config" <<-_EOF_ || die + #!/bin/sh + exec "${PYTHON_CONFIG}" "\${@}" + _EOF_ + cp "${workdir}/bin/python-config" \ + "${workdir}/bin/python${pyver}-config" || die + chmod +x "${workdir}/bin/python-config" \ + "${workdir}/bin/python${pyver}-config" || die # Python 2.6+. ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die @@ -872,16 +979,16 @@ python_wrapper_setup() { "${workdir}"/pkgconfig/python.pc || die ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die else - nonsupp+=( 2to3 python-config ) + nonsupp+=( 2to3 python-config "python${pyver}-config" ) fi local x for x in "${nonsupp[@]}"; do - cat >"${workdir}"/bin/${x} <<__EOF__ -#!/bin/sh -echo "${x} is not supported by ${EPYTHON}" >&2 -exit 1 -__EOF__ + cat >"${workdir}"/bin/${x} <<-_EOF_ || die + #!/bin/sh + echo "${x} is not supported by ${EPYTHON}" >&2 + exit 127 + _EOF_ chmod +x "${workdir}"/bin/${x} || die done @@ -989,12 +1096,14 @@ python_fix_shebang() { local shebang i local error= from= - IFS= read -r shebang <${f} + # note: we can't ||die here since read will fail if file + # has no newline characters + IFS= read -r shebang <"${f}" # First, check if it's shebang at all... if [[ ${shebang} == '#!'* ]]; then local split_shebang=() - read -r -a split_shebang <<<${shebang} + read -r -a split_shebang <<<${shebang} || die # Match left-to-right in a loop, to avoid matching random # repetitions like 'python2.7 python2'. @@ -1079,19 +1188,42 @@ python_fix_shebang() { eerror " requested impl: ${EPYTHON}" die "${FUNCNAME}: conversion of incompatible shebang requested" fi - done < <(find "${path}" -type f -print0) + done < <(find -H "${path}" -type f -print0 || die) if [[ ! ${any_fixed} ]]; then - eqawarn "QA warning: ${FUNCNAME}, ${path#${D}} did not match any fixable files." + local cmd=eerror + [[ ${EAPI:-0} == [012345] ]] && cmd=eqawarn + + "${cmd}" "QA warning: ${FUNCNAME}, ${path#${D}} did not match any fixable files." if [[ ${any_correct} ]]; then - eqawarn "All files have ${EPYTHON} shebang already." + "${cmd}" "All files have ${EPYTHON} shebang already." else - eqawarn "There are no Python files in specified directory." + "${cmd}" "There are no Python files in specified directory." fi + + [[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})" fi done } +# @FUNCTION: _python_check_locale_sanity +# @USAGE: +# @RETURN: 0 if sane, 1 otherwise +# @DESCRIPTION: +# Check whether the specified locale sanely maps between lowercase +# and uppercase ASCII characters. +_python_check_locale_sanity() { + local -x LC_CTYPE=${1} + local IFS= + + local lc=( {a..z} ) + local uc=( {A..Z} ) + local input="${lc[*]}${uc[*]}" + + local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}") + [[ ${output} == "${uc[*]}${lc[*]}" ]] +} + # @FUNCTION: python_export_utf8_locale # @RETURN: 0 on success, 1 on failure. # @DESCRIPTION: @@ -1101,20 +1233,33 @@ python_fix_shebang() { python_export_utf8_locale() { debug-print-function ${FUNCNAME} "${@}" - if [[ $(locale charmap) != UTF-8 ]]; then - if [[ -n ${LC_ALL} ]]; then - ewarn "LC_ALL is set to a locale with a charmap other than UTF-8." - ewarn "This may trigger build failures in some python packages." - return 1 - fi + # If the locale program isn't available, just return. + type locale >/dev/null || return 0 + if [[ $(locale charmap) != UTF-8 ]]; then # Try English first, then everything else. local lang locales="en_US.UTF-8 $(locale -a)" for lang in ${locales}; do - if [[ $(LC_CTYPE=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then - export LC_CTYPE=${lang} - return 0 + if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then + if _python_check_locale_sanity "${lang}"; then + export LC_CTYPE=${lang} + if [[ -n ${LC_ALL} ]]; then + export LC_NUMERIC=${LC_ALL} + export LC_TIME=${LC_ALL} + export LC_COLLATE=${LC_ALL} + export LC_MONETARY=${LC_ALL} + export LC_MESSAGES=${LC_ALL} + export LC_PAPER=${LC_ALL} + export LC_NAME=${LC_ALL} + export LC_ADDRESS=${LC_ALL} + export LC_TELEPHONE=${LC_ALL} + export LC_MEASUREMENT=${LC_ALL} + export LC_IDENTIFICATION=${LC_ALL} + export LC_ALL= + fi + return 0 + fi fi done diff --git a/sdk_container/src/third_party/portage-stable/eclass/python.eclass b/sdk_container/src/third_party/portage-stable/eclass/python.eclass index d89ee23119..d6742c12a2 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python.eclass @@ -1,6 +1,6 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.171 2015/03/31 18:43:33 ulm Exp $ +# $Id$ # @ECLASS: python.eclass # @MAINTAINER: @@ -12,6 +12,10 @@ # This eclass is DEPRECATED. Please use python-r1, python-single-r1 # or python-any-r1 instead. +if [[ ${EAPI} == 6 ]]; then + die "${ECLASS}.eclass is banned in EAPI ${EAPI}" +fi + if [[ ${_PYTHON_UTILS_R1} ]]; then die 'python.eclass can not be used with python-r1 suite eclasses.' fi @@ -341,19 +345,7 @@ _python_initialize_prefix_variables() { unset PYTHON_SANITY_CHECKS_EXECUTED PYTHON_SKIP_SANITY_CHECKS _python_initial_sanity_checks() { - if [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then - # Ensure that /usr/bin/python and /usr/bin/python-config are valid. - if [[ "$(readlink "${EPREFIX}/usr/bin/python")" != "python-wrapper" ]]; then - eerror "'${EPREFIX}/usr/bin/python' is not a valid symlink." - eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem." - die "'${EPREFIX}/usr/bin/python' is not a valid symlink" - fi - if [[ "$(<"${EPREFIX}/usr/bin/python-config")" != *"Gentoo python-config wrapper script"* ]]; then - eerror "'${EPREFIX}/usr/bin/python-config' is not a valid script" - eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem." - die "'${EPREFIX}/usr/bin/python-config' is not a valid script" - fi - fi + : } _python_final_sanity_checks() { @@ -804,10 +796,6 @@ _python_calculate_PYTHON_ABIS() { python_version="$("${EPREFIX}/usr/bin/python" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')" if has_version "=dev-lang/python-2*"; then - if [[ "$(readlink "${EPREFIX}/usr/bin/python2")" != "python2."* ]]; then - die "'${EPREFIX}/usr/bin/python2' is not a valid symlink" - fi - python2_version="$("${EPREFIX}/usr/bin/python2" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')" support_python_major_version="0" @@ -827,10 +815,6 @@ _python_calculate_PYTHON_ABIS() { fi if has_version "=dev-lang/python-3*"; then - if [[ "$(readlink "${EPREFIX}/usr/bin/python3")" != "python3."* ]]; then - die "'${EPREFIX}/usr/bin/python3' is not a valid symlink" - fi - python3_version="$("${EPREFIX}/usr/bin/python3" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')" support_python_major_version="0"