eclass: pull in updates for newer EAPI
BUG=chromium:600061
TEST=`cbuildbot chromiumos-sdk` works
CQ-DEPEND=CL:336990
Change-Id: I267b129a2abe2a0bd490fdced9d87d0297b442fb
Reviewed-on: https://chromium-review.googlesource.com/336930
Commit-Ready: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: David Hendricks <dhendrix@chromium.org>
diff --git a/eclass/distutils-r1.eclass b/eclass/distutils-r1.eclass
index 22afd1e..7965e91 100644
--- a/eclass/distutils-r1.eclass
+++ b/eclass/distutils-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/distutils-r1.eclass,v 1.113 2015/02/20 17:57:22 mgorny Exp $
+# $Id$
-# @ECLASS: distutils-r1
+# @ECLASS: distutils-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@@ -40,14 +40,14 @@
# as well. Thus, all the variables defined and documented there are
# relevant to the packages using distutils-r1.
#
-# 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/distutils-r1
case "${EAPI:-0}" in
0|1|2|3)
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
;;
- 4|5)
+ 4|5|6)
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@@ -79,7 +79,8 @@
if [[ ! ${_DISTUTILS_R1} ]]; then
-inherit eutils toolchain-funcs
+[[ ${EAPI} == [45] ]] && inherit eutils
+inherit toolchain-funcs
if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
inherit multiprocessing python-r1
@@ -150,6 +151,8 @@
# @ECLASS-VARIABLE: EXAMPLES
# @DEFAULT_UNSET
# @DESCRIPTION:
+# OBSOLETE: this variable is deprecated and banned in EAPI 6
+#
# An array containing examples installed into 'examples' doc
# subdirectory. The files and directories listed there must exist
# in the directory from which distutils-r1_python_install_all() is run
@@ -236,10 +239,13 @@
esetup.py() {
debug-print-function ${FUNCNAME} "${@}"
+ local die_args=()
+ [[ ${EAPI} != [45] ]] && die_args+=( -n )
+
set -- "${PYTHON:-python}" setup.py "${mydistutilsargs[@]}" "${@}"
echo "${@}" >&2
- "${@}" || die
+ "${@}" || die "${die_args[@]}" || return ${?}
}
# @FUNCTION: distutils_install_for_testing
@@ -309,9 +315,12 @@
distutils-r1_python_prepare_all() {
debug-print-function ${FUNCNAME} "${@}"
- [[ ${PATCHES} ]] && epatch "${PATCHES[@]}"
-
- epatch_user
+ if [[ ${EAPI} != [45] ]]; then
+ default
+ else
+ [[ ${PATCHES} ]] && epatch "${PATCHES[@]}"
+ epatch_user
+ fi
# by default, use in-source build if python_prepare() is used
if [[ ! ${DISTUTILS_IN_SOURCE_BUILD+1} ]]; then
@@ -337,7 +346,7 @@
distutils-r1_python_prepare() {
debug-print-function ${FUNCNAME} "${@}"
- :
+ [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI 6 (it was a no-op)"
}
# @FUNCTION: distutils-r1_python_configure
@@ -346,7 +355,7 @@
distutils-r1_python_configure() {
debug-print-function ${FUNCNAME} "${@}"
- :
+ [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI 6 (it was a no-op)"
}
# @FUNCTION: _distutils-r1_create_setup_cfg
@@ -410,7 +419,7 @@
_distutils-r1_copy_egg_info() {
mkdir -p "${BUILD_DIR}" || die
# stupid freebsd can't do 'cp -t ${BUILD_DIR} {} +'
- find -name '*.egg-info' -type d -exec cp -pr {} "${BUILD_DIR}"/ ';' || die
+ find -name '*.egg-info' -type d -exec cp -R -p {} "${BUILD_DIR}"/ ';' || die
}
# @FUNCTION: distutils-r1_python_compile
@@ -505,7 +514,7 @@
# python likes to compile any module it sees, which triggers sandbox
# failures if some packages haven't compiled their modules yet.
- addpredict "$(python_get_sitedir)"
+ addpredict "${EPREFIX}/usr/$(get_libdir)/${EPYTHON}"
addpredict /usr/lib/portage/pym
addpredict /usr/local # bug 498232
@@ -549,11 +558,17 @@
esetup.py install --root="${root}" "${args[@]}"
- if [[ -d ${root}$(python_get_sitedir)/tests ]]; then
- die "Package installs 'tests' package, file collisions likely."
- fi
+ local forbidden_package_names=( examples test tests )
+ local p
+ for p in "${forbidden_package_names[@]}"; do
+ if [[ -d ${root}$(python_get_sitedir)/${p} ]]; then
+ die "Package installs '${p}' package which is forbidden and likely a bug in the build system."
+ fi
+ done
if [[ -d ${root}/usr/$(get_libdir)/pypy/share ]]; then
- eqawarn "Package installs 'share' in PyPy prefix, see bug #465546."
+ local cmd=die
+ [[ ${EAPI} == [45] ]] && cmd=eqawarn
+ "${cmd}" "Package installs 'share' in PyPy prefix, see bug #465546."
fi
if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
@@ -571,6 +586,8 @@
einstalldocs
if declare -p EXAMPLES &>/dev/null; then
+ [[ ${EAPI} != [45] ]] && die "EXAMPLES are banned in EAPI ${EAPI}"
+
local INSDESTTREE=/usr/share/doc/${PF}/examples
doins -r "${EXAMPLES[@]}"
docompress -x "${INSDESTTREE}"
@@ -603,6 +620,14 @@
fi
local -x PYTHONPATH="${BUILD_DIR}/lib:${PYTHONPATH}"
+ # Bug 559644
+ # using PYTHONPATH when the ${BUILD_DIR}/lib is not created yet might lead to
+ # problems in setup.py scripts that try to import modules/packages from that path
+ # during the build process (Python at startup evaluates PYTHONPATH, if the dir is
+ # not valid then associates a NullImporter object to ${BUILD_DIR}/lib storing it
+ # in the sys.path_importer_cache)
+ mkdir -p "${BUILD_DIR}/lib" || die
+
# We need separate home for each implementation, for .pydistutils.cfg.
if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
local -x HOME=${HOME}/${EPYTHON}
@@ -653,6 +678,7 @@
done
}
python_foreach_impl _distutils_try_impl
+ unset -f _distutils_try_impl
local PYTHON_COMPAT=( "${best_impl}" )
fi
@@ -669,6 +695,8 @@
debug-print-function ${FUNCNAME} "${@}"
if [[ ${DISTUTILS_NO_PARALLEL_BUILD} ]]; then
+ [[ ${EAPI} == [45] ]] || die "DISTUTILS_NO_PARALLEL_BUILD is banned in EAPI ${EAPI}"
+
eqawarn "DISTUTILS_NO_PARALLEL_BUILD is no longer meaningful. Now all builds"
eqawarn "are non-parallel. Please remove it from the ebuild."
@@ -705,7 +733,10 @@
fi
if [[ ! ${_DISTUTILS_DEFAULT_CALLED} ]]; then
- eqawarn "QA warning: python_prepare_all() didn't call distutils-r1_python_prepare_all"
+ local cmd=die
+ [[ ${EAPI} == [45] ]] && cmd=eqawarn
+
+ "${cmd}" "QA: python_prepare_all() didn't call distutils-r1_python_prepare_all"
fi
if declare -f python_prepare >/dev/null; then
@@ -776,7 +807,10 @@
fi
if [[ ! ${_DISTUTILS_DEFAULT_CALLED} ]]; then
- eqawarn "QA warning: python_install_all() didn't call distutils-r1_python_install_all"
+ local cmd=die
+ [[ ${EAPI} == [45] ]] && cmd=eqawarn
+
+ "${cmd}" "QA: python_install_all() didn't call distutils-r1_python_install_all"
fi
}
diff --git a/eclass/distutils.eclass b/eclass/distutils.eclass
index 8b9140a..d24ae55 100644
--- a/eclass/distutils.eclass
+++ b/eclass/distutils.eclass
@@ -1,6 +1,6 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/distutils.eclass,v 1.85 2014/11/20 15:32:09 mgorny Exp $
+# $Id$
# @ECLASS: distutils.eclass
# @MAINTAINER:
@@ -18,6 +18,9 @@
inherit multilib
case "${EAPI:-0}" in
+ 6)
+ die "${ECLASS}.eclass is banned in EAPI ${EAPI}"
+ ;;
0|1)
EXPORT_FUNCTIONS src_unpack src_compile src_install pkg_postinst pkg_postrm
;;
diff --git a/eclass/multibuild.eclass b/eclass/multibuild.eclass
index d9a86e9..3d05f46 100644
--- a/eclass/multibuild.eclass
+++ b/eclass/multibuild.eclass
@@ -1,8 +1,8 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/multibuild.eclass,v 1.20 2014/12/13 08:42:42 mgorny Exp $
+# $Id$
-# @ECLASS: multibuild
+# @ECLASS: multibuild.eclass
# @MAINTAINER:
# MichaĆ Górny <mgorny@gentoo.org>
# @AUTHOR:
@@ -17,7 +17,7 @@
0|1|2|3)
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
;;
- 4|5)
+ 4|5|6)
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@@ -146,6 +146,8 @@
multibuild_parallel_foreach_variant() {
debug-print-function ${FUNCNAME} "${@}"
+ [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}"
+
multibuild_foreach_variant "${@}"
}
@@ -193,7 +195,7 @@
_multibuild_create_source_copy() {
einfo "${MULTIBUILD_VARIANT}: copying to ${BUILD_DIR}"
- cp -pr "${cp_args[@]}" \
+ cp -p -R "${cp_args[@]}" \
"${_MULTIBUILD_INITIAL_BUILD_DIR}" "${BUILD_DIR}" || die
}
diff --git a/eclass/multilib-build.eclass b/eclass/multilib-build.eclass
index 3509366..deb03db 100644
--- a/eclass/multilib-build.eclass
+++ b/eclass/multilib-build.eclass
@@ -1,6 +1,6 @@
-# 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/multilib-build.eclass,v 1.65 2014/12/13 08:41:37 mgorny Exp $
+# $Id$
# @ECLASS: multilib-build.eclass
# @MAINTAINER:
@@ -21,10 +21,11 @@
# EAPI=4 is required for meaningful MULTILIB_USEDEP.
case ${EAPI:-0} in
- 4|5) ;;
+ 4|5|6) ;;
*) die "EAPI=${EAPI} is not supported" ;;
esac
+[[ ${EAPI} == [45] ]] && inherit eutils
inherit multibuild multilib
# @ECLASS-VARIABLE: _MULTILIB_FLAGS
@@ -49,6 +50,7 @@
abi_s390_32:s390
abi_s390_64:s390x
)
+readonly _MULTILIB_FLAGS
# @ECLASS-VARIABLE: MULTILIB_COMPAT
# @DEFAULT_UNSET
@@ -124,8 +126,10 @@
IUSE=${flags[*]}
MULTILIB_USEDEP=${usedeps// /,}
+ readonly MULTILIB_USEDEP
}
_multilib_build_set_globals
+unset -f _multilib_build_set_globals
# @FUNCTION: multilib_get_enabled_abis
# @DESCRIPTION:
@@ -196,9 +200,10 @@
debug-print-function ${FUNCNAME} "${@}"
local ABI=${MULTIBUILD_VARIANT#*.}
- local MULTILIB_ABI_FLAG=${MULTIBUILD_VARIANT%.*}
+ local -r MULTILIB_ABI_FLAG=${MULTIBUILD_VARIANT%.*}
multilib_toolchain_setup "${ABI}"
+ readonly ABI
"${@}"
}
@@ -244,6 +249,8 @@
multilib_for_best_abi() {
debug-print-function ${FUNCNAME} "${@}"
+ [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}, use multilib_is_native_abi() instead"
+
eqawarn "QA warning: multilib_for_best_abi() function is deprecated and should"
eqawarn "not be used. The multilib_is_native_abi() check may be used instead."
@@ -261,19 +268,24 @@
# runs (if any). Dies if header files differ.
multilib_check_headers() {
_multilib_header_cksum() {
- [[ -d ${ED}usr/include ]] && \
- find "${ED}"usr/include -type f \
- -exec cksum {} + | sort -k2
+ set -o pipefail
+
+ if [[ -d ${ED}usr/include ]]; then
+ find "${ED}"usr/include -type f \
+ -exec cksum {} + | sort -k2
+ fi
}
- local cksum=$(_multilib_header_cksum)
+ local cksum cksum_prev
local cksum_file=${T}/.multilib_header_cksum
+ cksum=$(_multilib_header_cksum) || die
+ unset -f _multilib_header_cksum
if [[ -f ${cksum_file} ]]; then
- local cksum_prev=$(< "${cksum_file}")
+ cksum_prev=$(< "${cksum_file}") || die
if [[ ${cksum} != ${cksum_prev} ]]; then
- echo "${cksum}" > "${cksum_file}.new"
+ echo "${cksum}" > "${cksum_file}.new" || die
eerror "Header files have changed between ABIs."
@@ -287,7 +299,7 @@
die "Header checksum mismatch, aborting."
fi
else
- echo "${cksum}" > "${cksum_file}"
+ echo "${cksum}" > "${cksum_file}" || die
fi
}
@@ -408,9 +420,9 @@
if [[ -L ${root}/${f} ]]; then
# rewrite the symlink target
- local target=$(readlink "${root}/${f}")
- local target_dir
- local target_fn=${target##*/}
+ local target
+ target=$(readlink "${root}/${f}") || die
+ local target_dir target_fn=${target##*/}
[[ ${target} == */* ]] && target_dir=${target%/*}
@@ -452,7 +464,7 @@
if [[ ! -f ${ED}/tmp/multilib-include${f} ]]; then
dodir "/tmp/multilib-include${dir}"
# a generic template
- cat > "${wrapper}" <<_EOF_
+ cat > "${wrapper}" <<_EOF_ || die
/* This file is auto-generated by multilib-build.eclass
* as a multilib-friendly wrapper. For the original content,
* please see the files that are #included below.
@@ -513,14 +525,6 @@
sed -e "/${MULTILIB_ABI_FLAG} /s&error.*&include <${CHOST}${f}>&" \
-i "${wrapper}" || die
- # Hack for emul-linux-x86 compatibility.
- # It assumes amd64 will come after x86, and will use amd64
- # headers if no specific x86 headers were installed.
- if [[ ${ABI} == amd64 ]]; then
- sed -e "/abi_x86_32 /s&error.*&include <${CHOST}${f}>&" \
- -i "${wrapper}" || die
- fi
-
# Needed for swig.
if multilib_is_native_abi; then
sed -e "/Native ABI/s&error.*&include <${CHOST}${f}>&" \
@@ -581,6 +585,8 @@
multilib_build_binaries() {
debug-print-function ${FUNCNAME} "${@}"
+ [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}, use multilib_is_native_abi() instead"
+
eqawarn "QA warning: multilib_build_binaries is deprecated. Please use the equivalent"
eqawarn "multilib_is_native_abi function instead."
diff --git a/eclass/multilib-minimal.eclass b/eclass/multilib-minimal.eclass
index e1a5ac4..127614d 100644
--- a/eclass/multilib-minimal.eclass
+++ b/eclass/multilib-minimal.eclass
@@ -1,6 +1,6 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/multilib-minimal.eclass,v 1.10 2014/12/13 08:41:37 mgorny Exp $
+# $Id$
# @ECLASS: multilib-minimal.eclass
# @MAINTAINER:
@@ -25,12 +25,13 @@
# EAPI=4 is required for meaningful MULTILIB_USEDEP.
case ${EAPI:-0} in
- 4|5) ;;
+ 4|5|6) ;;
*) die "EAPI=${EAPI} is not supported" ;;
esac
-inherit eutils multilib-build
+[[ ${EAPI} == [45] ]] && inherit eutils
+inherit multilib-build
EXPORT_FUNCTIONS src_configure src_compile src_test src_install
diff --git a/eclass/multilib.eclass b/eclass/multilib.eclass
index b3e9903..69582b6 100644
--- a/eclass/multilib.eclass
+++ b/eclass/multilib.eclass
@@ -1,6 +1,6 @@
-# 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/multilib.eclass,v 1.106 2014/07/11 08:21:58 ulm Exp $
+# $Id$
# @ECLASS: multilib.eclass
# @MAINTAINER:
@@ -49,15 +49,17 @@
# fall back on old behavior. Any profile that has these set should also
# depend on a newer version of portage (not yet released) which uses these
# over CONF_LIBDIR in econf, dolib, etc...
-get_libdir() {
- local CONF_LIBDIR
- if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
- # if there is an override, we want to use that... always.
- echo ${CONF_LIBDIR_OVERRIDE}
- else
- get_abi_LIBDIR
- fi
-}
+if has "${EAPI:-0}" 0 1 2 3 4 5; then
+ get_libdir() {
+ local CONF_LIBDIR
+ if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
+ # if there is an override, we want to use that... always.
+ echo ${CONF_LIBDIR_OVERRIDE}
+ else
+ get_abi_LIBDIR
+ fi
+ }
+fi
# @FUNCTION: get_abi_var
# @USAGE: <VAR> [ABI]
@@ -415,7 +417,7 @@
# First restore any saved state we have laying around.
if [[ ${_DEFAULT_ABI_SAVED} == "true" ]] ; then
- for v in CHOST CBUILD AS CC CXX LD PKG_CONFIG_{LIBDIR,PATH} ; do
+ for v in CHOST CBUILD AS CC CXX F77 FC LD PKG_CONFIG_{LIBDIR,PATH} ; do
vv="_abi_saved_${v}"
[[ ${!vv+set} == "set" ]] && export ${v}="${!vv}" || unset ${v}
unset ${vv}
@@ -427,7 +429,7 @@
# screws up ccache and distcc. See #196243 for more info.
if [[ ${ABI} != ${DEFAULT_ABI} ]] ; then
# Back that multilib-ass up so we can restore it later
- for v in CHOST CBUILD AS CC CXX LD PKG_CONFIG_{LIBDIR,PATH} ; do
+ for v in CHOST CBUILD AS CC CXX F77 FC LD PKG_CONFIG_{LIBDIR,PATH} ; do
vv="_abi_saved_${v}"
[[ ${!v+set} == "set" ]] && export ${vv}="${!v}" || unset ${vv}
done
@@ -438,6 +440,8 @@
export CHOST=$(get_abi_CHOST ${DEFAULT_ABI})
export CC="$(tc-getCC) $(get_abi_CFLAGS)"
export CXX="$(tc-getCXX) $(get_abi_CFLAGS)"
+ export F77="$(tc-getF77) $(get_abi_CFLAGS)"
+ export FC="$(tc-getFC) $(get_abi_CFLAGS)"
export LD="$(tc-getLD) $(get_abi_LDFLAGS)"
export CHOST=$(get_abi_CHOST $1)
export CBUILD=$(get_abi_CHOST $1)
diff --git a/eclass/multiprocessing.eclass b/eclass/multiprocessing.eclass
index 3890f91..06e004a 100644
--- a/eclass/multiprocessing.eclass
+++ b/eclass/multiprocessing.eclass
@@ -1,6 +1,6 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/multiprocessing.eclass,v 1.9 2014/07/11 08:21:58 ulm Exp $
+# $Id$
# @ECLASS: multiprocessing.eclass
# @MAINTAINER:
@@ -86,9 +86,10 @@
# This assumes the first .* will be more greedy than the second .*
# since POSIX doesn't specify a non-greedy match (i.e. ".*?").
local lavg=$(echo " $* " | sed -r -n \
- -e 's:.*[[:space:]](-l|--load-average[=[:space:]])[[:space:]]*([0-9]+|[0-9]+\.[0-9]+)[^0-9.]*:\2:p' \
- -e 's:.*[[:space:]](-l|--load-average)[[:space:]].*:999:p')
- echo ${lavg:-1}
+ -e 's:.*[[:space:]](-l|--(load-average|max-load)[=[:space:]])[[:space:]]*([0-9]+|[0-9]+\.[0-9]+).*:\3:p' \
+ -e 's:.*[[:space:]](-l|--(load-average|max-load))[[:space:]].*:999:p')
+ # Default to 999 since the default is to not use a load limit.
+ echo ${lavg:-999}
}
# @FUNCTION: multijob_init
diff --git a/eclass/python-any-r1.eclass b/eclass/python-any-r1.eclass
index 42fd3c7..c6dfc9c 100644
--- a/eclass/python-any-r1.eclass
+++ b/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 <python@gentoo.org>
# @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 @@
# @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 @@
# 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 @@
# 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 @@
[[ ${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 @@
;;
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_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 @@
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/eclass/python-r1.eclass b/eclass/python-r1.eclass
index b40d928..fc12fc2 100644
--- a/eclass/python-r1.eclass
+++ b/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.89 2015/02/20 17:57:22 mgorny Exp $
+# $Id$
-# @ECLASS: python-r1
+# @ECLASS: python-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@@ -26,15 +26,15 @@
# 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)
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
;;
- 4|5)
- # EAPI=4 is required for USE default deps on USE_EXPAND flags
+ 4|5|6)
+ # EAPI=5 is required for sane USE_EXPAND dependencies
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@@ -49,6 +49,7 @@
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
@@ -60,16 +61,13 @@
#
# 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
@@ -125,8 +123,8 @@
# 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
@@ -146,7 +144,7 @@
#
# 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
@@ -164,28 +162,21 @@
#
# 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
@@ -194,7 +185,7 @@
# 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[*]}
@@ -214,8 +205,10 @@
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
@@ -226,9 +219,7 @@
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
@@ -270,9 +261,7 @@
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+=(
@@ -313,9 +302,7 @@
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}" )
@@ -341,17 +328,17 @@
#
# 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} "${@}"
@@ -362,17 +349,15 @@
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} )" )
@@ -384,6 +369,58 @@
echo "${matches[@]}"
}
+# @FUNCTION: python_gen_impl_dep
+# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
+# @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
@@ -396,7 +433,7 @@
#
# Example value:
# @CODE
-# ${WORKDIR}/foo-1.3-python2_6
+# ${WORKDIR}/foo-1.3-python2_7
# @CODE
# @FUNCTION: python_copy_sources
@@ -416,220 +453,6 @@
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:
@@ -651,17 +474,12 @@
fi
_python_validate_useflags
- _python_check_USE_PYTHON
- _python_check_EAPI
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
}
@@ -725,6 +543,8 @@
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."
@@ -777,6 +597,7 @@
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."
@@ -800,6 +621,8 @@
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."
@@ -812,6 +635,7 @@
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}" "${@}"
@@ -846,6 +670,7 @@
local files=( "${@}" )
python_foreach_impl _python_replicate_script
+ unset -f _python_replicate_script
# install the wrappers
local f
diff --git a/eclass/python-single-r1.eclass b/eclass/python-single-r1.eclass
index 964cd4a..392d26b 100644
--- a/eclass/python-single-r1.eclass
+++ b/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.36 2015/02/20 17:57:22 mgorny Exp $
+# $Id$
-# @ECLASS: python-single-r1
+# @ECLASS: python-single-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
@@ -28,15 +28,15 @@
# 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)
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
;;
- 4|5)
- # EAPI=4 is required for USE default deps on USE_EXPAND flags
+ 4|5|6)
+ # EAPI=5 is required for sane USE_EXPAND dependencies
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@@ -68,11 +68,32 @@
#
# Example:
# @CODE
-# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
+# PYTHON_COMPAT=( python2_7 python3_3 python3_4} )
# @CODE
-if ! declare -p PYTHON_COMPAT &>/dev/null; then
- die 'PYTHON_COMPAT not declared.'
-fi
+#
+# 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
# @ECLASS-VARIABLE: PYTHON_REQ_USE
# @DEFAULT_UNSET
@@ -111,8 +132,8 @@
# 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
@@ -132,7 +153,7 @@
#
# 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
@@ -152,40 +173,30 @@
#
# 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
@@ -200,7 +211,7 @@
# 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.
@@ -225,8 +236,10 @@
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: <pattern> [...]
@@ -258,9 +271,7 @@
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+=(
@@ -298,15 +309,19 @@
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
@@ -329,41 +344,103 @@
#
# 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: [<requested-use-flags> [<impl-pattern>...]]
+# @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
@@ -379,24 +456,34 @@
python_setup() {
debug-print-function ${FUNCNAME} "${@}"
- _python_check_EAPI
-
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"
@@ -424,14 +511,14 @@
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/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass
index 56e61cf..9488966 100644
--- a/eclass/python-utils-r1.eclass
+++ b/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.81 2015/02/21 08:07:30 mgorny Exp $
+# $Id$
-# @ECLASS: python-utils-r1
+# @ECLASS: python-utils-r1.eclass
# @MAINTAINER:
# Python team <python@gentoo.org>
# @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 @@
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
+ jython2_7
pypy pypy3
- python3_3 python3_4
python2_7
+ python3_3 python3_4 python3_5
)
+readonly _PYTHON_ALL_IMPLS
# @FUNCTION: _python_impl_supported
# @USAGE: <impl>
@@ -66,7 +68,7 @@
# 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 @@
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 @@
# 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 @@
# 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 @@
# 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 @@
# -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 @@
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 @@
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 @@
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,11 +388,28 @@
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
python2.7)
- PYTHON_PKG_DEP='>=dev-lang/python-2.7.3-r2:2.7';;
+ PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
python3.3)
PYTHON_PKG_DEP='>=dev-lang/python-3.3.2-r2:3.3';;
python*)
@@ -350,8 +418,6 @@
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 @@
echo "${PYTHON_LIBS}"
}
+# @FUNCTION: python_get_PYTHON_CONFIG
+# @USAGE: [<impl>]
+# @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: [<impl>]
# @DESCRIPTION:
@@ -533,9 +616,6 @@
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 @@
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 @@
[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
[[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
+ 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 @@
(
dodir "${wrapd}"
exeinto "${d}"
- newexe "${f}" "${newfn}" || die
+ newexe "${f}" "${newfn}" || return ${?}
)
# install the wrapper
@@ -761,6 +844,9 @@
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 @@
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 @@
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 @@
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 @@
"${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 @@
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 @@
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: <locale>
+# @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_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
@@ -1127,22 +1272,6 @@
return 0
}
-# @FUNCTION: _python_check_EAPI
-# @INTERNAL
-# @DESCRIPTION:
-# Check whether the ebuild is not using deprecated EAPI 4. Output
-# a QA warning if it does.
-_python_check_EAPI() {
- if [[ ${EAPI} == 4 && ! ${_PYTHON_WARNED_EAPI} ]]; then
- eqawarn "This package is still using EAPI=4. This results in package"
- eqawarn "dependencies violating PMS and causing issues for package managers."
- eqawarn "For this reason, using EAPI=4 in new Python packages will be banned"
- eqawarn "on 2015-03-20 (2 years and 6 months after approving EAPI 5)."
-
- _PYTHON_WARNED_EAPI=1
- fi
-}
-
# -- python.eclass functions --
_python_check_dead_variables() {
diff --git a/eclass/python.eclass b/eclass/python.eclass
index 3164704..d6742c1 100644
--- a/eclass/python.eclass
+++ b/eclass/python.eclass
@@ -1,6 +1,6 @@
-# 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.eclass,v 1.170 2014/11/20 15:32:09 mgorny 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
@@ -260,7 +264,7 @@
}
if _python_implementation; then
- DEPEND=">=app-admin/eselect-python-20091230"
+ DEPEND=">=app-eselect/eselect-python-20091230"
RDEPEND="${DEPEND}"
PDEPEND="app-admin/python-updater"
fi
@@ -341,19 +345,7 @@
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_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 @@
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"