public inbox for gentoo-python@lists.gentoo.org
 help / color / mirror / Atom feed
From: Ian Stakenvicius <axs@gentoo.org>
To: gentoo-python@lists.gentoo.org
Subject: [gentoo-python] Reducing exceptionality cases for PYTHON_SINGLE_TARGET
Date: Wed, 29 Oct 2014 14:17:29 -0400	[thread overview]
Message-ID: <54512F39.8080104@gentoo.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 3532 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hey all -- so I've noticed that there are a lot of packages using
python-single-r1.eclass which are python-2 only -- ie PYTHON_COMPAT=(
python2_{6,7} ) in most cases.  Effectively this means either an
end-user needs to tie PYTHON_SINGLE_TARGET on their system to
"python2_7", or they need to set the flag explicitly through
/etc/portage/package.use all the time.

As python-single-r1.eclass is meant to ensure that a package is bound
to just one implementation when multiple implementations are possible,
usually because it is too difficult to make the package multibuild, it
would make sense to me that if there is actually just one possible
implementation an ebuild can be satisfied with regardless of the
PYTHON_TARGETS and PYTHON_SINGLE_TARGET selections, that the ebuild
should be able to just depend on and use it regardless of what
PYTHON_SINGLE_TARGET is set to globally.

Simple example of situation -- assuming a properly-written
distcc-3.1-r9.ebuild (which the in-tree version apparently isn't):

> PYTHON_TARGETS="python2_7 python3_3 python3_4" \ 
> PYTHON_SINGLE_TARGET="python3_3" \ emerge -av sys-devel/distcc
> 
> These are the packages that would be merged, in order:
> 
> Calculating dependencies |
> 
> !!! Problem resolving dependencies for sys-devel/distcc ... done!
> 
> !!! The ebuild selected to satisfy "distcc" has unmet
> requirements. - sys-devel/distcc-3.1-r9::gentoo USE="gtk -avahi
> -hardened -ipv6 -selinux -xinetd" ABI_X86="64"
> PYTHON_SINGLE_TARGET="-python2_7" PYTHON_TARGETS="python2_7"
> 
> The following REQUIRED_USE flag constraints are unsatisfied: 
> python_single_target_python2_7
> 
> The above constraints are a subset of the following complete
> expression: python_single_target_python2_7? (
> python_targets_python2_7 ) exactly-one-of (
> python_single_target_python2_7 )


There are two ways to deal with this in-ebuild -- the first would be
to adjust the ebuilds to python-r1 but not multibuild them, which
means that the ebuilds are python-single but not actually implemented
in a python-single way.  The other is to adjust python-single-r1 so
that if there is only one possible implementation (ie, PYTHON_COMPAT
just has one entry, or only one such entry is in _PYTHON_ALL_IMPLS)
then the PYTHON_SINGLE_TARGET setting is ignored.

The main issue that this may cause is that the python_single_target_*
use dependencies are no longer fully deterministic at all times, and
are rather now determined based on the supported python implementation
list in _python_impl_supported() from python-utils-r1 -- ie, when that
list changes, some packages may suddenly require PYTHON_SINGLE_TARGET
be set while others just-as-suddenly won't need it.  This may mean
some extra rebuilds for users on "emerge -N", especially as the flags
are dropped.

Please note that documentation is likely going to need updating; I
tried but more work is going to be required on that front.  The eerror
section at the bottom of python-setup is particularily nasty and
likely needs adjusting.  Otherwise though, functionality seems to work
as expected without any side-effects in my 10 minutes of testing.

Thoughts and feedback appreciated -- I think incorporating this will
really help out end-users that don't want to remain locked to python-2.7


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iF4EAREIAAYFAlRRLzkACgkQ2ugaI38ACPBnPQEAmq0mB+jzbKc/M2y971d5SdvV
+jFtXvJgWEmKMbABKQsBALImzNqOBirDomrPYrYLHc/JeblZUkWvVwNkQMZ3Qwyl
=T/jY
-----END PGP SIGNATURE-----

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 4314 bytes --]

--- python-single-r1.eclass	2014-10-29 12:59:38.000000000 -0400
+++ /tmp/python-single-r1.eclass	2014-10-29 12:19:23.000000000 -0400
@@ -136,8 +136,9 @@
 
 # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
 # @DESCRIPTION:
-# This is an eclass-generated required-use expression which ensures the following:
-# 1. Exactly one PYTHON_SINGLE_TARGET value has been enabled.
+# This is an eclass-generated required-use expression which ensures the following
+# when more than one python implementation is possible:
+# 1. Exactly one PYTHON_SINGLE_TARGET value has been enabled
 # 2. The selected PYTHON_SINGLE_TARGET value is enabled in PYTHON_TARGETS.
 #
 # This expression should be utilized in an ebuild by including it in
@@ -155,22 +156,21 @@
 # ^^ ( python_single_target_python2_6 python_single_target_python2_7 )
 # @CODE
 
