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