1 |
commit: 65bd67b167c1f5445f433cb4d62fdf7931d3fb7a |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue May 10 06:22:06 2022 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue May 10 06:22:06 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=65bd67b1 |
7 |
|
8 |
python-utils-r1.eclass: sync with gx86 |
9 |
|
10 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
11 |
|
12 |
eclass/python-utils-r1.eclass | 211 ++++++++++++++++++++++-------------------- |
13 |
1 file changed, 112 insertions(+), 99 deletions(-) |
14 |
|
15 |
diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass |
16 |
index a96fbc78a7..48b6ea484b 100644 |
17 |
--- a/eclass/python-utils-r1.eclass |
18 |
+++ b/eclass/python-utils-r1.eclass |
19 |
@@ -37,17 +37,17 @@ if [[ ! ${_PYTHON_UTILS_R1} ]]; then |
20 |
[[ ${EAPI} == [67] ]] && inherit eapi8-dosym |
21 |
inherit multiprocessing toolchain-funcs |
22 |
|
23 |
-# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS |
24 |
+# @ECLASS_VARIABLE: _PYTHON_ALL_IMPLS |
25 |
# @INTERNAL |
26 |
# @DESCRIPTION: |
27 |
# All supported Python implementations, most preferred last. |
28 |
_PYTHON_ALL_IMPLS=( |
29 |
pypy3 |
30 |
- python3_{8..10} |
31 |
+ python3_{8..11} |
32 |
) |
33 |
readonly _PYTHON_ALL_IMPLS |
34 |
|
35 |
-# @ECLASS-VARIABLE: _PYTHON_HISTORICAL_IMPLS |
36 |
+# @ECLASS_VARIABLE: _PYTHON_HISTORICAL_IMPLS |
37 |
# @INTERNAL |
38 |
# @DESCRIPTION: |
39 |
# All historical Python implementations that are no longer supported. |
40 |
@@ -59,7 +59,7 @@ _PYTHON_HISTORICAL_IMPLS=( |
41 |
) |
42 |
readonly _PYTHON_HISTORICAL_IMPLS |
43 |
|
44 |
-# @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT |
45 |
+# @ECLASS_VARIABLE: PYTHON_COMPAT_NO_STRICT |
46 |
# @INTERNAL |
47 |
# @DESCRIPTION: |
48 |
# Set to a non-empty value in order to make eclass tolerate (ignore) |
49 |
@@ -83,7 +83,7 @@ _python_verify_patterns() { |
50 |
local impl pattern |
51 |
for pattern; do |
52 |
case ${pattern} in |
53 |
- -[23]|3.[89]|3.10) |
54 |
+ -[23]|3.[89]|3.1[01]) |
55 |
continue |
56 |
;; |
57 |
esac |
58 |
@@ -132,7 +132,7 @@ _python_set_impls() { |
59 |
# please keep them in sync with _PYTHON_ALL_IMPLS |
60 |
# and _PYTHON_HISTORICAL_IMPLS |
61 |
case ${i} in |
62 |
- pypy3|python2_7|python3_[89]|python3_10) |
63 |
+ pypy3|python2_7|python3_[89]|python3_1[01]) |
64 |
;; |
65 |
jython2_7|pypy|pypy1_[89]|pypy2_0|python2_[5-6]|python3_[1-7]) |
66 |
obsolete+=( "${i}" ) |
67 |
@@ -240,12 +240,12 @@ _python_impl_matches() { |
68 |
fi |
69 |
return 0 |
70 |
;; |
71 |
- 3.8) |
72 |
- # the only unmasked pypy3 version is pypy3.8 atm |
73 |
+ 3.9) |
74 |
+ # the only unmasked pypy3 version is pypy3.9 atm |
75 |
[[ ${impl} == python${pattern/./_} || ${impl} == pypy3 ]] && |
76 |
return 0 |
77 |
;; |
78 |
- 3.9|3.10) |
79 |
+ 3.8|3.1[01]) |
80 |
[[ ${impl} == python${pattern/./_} ]] && return 0 |
81 |
;; |
82 |
*) |
83 |
@@ -258,7 +258,7 @@ _python_impl_matches() { |
84 |
return 1 |
85 |
} |
86 |
|
87 |
-# @ECLASS-VARIABLE: PYTHON |
88 |
+# @ECLASS_VARIABLE: PYTHON |
89 |
# @DEFAULT_UNSET |
90 |
# @DESCRIPTION: |
91 |
# The absolute path to the current Python interpreter. |
92 |
@@ -277,7 +277,7 @@ _python_impl_matches() { |
93 |
# /usr/bin/python2.7 |
94 |
# @CODE |
95 |
|
96 |
-# @ECLASS-VARIABLE: EPYTHON |
97 |
+# @ECLASS_VARIABLE: EPYTHON |
98 |
# @DEFAULT_UNSET |
99 |
# @DESCRIPTION: |
100 |
# The executable name of the current Python interpreter. |
101 |
@@ -476,11 +476,13 @@ _python_export() { |
102 |
python2.7) |
103 |
PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';; |
104 |
python3.8) |
105 |
- PYTHON_PKG_DEP=">=dev-lang/python-3.8.8_p1-r1:3.8";; |
106 |
+ PYTHON_PKG_DEP=">=dev-lang/python-3.8.12_p1-r1:3.8";; |
107 |
python3.9) |
108 |
- PYTHON_PKG_DEP=">=dev-lang/python-3.9.6_p1-r1:3.9";; |
109 |
+ PYTHON_PKG_DEP=">=dev-lang/python-3.9.9-r1:3.9";; |
110 |
python3.10) |
111 |
PYTHON_PKG_DEP=">=dev-lang/python-3.10.0_p1-r1:3.10";; |
112 |
+ python3.11) |
113 |
+ PYTHON_PKG_DEP=">=dev-lang/python-3.11.0_beta1-r1:3.11";; |
114 |
python*) |
115 |
PYTHON_PKG_DEP="dev-lang/python:${impl#python}";; |
116 |
pypy) |
117 |
@@ -659,9 +661,7 @@ python_optimize() { |
118 |
debug-print "${FUNCNAME}: using sys.path: ${*/%/;}" |
119 |
fi |
120 |
|
121 |
- local jobs=$(makeopts_jobs "${MAKEOPTS}" INF) |
122 |
- [[ ${jobs} == INF ]] && jobs=$(get_nproc) |
123 |
- |
124 |
+ local jobs=$(makeopts_jobs) |
125 |
local d |
126 |
for d; do |
127 |
# make sure to get a nice path without // |
128 |
@@ -1029,25 +1029,30 @@ _python_wrapper_setup() { |
129 |
# @FUNCTION: python_fix_shebang |
130 |
# @USAGE: [-f|--force] [-q|--quiet] <path>... |
131 |
# @DESCRIPTION: |
132 |
-# Replace the shebang in Python scripts with the current Python |
133 |
-# implementation (EPYTHON). If a directory is passed, works recursively |
134 |
-# on all Python scripts. |
135 |
+# Replace the shebang in Python scripts with the full path |
136 |
+# to the current Python implementation (PYTHON, including EPREFIX). |
137 |
+# If a directory is passed, works recursively on all Python scripts |
138 |
+# found inside the directory tree. |
139 |
# |
140 |
-# Only files having a 'python*' shebang will be modified. Files with |
141 |
-# other shebang will either be skipped when working recursively |
142 |
-# on a directory or treated as error when specified explicitly. |
143 |
+# Only files having a Python shebang (a path to any known Python |
144 |
+# interpreter, optionally preceded by env(1) invocation) will |
145 |
+# be processed. Files with any other shebang will either be skipped |
146 |
+# silently when a directory was passed, or an error will be reported |
147 |
+# for any files without Python shebangs specified explicitly. |
148 |
# |
149 |
-# Shebangs matching explicitly current Python version will be left |
150 |
-# unmodified. Shebangs requesting another Python version will be treated |
151 |
-# as fatal error, unless --force is given. |
152 |
+# Shebangs that are compatible with the current Python version will be |
153 |
+# mangled unconditionally. Incompatible shebangs will cause a fatal |
154 |
+# error, unless --force is specified. |
155 |
# |
156 |
-# --force causes the function to replace even shebangs that require |
157 |
-# incompatible Python version. --quiet causes the function not to list |
158 |
-# modified files verbosely. |
159 |
+# --force causes the function to replace shebangs with incompatible |
160 |
+# Python version (but not non-Python shebangs). --quiet causes |
161 |
+# the function not to list modified files verbosely. |
162 |
python_fix_shebang() { |
163 |
debug-print-function ${FUNCNAME} "${@}" |
164 |
|
165 |
[[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)" |
166 |
+ local PYTHON |
167 |
+ _python_export "${EPYTHON}" PYTHON |
168 |
|
169 |
local force quiet |
170 |
while [[ ${@} ]]; do |
171 |
@@ -1063,13 +1068,13 @@ python_fix_shebang() { |
172 |
|
173 |
local path f |
174 |
for path; do |
175 |
- local any_correct any_fixed is_recursive |
176 |
+ local any_fixed is_recursive |
177 |
|
178 |
[[ -d ${path} ]] && is_recursive=1 |
179 |
|
180 |
while IFS= read -r -d '' f; do |
181 |
local shebang i |
182 |
- local error= from= |
183 |
+ local error= match= |
184 |
|
185 |
# note: we can't ||die here since read will fail if file |
186 |
# has no newline characters |
187 |
@@ -1078,64 +1083,36 @@ python_fix_shebang() { |
188 |
# First, check if it's shebang at all... |
189 |
if [[ ${shebang} == '#!'* ]]; then |
190 |
local split_shebang=() |
191 |
- read -r -a split_shebang <<<${shebang} || die |
192 |
- |
193 |
- # Match left-to-right in a loop, to avoid matching random |
194 |
- # repetitions like 'python2.7 python2'. |
195 |
- for i in "${split_shebang[@]}"; do |
196 |
- case "${i}" in |
197 |
- *"${EPYTHON}") |
198 |
- debug-print "${FUNCNAME}: in file ${f#${D%/}}" |
199 |
- debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}" |
200 |
- |
201 |
- # Nothing to do, move along. |
202 |
- any_correct=1 |
203 |
- from=${EPYTHON} |
204 |
- break |
205 |
- ;; |
206 |
- *python|*python[23]) |
207 |
- debug-print "${FUNCNAME}: in file ${f#${D%/}}" |
208 |
- debug-print "${FUNCNAME}: rewriting shebang: ${shebang}" |
209 |
- |
210 |
- if [[ ${i} == *python2 ]]; then |
211 |
- from=python2 |
212 |
- if [[ ! ${force} ]]; then |
213 |
- error=1 |
214 |
- fi |
215 |
- elif [[ ${i} == *python3 ]]; then |
216 |
- from=python3 |
217 |
- else |
218 |
- from=python |
219 |
- fi |
220 |
- break |
221 |
- ;; |
222 |
- *python[23].[0-9]|*python3.[1-9][0-9]|*pypy|*pypy3|*jython[23].[0-9]) |
223 |
- # Explicit mismatch. |
224 |
- if [[ ! ${force} ]]; then |
225 |
- error=1 |
226 |
- else |
227 |
- case "${i}" in |
228 |
- *python[23].[0-9]) |
229 |
- from="python[23].[0-9]";; |
230 |
- *python3.[1-9][0-9]) |
231 |
- from="python3.[1-9][0-9]";; |
232 |
- *pypy) |
233 |
- from="pypy";; |
234 |
- *pypy3) |
235 |
- from="pypy3";; |
236 |
- *jython[23].[0-9]) |
237 |
- from="jython[23].[0-9]";; |
238 |
- *) |
239 |
- die "${FUNCNAME}: internal error in 2nd pattern match";; |
240 |
- esac |
241 |
- fi |
242 |
- break |
243 |
- ;; |
244 |
- esac |
245 |
- done |
246 |
+ read -r -a split_shebang <<<${shebang#"#!"} || die |
247 |
+ |
248 |
+ local in_path=${split_shebang[0]} |
249 |
+ local from='^#! *[^ ]*' |
250 |
+ # if the first component is env(1), skip it |
251 |
+ if [[ ${in_path} == */env ]]; then |
252 |
+ in_path=${split_shebang[1]} |
253 |
+ from+=' *[^ ]*' |
254 |
+ fi |
255 |
+ |
256 |
+ case ${in_path##*/} in |
257 |
+ "${EPYTHON}") |
258 |
+ match=1 |
259 |
+ ;; |
260 |
+ python|python[23]) |
261 |
+ match=1 |
262 |
+ [[ ${in_path##*/} == python2 ]] && error=1 |
263 |
+ ;; |
264 |
+ python[23].[0-9]|python3.[1-9][0-9]|pypy|pypy3|jython[23].[0-9]) |
265 |
+ # Explicit mismatch. |
266 |
+ match=1 |
267 |
+ error=1 |
268 |
+ ;; |
269 |
+ esac |
270 |
fi |
271 |
|
272 |
- if [[ ! ${error} && ! ${from} ]]; then |
273 |
+ # disregard mismatches in force mode |
274 |
+ [[ ${force} ]] && error= |
275 |
+ |
276 |
+ if [[ ! ${match} ]]; then |
277 |
# Non-Python shebang. Allowed in recursive mode, |
278 |
# disallowed when specifying file explicitly. |
279 |
[[ ${is_recursive} ]] && continue |
280 |
@@ -1147,13 +1124,9 @@ python_fix_shebang() { |
281 |
fi |
282 |
|
283 |
if [[ ! ${error} ]]; then |
284 |
- # We either want to match ${from} followed by space |
285 |
- # or at end-of-string. |
286 |
- if [[ ${shebang} == *${from}" "* ]]; then |
287 |
- sed -i -e "1s:${from} :${EPYTHON} :" "${f}" || die |
288 |
- else |
289 |
- sed -i -e "1s:${from}$:${EPYTHON}:" "${f}" || die |
290 |
- fi |
291 |
+ debug-print "${FUNCNAME}: in file ${f#${D%/}}" |
292 |
+ debug-print "${FUNCNAME}: rewriting shebang: ${shebang}" |
293 |
+ sed -i -e "1s@${from}@#!${PYTHON}@" "${f}" || die |
294 |
any_fixed=1 |
295 |
else |
296 |
eerror "The file has incompatible shebang:" |
297 |
@@ -1166,12 +1139,7 @@ python_fix_shebang() { |
298 |
|
299 |
if [[ ! ${any_fixed} ]]; then |
300 |
eerror "QA error: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files." |
301 |
- if [[ ${any_correct} ]]; then |
302 |
- eerror "All files have ${EPYTHON} shebang already." |
303 |
- else |
304 |
- eerror "There are no Python files in specified directory." |
305 |
- fi |
306 |
- |
307 |
+ eerror "There are no Python files in specified directory." |
308 |
die "${FUNCNAME} did not match any fixable files" |
309 |
fi |
310 |
done |
311 |
@@ -1348,6 +1316,9 @@ epytest() { |
312 |
-Wdefault |
313 |
# override color output |
314 |
"--color=${color}" |
315 |
+ # count is more precise when we're dealing with a large number |
316 |
+ # of tests |
317 |
+ -o console_output_style=count |
318 |
# disable the undesirable-dependency plugins by default to |
319 |
# trigger missing argument strips. strip options that require |
320 |
# them from config files. enable them explicitly via "-p ..." |
321 |
@@ -1425,5 +1396,47 @@ _python_run_check_deps() { |
322 |
eend ${?} |
323 |
} |
324 |
|
325 |
+# @FUNCTION: python_has_version |
326 |
+# @USAGE: [-b|-d|-r] <atom>... |
327 |
+# @DESCRIPTION: |
328 |
+# A convenience wrapper for has_version() with verbose output and better |
329 |
+# defaults for use in python_check_deps(). |
330 |
+# |
331 |
+# The wrapper accepts EAPI 7+-style -b/-d/-r options to indicate |
332 |
+# the root to perform the lookup on. Unlike has_version, the default |
333 |
+# is -b. In EAPI 6, -b and -d are translated to --host-root |
334 |
+# for compatibility. |
335 |
+# |
336 |
+# The wrapper accepts multiple package specifications. For the check |
337 |
+# to succeed, *all* specified atoms must match. |
338 |
+python_has_version() { |
339 |
+ debug-print-function ${FUNCNAME} "${@}" |
340 |
+ |
341 |
+ local root_arg=( -b ) |
342 |
+ case ${1} in |
343 |
+ -b|-d|-r) |
344 |
+ root_arg=( "${1}" ) |
345 |
+ shift |
346 |
+ ;; |
347 |
+ esac |
348 |
+ |
349 |
+ if [[ ${EAPI} == 6 ]]; then |
350 |
+ if [[ ${root_arg} == -r ]]; then |
351 |
+ root_arg=() |
352 |
+ else |
353 |
+ root_arg=( --host-root ) |
354 |
+ fi |
355 |
+ fi |
356 |
+ |
357 |
+ local pkg |
358 |
+ for pkg; do |
359 |
+ ebegin " ${pkg}" |
360 |
+ has_version "${root_arg[@]}" "${pkg}" |
361 |
+ eend ${?} || return |
362 |
+ done |
363 |
+ |
364 |
+ return 0 |
365 |
+} |
366 |
+ |
367 |
_PYTHON_UTILS_R1=1 |
368 |
fi |