+# @ECLASS-VARIABLE: _PYTHON_SINGLE_TARGET_INUSE
+# @INTERNAL
+# @DESCRIPTION:
+# This is a read-only variable which is set when it is determined
+# that there is more than one possible supported python target,
+# and so the PYTHON_SINGLE_TARGET use-expand will take effect.
+
 _python_single_set_globals() {
 	local impls=()
 
+	_PYTHON_SINGLE_TARGET_INUSE=0
 	PYTHON_DEPS=
 	local i PYTHON_PKG_DEP
 	for i in "${PYTHON_COMPAT[@]}"; do
 		_python_impl_supported "${i}" || continue
-
-		# The chosen targets need to be in PYTHON_TARGETS as well.
-		# This is in order to enforce correct dependencies on packages
-		# supporting multiple implementations.
-		PYTHON_REQUIRED_USE+=" python_single_target_${i}? ( python_targets_${i} )"
-
-		python_export "${i}" PYTHON_PKG_DEP
-		PYTHON_DEPS+="python_single_target_${i}? ( ${PYTHON_PKG_DEP} ) "
-
 		impls+=( "${i}" )
 	done
 
@@ -182,11 +182,34 @@
 	local flags=( "${impls[@]/#/python_single_target_}" )
 
 	local optflags=${flags_mt[@]/%/(-)?}
-	optflags+=,${flags[@]/%/(+)?}
 
-	IUSE="${flags_mt[*]} ${flags[*]}"
-	PYTHON_REQUIRED_USE+=" ^^ ( ${flags[*]} )"
-	PYTHON_USEDEP=${optflags// /,}
+	if [[ ${#impls[@]} -eq 1 ]]; then
+		# One implementation, don't set python_single_target* in IUSE
+		# and set deps directly according to value of ${impls[@]}
+		IUSE="${flags_mt[*]}"
+		PYTHON_USEDEP=${optflags// /,}
+		python_export "${impls[@]}" PYTHON_PKG_DEP
+		PYTHON_DEPS="${PYTHON_PKG_DEP} "
+		_PYTHON_SINGLE_TARGET_INUSE=1
+	else
+		# Multiple possible implementations, prepare deps and IUSE
+		# for inclusion of python_single_target*
+		for i in "${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.
+			PYTHON_REQUIRED_USE+=" python_single_target_${i}? ( python_targets_${i} )"
+
+			python_export "${i}" PYTHON_PKG_DEP
+			PYTHON_DEPS+="python_single_target_${i}? ( ${PYTHON_PKG_DEP} ) "
+		done
+
+		optflags+=,${flags[@]/%/(+)?}
+
+		IUSE="${flags_mt[*]} ${flags[*]}"
+		PYTHON_REQUIRED_USE+=" ^^ ( ${flags[*]} )"
+		PYTHON_USEDEP=${optflags// /,}
+	fi
 
 	# 1) well, python-exec would suffice as an RDEP
 	# but no point in making this overcomplex, BDEP doesn't hurt anyone
@@ -216,6 +239,17 @@
 	local impl
 	for impl in "${_PYTHON_ALL_IMPLS[@]}"; do
 		if has "${impl}" "${PYTHON_COMPAT[@]}" \
+			&& [[ ! ${_PYTHON_SINGLE_TARGET_INUSE} ]] \
+			&& use "python_targets_${impl}"
+		then
+			# Only one implementation possible since
+			# _PYTHON_SINGLE_TARGET_INUSE is false,
+			# enable it explicitly
+			python_export "${impl}" EPYTHON PYTHON
+			python_wrapper_setup
+
+		elif has "${impl}" "${PYTHON_COMPAT[@]}" \
+			&& [[ ${_PYTHON_SINGLE_TARGET_INUSE} ]] \
 			&& use "python_single_target_${impl}"
 		then
 			if [[ ${EPYTHON} ]]; then
@@ -243,12 +277,21 @@
 
 	if [[ ! ${EPYTHON} ]]; then
 		eerror "No Python implementation selected for the build. Please set"
+		if [[ ${_PYTHON_SINGLE_TARGET_INUSE} ]]; then
 		eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
 		eerror "of the following values:"
 		eerror
 		eerror "${PYTHON_COMPAT[@]}"
 		echo
 		die "No supported Python implementation in PYTHON_SINGLE_TARGET."
+		else
+		eerror "the PYTHON_TARGETS variable in your make.conf to include one"
+		eerror "of the following values:"
+		eerror
+		eerror "${PYTHON_COMPAT[@]}"
+		echo
+		die "Only supported Python implementation not in PYTHON_TARGETS."
+		fi
 	fi
 }
 

             reply	other threads:[~2014-10-29 18:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-29 18:17 Ian Stakenvicius [this message]
2014-10-29 18:25 ` [gentoo-python] Reducing exceptionality cases for PYTHON_SINGLE_TARGET W. Trevor King
2014-10-29 18:40   ` Ian Stakenvicius
     [not found]   ` <5451330B.7000705@gentoo.org>
     [not found]     ` <20141029184254.GI15443@odin.tremily.us>
2014-10-29 18:47       ` Ian Stakenvicius
2014-10-29 18:31 ` Michał Górny
2014-10-29 18:39   ` Ian Stakenvicius
2014-10-29 20:09     ` Michał Górny
2014-10-29 20:21       ` Mike Gilbert
2014-10-29 20:25         ` Michał Górny
2014-10-30 19:21           ` Ian Stakenvicius
2014-10-30 19:43             ` Michał Górny
2014-10-30 20:26               ` Mike Gilbert
2014-10-30 21:31                 ` Michał Górny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54512F39.8080104@gentoo.org \
    --to=axs@gentoo.org \
    --cc=gentoo-python@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox