Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 559664 - python-r1.eclass - python_gen_cond_dep() puts too many implementations inside conditional blocks
Summary: python-r1.eclass - python_gen_cond_dep() puts too many implementations inside...
Status: RESOLVED WONTFIX
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Python Gentoo Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-09-05 13:44 UTC by eroen
Modified: 2017-03-10 16:04 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description eroen 2015-09-05 13:44:35 UTC
While looking at the blocker in beautifulsoup-4.4.0 dependencies (leading to [1]), I noticed that python_gen_usedep() does not behave according to its documentation[2]. I consulted floppym in irc. Floppym found it odd.

Example ebuild:
    EAPI=5
    PYTHON_COMPAT=(python{2_7,3_4})
    inherit python-r1
    SLOT="0"
    DEPEND="$(python_gen_cond_dep '!dev-python/chardet[${PYTHON_USEDEP}]' "${PYTHON_COMPAT[@]}")"

    echo $DEPEND

Output:
    eroen@occam /usr/local/portage/app-misc/python-blocker $ ebuild python-blocker-0.ebuild clean pretend
    python_targets_python2_7? ( !dev-python/chardet[python_targets_python2_7(-)?,-python_single_target_python2_7(-),python_targets_python3_4(-)?,-python_single_target_python3_4(-)] ) python_targets_python3_4? ( !dev-python/chardet[python_targets_python2_7(-)?,-python_single_target_python2_7(-),python_targets_python3_4(-)?,-python_single_target_python3_4(-)] )


I expect:
    python_targets_python2_7? ( !dev-python/chardet[python_targets_python2_7(-)?,-python_single_target_python2_7(-)] ) python_targets_python3_4? ( !dev-python/chardet[python_targets_python2_7(-)?,-python_single_target_python2_7(-)] )

This is no big deal for most usage, but when making a blocker it becomes troublesome.

1: https://gitweb.gentoo.org/repo/gentoo.git/commit?id=6cb2905fafdd2f2c0407c2bb4a1bc12b6f3126a9
2: https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/python-r1.eclass#n344
Comment 1 eroen 2015-09-05 13:45:39 UTC
Suggested change:

--- eclass/python-r1.eclass
+++ eclass/python-r1.eclass
@@ -385,7 +385,7 @@
 				# (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 "${@}")
+					local PYTHON_USEDEP=$(python_gen_usedep "$impl")
 					dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
 				fi
Comment 2 eroen 2015-09-05 14:23:40 UTC
Err, no. My suggestion is wrong and doesn't work.

Expected result should really be be:
python_targets_python2_7? ( !dev-python/chardet[python_targets_python2_7(-)?,-python_single_target_python2_7(-)] ) python_targets_python3_4? ( !dev-python/chardet[python_targets_python3_4(-)?,-python_single_target_python3_4(-)] )
Comment 3 eroen 2015-09-05 15:25:29 UTC
Suggested change 2:

--- eclass/python-r1.eclass
+++ eclass/python-r1.eclass
@@ -373,19 +373,20 @@
 	local impl pattern
 	local matches=()
 
-	local dep=${1}
+	local orig_dep=${1}
 	shift
 
 	for impl in "${PYTHON_COMPAT[@]}"; do
 		_python_impl_supported "${impl}" || continue
 
-		for pattern; do
+		for pattern in "$@"; do
 			if [[ ${impl} == ${pattern} ]]; then
+				local dep="$orig_dep"
 				# substitute ${PYTHON_USEDEP} if used
-				# (since python_gen_usedep() will not return ${PYTHON_USEDEP}
-				#  the code is run at most once)
+				# (python_gen_usedep() will run several times, once for each
+				# implementation in PYTHON_COMPAT)
 				if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
-					local PYTHON_USEDEP=$(python_gen_usedep "${@}")
+					local PYTHON_USEDEP=$(python_gen_usedep "${pattern}")
 					dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
 				fi
 

It might also be prudent to explicitly mention in documentation that real variable substitution for the "dep" argument doesn't work.
Comment 4 eroen 2015-09-05 15:56:06 UTC
This difference between docs and behaviour has existed since the functionality was added.[3]


> It might also be prudent to explicitly mention in documentation that real variable substitution for the "dep" argument doesn't work.

Apologies, this is already the case, but it is not rendered correctly in the man pages, which makes it easy to miss.


3: https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/eclass/python-r1.eclass?r1=1.71&r2=1.72
Comment 5 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2015-09-10 19:22:55 UTC
The idea behind it was rather simple: it's easier and less wasteful to generate one USE-dep and reuse it for all blocks than generate N different strings. Additionally, having them all in the first block means Portage will output better suggestions like 'enable three pythons' instead of 'enable first python', 'enable second python'...
Comment 6 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2015-10-23 17:13:55 UTC
First of all, please don't paste patches inline, bugzie will break them. Either attach them, or (preferable for me) open a pull request with eclass change on github.

(In reply to eroen from comment #3)
> Suggested change 2:
> 
> --- eclass/python-r1.eclass
> +++ eclass/python-r1.eclass
> @@ -373,19 +373,20 @@
>  	local impl pattern
>  	local matches=()
>  
> -	local dep=${1}
> +	local orig_dep=${1}
>  	shift
>  
>  	for impl in "${PYTHON_COMPAT[@]}"; do
>  		_python_impl_supported "${impl}" || continue
>  
> -		for pattern; do
> +		for pattern in "$@"; do

Unrelated and unnecessary.

>  			if [[ ${impl} == ${pattern} ]]; then
> +				local dep="$orig_dep"



>  				# substitute ${PYTHON_USEDEP} if used
> -				# (since python_gen_usedep() will not return ${PYTHON_USEDEP}
> -				#  the code is run at most once)
> +				# (python_gen_usedep() will run several times, once for each
> +				# implementation in PYTHON_COMPAT)

Remove the comment inside () completely, it was only explaining implicit behavior which is irrelevant now.

>  				if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
> -					local PYTHON_USEDEP=$(python_gen_usedep "${@}")
> +					local PYTHON_USEDEP=$(python_gen_usedep "${pattern}")
>  					dep=${dep//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
>  				fi
>  
> 
> It might also be prudent to explicitly mention in documentation that real
> variable substitution for the "dep" argument doesn't work.

Also, please check how Portage behaves when it needs to enable more than one flag on dependency, with --autounmask disabled, enabled and enabled with --autounmask-write. In particular, if Portage catches two missing flags immediately or requests two changes in a row.
Comment 7 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2017-03-10 16:04:10 UTC
No reply since Oct 2015, plus I still don't see a major reason to change that.