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"