Support PYTHON_DEPEND / PYTHON_BDEPEND in EAPI >=4. (Patch by Arfrever. Backported from Progress Overlay.) --- python.eclass +++ python.eclass @@ -130,9 +130,37 @@ # @ECLASS-VARIABLE: PYTHON_DEPEND # @DESCRIPTION: -# Specification of dependency on dev-lang/python. -# Syntax: -# PYTHON_DEPEND: [[!]USE_flag? ][ version_components_group] +# Specification of build time and run time dependency on Python implementational packages. +# +# PYTHON_DEPEND in EAPI >=4 is a dependency string with <<>> markers. +# <<>> markers indicate atoms of Python implementational packages. +# <<>> markers can contain USE dependencies. +# <<>> markers must contain versions ranges in ebuilds of packages not supporting installation for multiple Python ABIs. +# +# Syntax in EAPI <=3: +# PYTHON_DEPEND: [[!]USE_flag? ] +# +# Syntax of versions range: +# versions_range: [[!]USE_flag? ][ version_components_group] +# version_components_group: +# major_version: <2|3|*> +# minimal_version: +# maximal_version: + +# @ECLASS-VARIABLE: PYTHON_BDEPEND +# @DESCRIPTION: +# Specification of build time dependency on Python implementational packages. +# +# PYTHON_BDEPEND in EAPI >=4 is a dependency string with <<>> markers. +# <<>> markers indicate atoms of Python implementational packages. +# <<>> markers can contain USE dependencies. +# <<>> markers must contain versions ranges in ebuilds of packages not supporting installation for multiple Python ABIs. +# +# Syntax in EAPI <=3: +# PYTHON_BDEPEND: [[!]USE_flag? ] +# +# Syntax of versions range: +# versions_range: [[!]USE_flag? ][ version_components_group] # version_components_group: # major_version: <2|3|*> # minimal_version: @@ -282,8 +310,172 @@ fi } +unset _PYTHON_USE_FLAGS_CHECKS_CODE + _python_parse_dependencies_in_new_EAPIs() { - : + local component cpython_abis=() cpython_atoms=() cpython_reversed_abis=() i input_value input_variable output_value output_variable output_variables PYTHON_ABI replace_whitespace_characters="1" required_USE_flags separate_components USE_dependencies versions_range + + input_value="${!1}" + input_variable="$1" + output_variables="$2" + + if has "${EAPI:-0}" 4 && _python_package_supporting_installation_for_multiple_python_abis; then + cpython_abis=(${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]} ${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}) + for ((i = $((${#cpython_abis[@]} - 1)); i >= 0; i--)); do + cpython_reversed_abis+=("${cpython_abis[${i}]}") + done + fi + + _get_matched_USE_dependencies() { + local matched_USE_dependencies patterns separate_USE_dependencies USE_dependency + + if [[ -n "${USE_dependencies}" ]]; then + separate_USE_dependencies="${USE_dependencies:1:$((${#USE_dependencies} - 2))}" + separate_USE_dependencies="${separate_USE_dependencies//,/$'\n'}" + while read USE_dependency; do + if [[ "${USE_dependency}" == "{"*"}"* ]]; then + patterns="${USE_dependency%\}*}" + patterns="${patterns:1}" + USE_dependency="${USE_dependency#*\}}" + if _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${patterns}"; then + matched_USE_dependencies+="${matched_USE_dependencies:+,}${USE_dependency}" + fi + else + matched_USE_dependencies+="${matched_USE_dependencies:+,}${USE_dependency}" + fi + done <<< "${separate_USE_dependencies}" + if [[ -n "${matched_USE_dependencies}" ]]; then + matched_USE_dependencies="[${matched_USE_dependencies}]" + fi + fi + + echo "${matched_USE_dependencies}" + } + + for ((i = 0; i < "${#input_value}"; i++)); do + if [[ "${input_value:${i}:1}" == "<" && "${input_value:$((${i} + 1)):1}" == "<" ]]; then + replace_whitespace_characters="0" + separate_components+="${input_value:${i}:1}" + elif [[ "${input_value:${i}:1}" == ">" && "${input_value:$((${i} + 1)):1}" == ">" ]]; then + replace_whitespace_characters="1" + separate_components+="${input_value:${i}:1}" + elif [[ "${input_value:${i}:1}" == [${IFS}] ]]; then + if [[ "${replace_whitespace_characters}" == "1" ]]; then + separate_components+=$'\n' + else + separate_components+="${input_value:${i}:1}" + fi + else + separate_components+="${input_value:${i}:1}" + fi + done + + while read component; do + if [[ -z "${component}" ]]; then + continue + elif [[ "${component}" == "<<"*">>" ]]; then + component="${component:2:$((${#component} - 4))}" + if [[ "${component}" == *"["*"]" ]]; then + versions_range="${component%%\[*\]}" + USE_dependencies="${component#${versions_range}}" + else + versions_range="${component}" + USE_dependencies="" + fi + if _python_package_supporting_installation_for_multiple_python_abis; then + if [[ -n "${versions_range}" ]]; then + die "Invalid syntax of ${input_variable}: Versions range cannot be used in ebuilds of packages supporting installation for multiple Python ABIs" + fi + if has "${EAPI:-0}" 4; then + cpython_atoms=() + for PYTHON_ABI in "${cpython_reversed_abis[@]}"; do + if ! _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${PYTHON_RESTRICTED_ABIS}"; then + cpython_atoms+=("dev-lang/python:${PYTHON_ABI}$(_get_matched_USE_dependencies)") + fi + done + if [[ "${#cpython_atoms[@]}" -gt 1 ]]; then + output_value+="${output_value:+ }|| ( ${cpython_atoms[@]} )" + else + output_value+="${output_value:+ }${cpython_atoms[@]}" + fi + if [[ -z "${USE_dependencies}" ]]; then + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }:;" + fi + fi + for PYTHON_ABI in "${_PYTHON_LOCALLY_SUPPORTED_ABIS[@]}"; do + if has "${EAPI:-0}" 4; then + if [[ -n "${USE_dependencies}" ]]; then + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }if [[ \"\${PYTHON_ABI}\" == \"${PYTHON_ABI}\" ]] && ! has_version \"\$(python_get_implementational_package)$(_get_matched_USE_dependencies)\"; then die \"\$(python_get_implementational_package)$(_get_matched_USE_dependencies) not installed\"; fi;" + fi + else + if [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then + output_value+="${output_value:+ }python_abis_${PYTHON_ABI}? ( dev-lang/python:${PYTHON_ABI}$(_get_matched_USE_dependencies) )" + elif [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+-jython$ ]]; then + output_value+="${output_value:+ }python_abis_${PYTHON_ABI}? ( dev-java/jython:${PYTHON_ABI%-jython}$(_get_matched_USE_dependencies) )" + elif [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+-pypy-[[:digit:]]+\.[[:digit:]]+$ ]]; then + output_value+="${output_value:+ }python_abis_${PYTHON_ABI}? ( dev-python/pypy:${PYTHON_ABI#*-pypy-}$(_get_matched_USE_dependencies) )" + fi + fi + done + if ! has "${EAPI:-0}" 4; then + if [[ "${#_PYTHON_LOCALLY_SUPPORTED_ABIS[@]}" -gt 1 ]]; then + required_USE_flags+="${required_USE_flags:+ }|| ( ${_PYTHON_LOCALLY_SUPPORTED_ABIS[@]/#/python_abis_} )" + else + required_USE_flags+="${required_USE_flags:+ }${_PYTHON_LOCALLY_SUPPORTED_ABIS[@]/#/python_abis_}" + fi + fi + else + _python_parse_versions_range "${versions_range}" "${input_variable}" cpython_atoms + cpython_atoms=("${cpython_atoms[@]/%/${USE_dependencies}}") + if [[ "${#cpython_atoms[@]}" -gt 1 ]]; then + output_value+="${output_value:+ }|| ( ${cpython_atoms[@]} )" + else + output_value+="${output_value:+ }${cpython_atoms[@]}" + fi + if [[ -n "${USE_dependencies}" ]]; then + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }if ! has_version \"\$(python_get_implementational_package)${USE_dependencies}\"; then die \"\$(python_get_implementational_package)${USE_dependencies} not installed\"; fi;" + else + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }:;" + fi + fi + elif [[ "${component}" == *"?" ]]; then + output_value+="${output_value:+ }${component}" + required_USE_flags+="${required_USE_flags:+ }${component}" + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }if use ${component%\?};" + elif [[ "${component}" == "||" ]]; then + if has "${EAPI:-0}" 4 || ! _python_package_supporting_installation_for_multiple_python_abis; then + die "Invalid syntax of ${input_variable}: Unrecognized component '${component}'" + fi + output_value+="${output_value:+ }${component}" + required_USE_flags+="${required_USE_flags:+ }${component}" + elif [[ "${component}" == "(" ]]; then + output_value+="${output_value:+ }${component}" + required_USE_flags+="${required_USE_flags:+ }${component}" + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }then" + elif [[ "${component}" == ")" ]]; then + output_value+="${output_value:+ }${component}" + required_USE_flags+="${required_USE_flags:+ }${component}" + _PYTHON_USE_FLAGS_CHECKS_CODE+="${_PYTHON_USE_FLAGS_CHECKS_CODE:+ }fi;" + else + die "Invalid syntax of ${input_variable}: Unrecognized component '${component}'" + fi + done <<< "${separate_components}" + + for output_variable in ${output_variables}; do + eval "${output_variable}+=\"\${!output_variable:+ }\${output_value}\"" + done + + _PYTHON_USE_FLAGS_CHECKS_CODE="${_PYTHON_USE_FLAGS_CHECKS_CODE%;}" + + if ! has "${EAPI:-0}" 4 && _python_package_supporting_installation_for_multiple_python_abis; then + if [[ "${input_variable}" == "PYTHON_DEPEND" ]]; then + REQUIRED_USE="${required_USE_flags}" + fi + + unset _PYTHON_USE_FLAGS_CHECKS_CODE + fi + + unset -f _get_matched_USE_dependencies } DEPEND=">=app-admin/eselect-python-20091230" @@ -305,7 +497,15 @@ fi unset _PYTHON_ATOMS else - _python_parse_dependencies_in_new_EAPIs + if [[ -z "$(declare -p PYTHON_DEPEND 2> /dev/null)" ]] && _python_package_supporting_installation_for_multiple_python_abis; then + PYTHON_DEPEND="<<>>" + fi + if [[ -n "${PYTHON_DEPEND}" ]]; then + _python_parse_dependencies_in_new_EAPIs PYTHON_DEPEND "DEPEND RDEPEND" + fi + if [[ -n "${PYTHON_BDEPEND}" ]]; then + _python_parse_dependencies_in_new_EAPIs PYTHON_BDEPEND "DEPEND" + fi fi unset -f _python_parse_versions_range _python_parse_dependencies_in_old_EAPIs _python_parse_dependencies_in_new_EAPIs @@ -523,7 +723,7 @@ PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}" fi - if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; then + if has "${EAPI:-0}" 2 3 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; then if [[ "${PYTHON_USE_WITH_OPT}" ]]; then if [[ "${PYTHON_USE_WITH_OPT}" == !* ]]; then use ${PYTHON_USE_WITH_OPT#!} && return @@ -556,6 +756,20 @@ } if _python_package_supporting_installation_for_multiple_python_abis; then + PYTHON_SKIP_SANITY_CHECKS="1" python_execute_function -q python_pkg_setup_check_USE_flags + else + python_pkg_setup_check_USE_flags + fi + + unset -f python_pkg_setup_check_USE_flags + fi + + if has "${EAPI:-0}" 4 || { ! has "${EAPI:-0}" 0 1 2 3 4 && ! _python_package_supporting_installation_for_multiple_python_abis; }; then + python_pkg_setup_check_USE_flags() { + eval "${_PYTHON_USE_FLAGS_CHECKS_CODE}" + } + + if _python_package_supporting_installation_for_multiple_python_abis; then PYTHON_SKIP_SANITY_CHECKS="1" python_execute_function -q python_pkg_setup_check_USE_flags else python_pkg_setup_check_USE_flags