Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: eclass/
Date: Tue, 22 Dec 2015 22:12:46
Message-Id: 1450822343.33380ad5e121a47375442de08fd9239b9102b1fa.mgorny@gentoo
1 commit: 33380ad5e121a47375442de08fd9239b9102b1fa
2 Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
3 AuthorDate: Sat Dec 12 22:06:33 2015 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Tue Dec 22 22:12:23 2015 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=33380ad5
7
8 python*-r1.eclass: Commonize PYTHON_COMPAT processing, cache the result
9
10 Introduce a common _python_set_impls function in python-utils-r1.eclass
11 that validates and processes PYTHON_COMPAT, then stores the result in
12 _PYTHON_SUPPORTED_IMPLS and _PYTHON_UNSUPPORTED_IMPLS variables. Reuse
13 those variables in all python-r1 suite eclasses, effectively reducing
14 code duplication and providing cache for repeated implementation support
15 checks.
16
17 eclass/python-any-r1.eclass | 28 +++++--------------
18 eclass/python-r1.eclass | 47 ++++++++------------------------
19 eclass/python-single-r1.eclass | 61 ++++++++++++------------------------------
20 eclass/python-utils-r1.eclass | 49 +++++++++++++++++++++++++++++++++
21 4 files changed, 83 insertions(+), 102 deletions(-)
22
23 diff --git a/eclass/python-any-r1.eclass b/eclass/python-any-r1.eclass
24 index 721ba45..dbfeded 100644
25 --- a/eclass/python-any-r1.eclass
26 +++ b/eclass/python-any-r1.eclass
27 @@ -71,12 +71,6 @@ if [[ ! ${_PYTHON_ANY_R1} ]]; then
28 # @CODE
29 # PYTHON_COMPAT=( python{2_5,2_6,2_7} )
30 # @CODE
31 -if ! declare -p PYTHON_COMPAT &>/dev/null; then
32 - die 'PYTHON_COMPAT not declared.'
33 -fi
34 -if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
35 - die 'PYTHON_COMPAT must be an array.'
36 -fi
37
38 # @ECLASS-VARIABLE: PYTHON_REQ_USE
39 # @DEFAULT_UNSET
40 @@ -119,16 +113,10 @@ _python_any_set_globals() {
41 local usestr i PYTHON_PKG_DEP
42 [[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
43
44 - # check for invalid PYTHON_COMPAT
45 - for i in "${PYTHON_COMPAT[@]}"; do
46 - # the function simply dies on invalid impl
47 - _python_impl_supported "${i}"
48 - done
49 + _python_set_impls
50
51 PYTHON_DEPS=
52 - for i in "${_PYTHON_ALL_IMPLS[@]}"; do
53 - has "${i}" "${PYTHON_COMPAT[@]}" || continue
54 -
55 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
56 python_export "${i}" PYTHON_PKG_DEP
57
58 PYTHON_DEPS="${PYTHON_PKG_DEP} ${PYTHON_DEPS}"
59 @@ -209,9 +197,7 @@ python_gen_any_dep() {
60 [[ ${depstr} ]] || die "No dependency string provided"
61
62 local PYTHON_PKG_DEP out=
63 - for i in "${_PYTHON_ALL_IMPLS[@]}"; do
64 - has "${i}" "${PYTHON_COMPAT[@]}" || continue
65 -
66 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
67 local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
68 python_export "${i}" PYTHON_PKG_DEP
69
70 @@ -242,7 +228,7 @@ _python_EPYTHON_supported() {
71 ;;
72 esac
73
74 - if has "${i}" "${PYTHON_COMPAT[@]}"; then
75 + if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
76 if python_is_installed "${i}"; then
77 if declare -f python_check_deps >/dev/null; then
78 local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
79 @@ -293,10 +279,8 @@ python_setup() {
80
81 # fallback to best installed impl.
82 local rev_impls=()
83 - for i in "${_PYTHON_ALL_IMPLS[@]}"; do
84 - if has "${i}" "${PYTHON_COMPAT[@]}"; then
85 - rev_impls=( "${i}" "${rev_impls[@]}" )
86 - fi
87 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
88 + rev_impls=( "${i}" "${rev_impls[@]}" )
89 done
90
91 for i in "${rev_impls[@]}"; do
92
93 diff --git a/eclass/python-r1.eclass b/eclass/python-r1.eclass
94 index fbc39dc..f7a8541 100644
95 --- a/eclass/python-r1.eclass
96 +++ b/eclass/python-r1.eclass
97 @@ -82,12 +82,6 @@ inherit multibuild python-utils-r1
98 # @CODE
99 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
100 # @CODE
101 -if ! declare -p PYTHON_COMPAT &>/dev/null; then
102 - die 'PYTHON_COMPAT not declared.'
103 -fi
104 -if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
105 - die 'PYTHON_COMPAT must be an array.'
106 -fi
107
108 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
109 # @INTERNAL
110 @@ -186,24 +180,17 @@ fi
111 # @CODE
112
113 _python_set_globals() {
114 - local impls=()
115 -
116 PYTHON_DEPS=
117 local i PYTHON_PKG_DEP
118 - for i in "${PYTHON_COMPAT[@]}"; do
119 - _python_impl_supported "${i}" || continue
120
121 + _python_set_impls
122 +
123 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
124 python_export "${i}" PYTHON_PKG_DEP
125 PYTHON_DEPS+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) "
126 -
127 - impls+=( "${i}" )
128 done
129
130 - if [[ ${#impls[@]} -eq 0 ]]; then
131 - die "No supported implementation in PYTHON_COMPAT."
132 - fi
133 -
134 - local flags=( "${impls[@]/#/python_targets_}" )
135 + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
136 local optflags=${flags[@]/%/(-)?}
137
138 # A nice QA trick here. Since a python-single-r1 package has to have
139 @@ -212,7 +199,7 @@ _python_set_globals() {
140 # it should prevent developers from mistakenly depending on packages
141 # not supporting multiple Python implementations.
142
143 - local flags_st=( "${impls[@]/#/-python_single_target_}" )
144 + local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" )
145 optflags+=,${flags_st[@]/%/(-)}
146
147 IUSE=${flags[*]}
148 @@ -246,9 +233,7 @@ _python_validate_useflags() {
149
150 local i
151
152 - for i in "${PYTHON_COMPAT[@]}"; do
153 - _python_impl_supported "${i}" || continue
154 -
155 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
156 use "python_targets_${i}" && return 0
157 done
158
159 @@ -290,9 +275,7 @@ python_gen_usedep() {
160 local impl pattern
161 local matches=()
162
163 - for impl in "${PYTHON_COMPAT[@]}"; do
164 - _python_impl_supported "${impl}" || continue
165 -
166 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
167 for pattern; do
168 if [[ ${impl} == ${pattern} ]]; then
169 matches+=(
170 @@ -333,9 +316,7 @@ python_gen_useflags() {
171 local impl pattern
172 local matches=()
173
174 - for impl in "${PYTHON_COMPAT[@]}"; do
175 - _python_impl_supported "${impl}" || continue
176 -
177 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
178 for pattern; do
179 if [[ ${impl} == ${pattern} ]]; then
180 matches+=( "python_targets_${impl}" )
181 @@ -382,9 +363,7 @@ python_gen_cond_dep() {
182 local dep=${1}
183 shift
184
185 - for impl in "${PYTHON_COMPAT[@]}"; do
186 - _python_impl_supported "${impl}" || continue
187 -
188 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
189 for pattern; do
190 if [[ ${impl} == ${pattern} ]]; then
191 # substitute ${PYTHON_USEDEP} if used
192 @@ -460,12 +439,8 @@ _python_obtain_impls() {
193
194 MULTIBUILD_VARIANTS=()
195
196 - for impl in "${_PYTHON_ALL_IMPLS[@]}"; do
197 - if has "${impl}" "${PYTHON_COMPAT[@]}" \
198 - && use "python_targets_${impl}"
199 - then
200 - MULTIBUILD_VARIANTS+=( "${impl}" )
201 - fi
202 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
203 + use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" )
204 done
205 }
206
207
208 diff --git a/eclass/python-single-r1.eclass b/eclass/python-single-r1.eclass
209 index b8684f0..8ef3846 100644
210 --- a/eclass/python-single-r1.eclass
211 +++ b/eclass/python-single-r1.eclass
212 @@ -95,12 +95,6 @@ if [[ ! ${_PYTHON_SINGLE_R1} ]]; then
213 # @CODE
214 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
215 # @CODE
216 -if ! declare -p PYTHON_COMPAT &>/dev/null; then
217 - die 'PYTHON_COMPAT not declared.'
218 -fi
219 -if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
220 - die 'PYTHON_COMPAT must be an array.'
221 -fi
222
223 # @ECLASS-VARIABLE: PYTHON_REQ_USE
224 # @DEFAULT_UNSET
225 @@ -186,34 +180,24 @@ fi
226 # @CODE
227
228 _python_single_set_globals() {
229 - local impls=()
230 - local unimpls=()
231 + _python_set_impls
232
233 PYTHON_DEPS=
234 local i PYTHON_PKG_DEP
235 - for i in "${_PYTHON_ALL_IMPLS[@]}"; do
236 - has "${i}" "${PYTHON_COMPAT[@]}" \
237 - && impls+=( "${i}" ) \
238 - || unimpls+=( "${i}" )
239 - done
240 -
241 - if [[ ${#impls[@]} -eq 0 ]]; then
242 - die "No supported implementation in PYTHON_COMPAT."
243 - fi
244
245 - local flags_mt=( "${impls[@]/#/python_targets_}" )
246 - local flags=( "${impls[@]/#/python_single_target_}" )
247 - local unflags=( "${unimpls[@]/#/-python_single_target_}" )
248 + local flags_mt=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
249 + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
250 + local unflags=( "${_PYTHON_UNSUPPORTED_IMPLS[@]/#/-python_single_target_}" )
251
252 local optflags=${flags_mt[@]/%/(-)?},${unflags[@]/%/(-)}
253
254 IUSE="${flags_mt[*]}"
255
256 - if [[ ${#impls[@]} -eq 1 ]]; then
257 + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
258 # There is only one supported implementation; set IUSE and other
259 # variables without PYTHON_SINGLE_TARGET.
260 PYTHON_REQUIRED_USE="${flags_mt[*]}"
261 - python_export "${impls[0]}" PYTHON_PKG_DEP
262 + python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" PYTHON_PKG_DEP
263 PYTHON_DEPS="${PYTHON_PKG_DEP} "
264 # Force on the python_single_target_* flag for this impl, so
265 # that any dependencies that inherit python-single-r1 and
266 @@ -228,7 +212,7 @@ _python_single_set_globals() {
267 # on this package.
268 optflags+=,${flags[@]/%/(+)?}
269
270 - for i in "${impls[@]}"; do
271 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
272 # The chosen targets need to be in PYTHON_TARGETS as well.
273 # This is in order to enforce correct dependencies on packages
274 # supporting multiple implementations.
275 @@ -288,9 +272,7 @@ python_gen_usedep() {
276 local impl pattern
277 local matches=()
278
279 - for impl in "${PYTHON_COMPAT[@]}"; do
280 - _python_impl_supported "${impl}" || continue
281 -
282 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
283 for pattern; do
284 if [[ ${impl} == ${pattern} ]]; then
285 matches+=(
286 @@ -331,9 +313,7 @@ python_gen_useflags() {
287 local impl pattern
288 local matches=()
289
290 - for impl in "${PYTHON_COMPAT[@]}"; do
291 - _python_impl_supported "${impl}" || continue
292 -
293 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
294 for pattern; do
295 if [[ ${impl} == ${pattern} ]]; then
296 matches+=( "python_single_target_${impl}" )
297 @@ -380,9 +360,7 @@ python_gen_cond_dep() {
298 local dep=${1}
299 shift
300
301 - for impl in "${PYTHON_COMPAT[@]}"; do
302 - _python_impl_supported "${impl}" || continue
303 -
304 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
305 for pattern; do
306 if [[ ${impl} == ${pattern} ]]; then
307 # substitute ${PYTHON_USEDEP} if used
308 @@ -411,20 +389,15 @@ python_setup() {
309
310 unset EPYTHON
311
312 - local impl impls=()
313 - for impl in "${PYTHON_COMPAT[@]}"; do
314 - _python_impl_supported "${impl}" || continue
315 - impls+=( "${impl}" )
316 - done
317 -
318 - if [[ ${#impls[@]} -eq 1 ]]; then
319 - if use "python_targets_${impls[0]}"; then
320 + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
321 + if use "python_targets_${_PYTHON_SUPPORTED_IMPLS[0]}"; then
322 # Only one supported implementation, enable it explicitly
323 - python_export "${impls[0]}" EPYTHON PYTHON
324 + python_export "${_PYTHON_SUPPORTED_IMPLS[0]}" EPYTHON PYTHON
325 python_wrapper_setup
326 fi
327 else
328 - for impl in "${impls[@]}"; do
329 + local impl
330 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
331 if use "python_single_target_${impl}"; then
332 if [[ ${EPYTHON} ]]; then
333 eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
334 @@ -452,14 +425,14 @@ python_setup() {
335
336 if [[ ! ${EPYTHON} ]]; then
337 eerror "No Python implementation selected for the build. Please set"
338 - if [[ ${#impls[@]} -eq 1 ]]; then
339 + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
340 eerror "the PYTHON_TARGETS variable in your make.conf to include one"
341 else
342 eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
343 fi
344 eerror "of the following values:"
345 eerror
346 - eerror "${impls[@]}"
347 + eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
348 echo
349 die "No supported Python implementation in PYTHON_SINGLE_TARGET/PYTHON_TARGETS."
350 fi
351
352 diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass
353 index 7830323..89a7cbf 100644
354 --- a/eclass/python-utils-r1.eclass
355 +++ b/eclass/python-utils-r1.eclass
356 @@ -84,6 +84,55 @@ _python_impl_supported() {
357 esac
358 }
359
360 +# @FUNCTION: _python_set_impls
361 +# @INTERNAL
362 +# @DESCRIPTION:
363 +# Check PYTHON_COMPAT for well-formedness and validity, then set
364 +# two global variables:
365 +#
366 +# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
367 +# by the ebuild (PYTHON_COMPAT - dead implementations),
368 +#
369 +# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
370 +# are not supported by the ebuild.
371 +#
372 +# Implementations in both variables are ordered using the pre-defined
373 +# eclass implementation ordering.
374 +#
375 +# This function must be called once in global scope by an eclass
376 +# utilizing PYTHON_COMPAT.
377 +_python_set_impls() {
378 + local i
379 +
380 + if ! declare -p PYTHON_COMPAT &>/dev/null; then
381 + die 'PYTHON_COMPAT not declared.'
382 + fi
383 + if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
384 + die 'PYTHON_COMPAT must be an array.'
385 + fi
386 + for i in "${PYTHON_COMPAT[@]}"; do
387 + # trigger validity checks
388 + _python_impl_supported "${i}"
389 + done
390 +
391 + _PYTHON_SUPPORTED_IMPLS=()
392 + _PYTHON_UNSUPPORTED_IMPLS=()
393 +
394 + for i in "${_PYTHON_ALL_IMPLS[@]}"; do
395 + if has "${i}" "${PYTHON_COMPAT[@]}"; then
396 + _PYTHON_SUPPORTED_IMPLS+=( "${i}" )
397 + else
398 + _PYTHON_UNSUPPORTED_IMPLS+=( "${i}" )
399 + fi
400 + done
401 +
402 + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 0 ]]; then
403 + die "No supported implementation in PYTHON_COMPAT."
404 + fi
405 +
406 + readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
407 +}
408 +
409 # @ECLASS-VARIABLE: PYTHON
410 # @DEFAULT_UNSET
411 # @DESCRIPTION: