/[gentoo-x86]/eclass/python.eclass
Gentoo

Contents of /eclass/python.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.101 - (show annotations) (download)
Sat Jul 17 23:02:14 2010 UTC (3 years, 9 months ago) by arfrever
Branch: MAIN
Changes since 1.100: +350 -211 lines
Deprecate NEED_PYTHON variable.
Require python_pkg_setup() in EAPI >=4.
Ensure that sanity checks in python_pkg_setup() and python_set_active_version() are performed for binary packages.
Improve handling of arguments in some functions.
Support flags specific to given Python ABIs.
Improve sanity checks in some functions.
Improve error messages in some functions.
Support --base-path option in python_get_includedir(), python_get_libdir(), python_get_sitedir() and python_get_library().
Allow multiple paths in argument of --PYTHONPATH option of python_execute_nosetests(), python_execute_py.test() and python_execute_trial().
Simplify python_mod_optimize() and python_mod_cleanup() in EAPI >=4.
Clean unneeded code in python_version(), python_mod_exists() and python_tkinter_exists().

1 # Copyright 1999-2010 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.100 2010/05/29 16:39:13 arfrever Exp $
4
5 # @ECLASS: python.eclass
6 # @MAINTAINER:
7 # Gentoo Python Project <python@gentoo.org>
8 # @BLURB: Eclass for Python packages
9 # @DESCRIPTION:
10 # The python eclass contains miscellaneous, useful functions for Python packages.
11
12 inherit multilib
13
14 if ! has "${EAPI:-0}" 0 1 2 3; then
15 die "API of python.eclass in EAPI=\"${EAPI}\" not established"
16 fi
17
18 _CPYTHON2_SUPPORTED_ABIS=(2.4 2.5 2.6 2.7)
19 _CPYTHON3_SUPPORTED_ABIS=(3.0 3.1 3.2)
20 _JYTHON_SUPPORTED_ABIS=(2.5-jython)
21
22 # @ECLASS-VARIABLE: PYTHON_DEPEND
23 # @DESCRIPTION:
24 # Specification of dependency on dev-lang/python.
25 # Syntax:
26 # PYTHON_DEPEND: [[!]USE_flag? ]<version_components_group>[ version_components_group]
27 # version_components_group: <major_version[:[minimal_version][:maximal_version]]>
28 # major_version: <2|3|*>
29 # minimal_version: <minimal_major_version.minimal_minor_version>
30 # maximal_version: <maximal_major_version.maximal_minor_version>
31
32 _parse_PYTHON_DEPEND() {
33 local major_version maximal_version minimal_version python_all="0" python_maximal_version python_minimal_version python_versions=() python2="0" python2_maximal_version python2_minimal_version python3="0" python3_maximal_version python3_minimal_version USE_flag= version_components_group version_components_group_regex version_components_groups
34
35 version_components_group_regex="(2|3|\*)(:([[:digit:]]+\.[[:digit:]]+)?(:([[:digit:]]+\.[[:digit:]]+)?)?)?"
36 version_components_groups="${PYTHON_DEPEND}"
37
38 if [[ "${version_components_groups}" =~ ^((\!)?[[:alnum:]_-]+\?\ )?${version_components_group_regex}(\ ${version_components_group_regex})?$ ]]; then
39 if [[ "${version_components_groups}" =~ ^(\!)?[[:alnum:]_-]+\? ]]; then
40 USE_flag="${version_components_groups%\? *}"
41 version_components_groups="${version_components_groups#* }"
42 fi
43 if [[ "${version_components_groups}" =~ ("*".*" "|" *"|^2.*\ (2|\*)|^3.*\ (3|\*)) ]]; then
44 die "Invalid syntax of PYTHON_DEPEND: Incorrectly specified groups of versions"
45 fi
46
47 version_components_groups="${version_components_groups// /$'\n'}"
48 while read version_components_group; do
49 major_version="${version_components_group:0:1}"
50 minimal_version="${version_components_group:2}"
51 minimal_version="${minimal_version%:*}"
52 maximal_version="${version_components_group:$((3 + ${#minimal_version}))}"
53
54 if [[ "${major_version}" =~ ^(2|3)$ ]]; then
55 if [[ -n "${minimal_version}" && "${major_version}" != "${minimal_version:0:1}" ]]; then
56 die "Invalid syntax of PYTHON_DEPEND: Minimal version '${minimal_version}' not in specified group of versions"
57 fi
58 if [[ -n "${maximal_version}" && "${major_version}" != "${maximal_version:0:1}" ]]; then
59 die "Invalid syntax of PYTHON_DEPEND: Maximal version '${maximal_version}' not in specified group of versions"
60 fi
61 fi
62
63 if [[ "${major_version}" == "2" ]]; then
64 python2="1"
65 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}")
66 python2_minimal_version="${minimal_version}"
67 python2_maximal_version="${maximal_version}"
68 elif [[ "${major_version}" == "3" ]]; then
69 python3="1"
70 python_versions=("${_CPYTHON3_SUPPORTED_ABIS[@]}")
71 python3_minimal_version="${minimal_version}"
72 python3_maximal_version="${maximal_version}"
73 else
74 python_all="1"
75 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}")
76 python_minimal_version="${minimal_version}"
77 python_maximal_version="${maximal_version}"
78 fi
79
80 if [[ -n "${minimal_version}" ]] && ! has "${minimal_version}" "${python_versions[@]}"; then
81 die "Invalid syntax of PYTHON_DEPEND: Unrecognized minimal version '${minimal_version}'"
82 fi
83 if [[ -n "${maximal_version}" ]] && ! has "${maximal_version}" "${python_versions[@]}"; then
84 die "Invalid syntax of PYTHON_DEPEND: Unrecognized maximal version '${maximal_version}'"
85 fi
86
87 if [[ -n "${minimal_version}" && -n "${maximal_version}" && "${minimal_version}" > "${maximal_version}" ]]; then
88 die "Invalid syntax of PYTHON_DEPEND: Minimal version '${minimal_version}' greater than maximal version '${maximal_version}'"
89 fi
90 done <<< "${version_components_groups}"
91
92 _PYTHON_ATOMS=()
93
94 _append_accepted_versions_range() {
95 local accepted_version="0" i
96 for ((i = "${#python_versions[@]}"; i >= 0; i--)); do
97 if [[ "${python_versions[${i}]}" == "${python_maximal_version}" ]]; then
98 accepted_version="1"
99 fi
100 if [[ "${accepted_version}" == "1" ]]; then
101 _PYTHON_ATOMS+=("=dev-lang/python-${python_versions[${i}]}*")
102 fi
103 if [[ "${python_versions[${i}]}" == "${python_minimal_version}" ]]; then
104 accepted_version="0"
105 fi
106 done
107 }
108
109 if [[ "${python_all}" == "1" ]]; then
110 if [[ -z "${python_minimal_version}" && -z "${python_maximal_version}" ]]; then
111 _PYTHON_ATOMS+=("dev-lang/python")
112 else
113 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}")
114 python_minimal_version="${python_minimal_version:-${python_versions[0]}}"
115 python_maximal_version="${python_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
116 _append_accepted_versions_range
117 fi
118 else
119 if [[ "${python3}" == "1" ]]; then
120 if [[ -z "${python3_minimal_version}" && -z "${python3_maximal_version}" ]]; then
121 _PYTHON_ATOMS+=("=dev-lang/python-3*")
122 else
123 python_versions=("${_CPYTHON3_SUPPORTED_ABIS[@]}")
124 python_minimal_version="${python3_minimal_version:-${python_versions[0]}}"
125 python_maximal_version="${python3_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
126 _append_accepted_versions_range
127 fi
128 fi
129 if [[ "${python2}" == "1" ]]; then
130 if [[ -z "${python2_minimal_version}" && -z "${python2_maximal_version}" ]]; then
131 _PYTHON_ATOMS+=("=dev-lang/python-2*")
132 else
133 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}")
134 python_minimal_version="${python2_minimal_version:-${python_versions[0]}}"
135 python_maximal_version="${python2_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
136 _append_accepted_versions_range
137 fi
138 fi
139 fi
140
141 unset -f _append_accepted_versions_range
142
143 if [[ "${#_PYTHON_ATOMS[@]}" -gt 1 ]]; then
144 DEPEND+="${DEPEND:+ }${USE_flag}${USE_flag:+? ( }|| ( ${_PYTHON_ATOMS[@]} )${USE_flag:+ )}"
145 RDEPEND+="${RDEPEND:+ }${USE_flag}${USE_flag:+? ( }|| ( ${_PYTHON_ATOMS[@]} )${USE_flag:+ )}"
146 else
147 DEPEND+="${DEPEND:+ }${USE_flag}${USE_flag:+? ( }${_PYTHON_ATOMS[@]}${USE_flag:+ )}"
148 RDEPEND+="${RDEPEND:+ }${USE_flag}${USE_flag:+? ( }${_PYTHON_ATOMS[@]}${USE_flag:+ )}"
149 fi
150 else
151 die "Invalid syntax of PYTHON_DEPEND"
152 fi
153 }
154
155 DEPEND=">=app-admin/eselect-python-20091230"
156 RDEPEND="${DEPEND}"
157
158 if [[ -n "${PYTHON_DEPEND}" && -n "${NEED_PYTHON}" ]]; then
159 die "PYTHON_DEPEND and NEED_PYTHON cannot be set simultaneously"
160 elif [[ -n "${PYTHON_DEPEND}" ]]; then
161 _parse_PYTHON_DEPEND
162 elif [[ -n "${NEED_PYTHON}" ]]; then
163 if ! has "${EAPI:-0}" 0 1 2; then
164 eerror "Use PYTHON_DEPEND variable instead of NEED_PYTHON variable."
165 die "NEED_PYTHON variable cannot be used in this EAPI"
166 fi
167
168 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
169 _RED=$'\e[1;31m'
170 _NORMAL=$'\e[0m'
171 else
172 _RED=
173 _NORMAL=
174 fi
175
176 echo
177 echo " ${_RED}*${_NORMAL} ${_RED}Deprecation Warning: NEED_PYTHON variable is deprecated and will be banned on 2010-10-01.${_NORMAL}"
178 echo " ${_RED}*${_NORMAL} ${_RED}Use PYTHON_DEPEND variable instead of NEED_PYTHON variable.${_NORMAL}"
179 echo " ${_RED}*${_NORMAL} ${_RED}The ebuild needs to be fixed. Please report a bug, if it has not been already reported.${_NORMAL}"
180 echo
181
182 unset _BOLD _NORMAL
183
184 _PYTHON_ATOMS=(">=dev-lang/python-${NEED_PYTHON}")
185 DEPEND+="${DEPEND:+ }${_PYTHON_ATOMS[@]}"
186 RDEPEND+="${RDEPEND:+ }${_PYTHON_ATOMS[@]}"
187 else
188 _PYTHON_ATOMS=("dev-lang/python")
189 fi
190
191 # @ECLASS-VARIABLE: PYTHON_USE_WITH
192 # @DESCRIPTION:
193 # Set this to a space separated list of USE flags the Python slot in use must be built with.
194
195 # @ECLASS-VARIABLE: PYTHON_USE_WITH_OR
196 # @DESCRIPTION:
197 # Set this to a space separated list of USE flags of which one must be turned on for the slot in use.
198
199 # @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
200 # @DESCRIPTION:
201 # Set this to a name of a USE flag if you need to make either PYTHON_USE_WITH or
202 # PYTHON_USE_WITH_OR atoms conditional under a USE flag.
203
204 if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
205 _PYTHON_USE_WITH_ATOMS_ARRAY=()
206 if [[ -n "${PYTHON_USE_WITH}" ]]; then
207 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do
208 _PYTHON_USE_WITH_ATOMS_ARRAY+=("${_PYTHON_ATOM}[${PYTHON_USE_WITH// /,}]")
209 done
210 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
211 for _USE_flag in ${PYTHON_USE_WITH_OR}; do
212 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do
213 _PYTHON_USE_WITH_ATOMS_ARRAY+=("${_PYTHON_ATOM}[${_USE_flag}]")
214 done
215 done
216 unset _USE_flag
217 fi
218 if [[ "${#_PYTHON_USE_WITH_ATOMS_ARRAY[@]}" -gt 1 ]]; then
219 _PYTHON_USE_WITH_ATOMS="|| ( ${_PYTHON_USE_WITH_ATOMS_ARRAY[@]} )"
220 else
221 _PYTHON_USE_WITH_ATOMS="${_PYTHON_USE_WITH_ATOMS_ARRAY[@]}"
222 fi
223 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
224 _PYTHON_USE_WITH_ATOMS="${PYTHON_USE_WITH_OPT}? ( ${_PYTHON_USE_WITH_ATOMS} )"
225 fi
226 DEPEND+=" ${_PYTHON_USE_WITH_ATOMS}"
227 RDEPEND+=" ${_PYTHON_USE_WITH_ATOMS}"
228 unset _PYTHON_ATOM _PYTHON_USE_WITH_ATOMS _PYTHON_USE_WITH_ATOMS_ARRAY
229 fi
230
231 unset _PYTHON_ATOMS
232
233 # ================================================================================================
234 # =================================== MISCELLANEOUS FUNCTIONS ====================================
235 # ================================================================================================
236
237 _python_implementation() {
238 if [[ "${CATEGORY}/${PN}" == "dev-lang/python" ]]; then
239 return 0
240 elif [[ "${CATEGORY}/${PN}" == "dev-java/jython" ]]; then
241 return 0
242 else
243 return 1
244 fi
245 }
246
247 _python_package_supporting_installation_for_multiple_python_abis() {
248 if [[ "${EBUILD_PHASE}" == "depend" ]]; then
249 die "${FUNCNAME}() cannot be used in global scope"
250 fi
251
252 if has "${EAPI:-0}" 0 1 2 3 4; then
253 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
254 return 0
255 else
256 return 1
257 fi
258 else
259 die "${FUNCNAME}(): Support for EAPI=\"${EAPI}\" not implemented"
260 fi
261 }
262
263 _python_abi-specific_local_scope() {
264 [[ " ${FUNCNAME[@]:2} " =~ " "(_python_final_sanity_checks|python_execute_function|python_mod_optimize|python_mod_cleanup)" " ]]
265 }
266
267 _python_initialize_prefix_variables() {
268 if has "${EAPI:-0}" 0 1 2; then
269 if [[ -n "${ROOT}" && -z "${EROOT}" ]]; then
270 EROOT="${ROOT%/}${EPREFIX}/"
271 fi
272 if [[ -n "${D}" && -z "${ED}" ]]; then
273 ED="${D%/}${EPREFIX}/"
274 fi
275 fi
276 }
277
278 unset PYTHON_SANITY_CHECKS_EXECUTED PYTHON_SKIP_SANITY_CHECKS
279
280 _python_initial_sanity_checks() {
281 if [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then
282 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
283 if [[ "$(readlink "${EPREFIX}/usr/bin/python")" != "python-wrapper" ]]; then
284 eerror "'${EPREFIX}/usr/bin/python' is not valid symlink."
285 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
286 die "'${EPREFIX}/usr/bin/python' is not valid symlink"
287 fi
288 if [[ "$(<"${EPREFIX}/usr/bin/python-config")" != *"Gentoo python-config wrapper script"* ]]; then
289 eerror "'${EPREFIX}/usr/bin/python-config' is not valid script"
290 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
291 die "'${EPREFIX}/usr/bin/python-config' is not valid script"
292 fi
293 fi
294 }
295
296 _python_final_sanity_checks() {
297 if ! _python_implementation && [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then
298 local PYTHON_ABI="${PYTHON_ABI}"
299 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI}}; do
300 # Ensure that appropriate version of Python is installed.
301 if ! has_version "$(python_get_implementational_package)"; then
302 die "$(python_get_implementational_package) is not installed"
303 fi
304
305 # Ensure that EPYTHON variable is respected.
306 if [[ "$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")" != "${PYTHON_ABI}" ]]; then
307 eerror "Path to 'python': '$(type -p python)'"
308 eerror "ABI: '${ABI}'"
309 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'"
310 eerror "EPYTHON: '$(PYTHON)'"
311 eerror "PYTHON_ABI: '${PYTHON_ABI}'"
312 eerror "Locally active version of Python: '$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")'"
313 die "'python' does not respect EPYTHON variable"
314 fi
315 done
316 fi
317 PYTHON_SANITY_CHECKS_EXECUTED="1"
318 }
319
320 _python_set_color_variables() {
321 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
322 _BOLD=$'\e[1m'
323 _RED=$'\e[1;31m'
324 _GREEN=$'\e[1;32m'
325 _BLUE=$'\e[1;34m'
326 _CYAN=$'\e[1;36m'
327 _NORMAL=$'\e[0m'
328 else
329 _BOLD=
330 _RED=
331 _GREEN=
332 _BLUE=
333 _CYAN=
334 _NORMAL=
335 fi
336 }
337
338 unset PYTHON_PKG_SETUP_EXECUTED
339
340 _python_check_python_pkg_setup_execution() {
341 [[ " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " ]] && return
342
343 if ! has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_PKG_SETUP_EXECUTED}" ]]; then
344 die "python_pkg_setup() not called"
345 fi
346 }
347
348 # @FUNCTION: python_pkg_setup
349 # @DESCRIPTION:
350 # Perform sanity checks and initialize environment.
351 #
352 # This function is exported in EAPI 2 and 3 when PYTHON_USE_WITH or PYTHON_USE_WITH_OR variable
353 # is set and always in EAPI >=4. Calling of this function is mandatory in EAPI >=4.
354 #
355 # This function can be used only in pkg_setup() phase.
356 python_pkg_setup() {
357 # Check if phase is pkg_setup().
358 [[ "${EBUILD_PHASE}" != "setup" ]] && die "${FUNCNAME}() can be used only in pkg_setup() phase"
359
360 if [[ "$#" -ne 0 ]]; then
361 die "${FUNCNAME}() does not accept arguments"
362 fi
363
364 if _python_package_supporting_installation_for_multiple_python_abis; then
365 _python_calculate_PYTHON_ABIS
366 export EPYTHON="$(PYTHON -f)"
367 else
368 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
369 fi
370
371 if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; then
372 if [[ "${PYTHON_USE_WITH_OPT}" ]]; then
373 if [[ "${PYTHON_USE_WITH_OPT}" == !* ]]; then
374 use ${PYTHON_USE_WITH_OPT#!} && return
375 else
376 use !${PYTHON_USE_WITH_OPT} && return
377 fi
378 fi
379
380 python_pkg_setup_check_USE_flags() {
381 local python_atom USE_flag
382 python_atom="$(python_get_implementational_package)"
383
384 for USE_flag in ${PYTHON_USE_WITH}; do
385 if ! has_version "${python_atom}[${USE_flag}]"; then
386 eerror "Please rebuild ${python_atom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
387 die "Please rebuild ${python_atom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
388 fi
389 done
390
391 for USE_flag in ${PYTHON_USE_WITH_OR}; do
392 if has_version "${python_atom}[${USE_flag}]"; then
393 return
394 fi
395 done
396
397 if [[ ${PYTHON_USE_WITH_OR} ]]; then
398 eerror "Please rebuild ${python_atom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
399 die "Please rebuild ${python_atom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
400 fi
401 }
402
403 if _python_package_supporting_installation_for_multiple_python_abis; then
404 PYTHON_SKIP_SANITY_CHECKS="1" python_execute_function -q python_pkg_setup_check_USE_flags
405 else
406 python_pkg_setup_check_USE_flags
407 fi
408
409 unset -f python_pkg_setup_check_USE_flags
410 fi
411
412 PYTHON_PKG_SETUP_EXECUTED="1"
413 }
414
415 if ! has "${EAPI:-0}" 0 1 2 3 || has "${EAPI:-0}" 2 3 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; then
416 EXPORT_FUNCTIONS pkg_setup
417 fi
418
419 # @FUNCTION: python_convert_shebangs
420 # @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories]
421 # @DESCRIPTION:
422 # Convert shebangs in specified files. Directories can be specified only with --recursive option.
423 python_convert_shebangs() {
424 _python_check_python_pkg_setup_execution
425
426 local argument file files=() only_executables="0" python_version quiet="0" recursive="0"
427
428 while (($#)); do
429 case "$1" in
430 -r|--recursive)
431 recursive="1"
432 ;;
433 -q|--quiet)
434 quiet="1"
435 ;;
436 -x|--only-executables)
437 only_executables="1"
438 ;;
439 --)
440 shift
441 break
442 ;;
443 -*)
444 die "${FUNCNAME}(): Unrecognized option '$1'"
445 ;;
446 *)
447 break
448 ;;
449 esac
450 shift
451 done
452
453 if [[ "$#" -eq 0 ]]; then
454 die "${FUNCNAME}(): Missing Python version and files or directories"
455 elif [[ "$#" -eq 1 ]]; then
456 die "${FUNCNAME}(): Missing files or directories"
457 fi
458
459 python_version="$1"
460 shift
461
462 for argument in "$@"; do
463 if [[ ! -e "${argument}" ]]; then
464 die "${FUNCNAME}(): '${argument}' does not exist"
465 elif [[ -f "${argument}" ]]; then
466 files+=("${argument}")
467 elif [[ -d "${argument}" ]]; then
468 if [[ "${recursive}" == "1" ]]; then
469 while read -d $'\0' -r file; do
470 files+=("${file}")
471 done < <(find "${argument}" $([[ "${only_executables}" == "1" ]] && echo -perm /111) -type f -print0)
472 else
473 die "${FUNCNAME}(): '${argument}' is not a regular file"
474 fi
475 else
476 die "${FUNCNAME}(): '${argument}' is not a regular file or a directory"
477 fi
478 done
479
480 for file in "${files[@]}"; do
481 file="${file#./}"
482 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
483
484 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then
485 [[ "$(sed -ne "2p" "${file}")" =~ ^"# Gentoo '".*"' wrapper script generated by python_generate_wrapper_scripts()"$ ]] && continue
486
487 if [[ "${quiet}" == "0" ]]; then
488 einfo "Converting shebang in '${file}'"
489 fi
490
491 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
492
493 # Delete potential whitespace after "#!".
494 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed"
495 fi
496 done
497 }
498
499 # @FUNCTION: python_clean_installation_image
500 # @USAGE: [-q|--quiet]
501 # @DESCRIPTION:
502 # Delete needless files in installation image.
503 python_clean_installation_image() {
504 _python_check_python_pkg_setup_execution
505 _python_initialize_prefix_variables
506
507 local file files=() quiet="0"
508
509 # Check if phase is src_install().
510 [[ "${EBUILD_PHASE}" != "install" ]] && die "${FUNCNAME}() can be used only in src_install() phase"
511
512 while (($#)); do
513 case "$1" in
514 -q|--quiet)
515 quiet="1"
516 ;;
517 -*)
518 die "${FUNCNAME}(): Unrecognized option '$1'"
519 ;;
520 *)
521 die "${FUNCNAME}(): Invalid usage"
522 ;;
523 esac
524 shift
525 done
526
527 while read -d $'\0' -r file; do
528 files+=("${file}")
529 done < <(find "${ED}" "(" -name "*.py[co]" -o -name "*\$py.class" ")" -type f -print0)
530
531 if [[ "${#files[@]}" -gt 0 ]]; then
532 if [[ "${quiet}" == "0" ]]; then
533 ewarn "Deleting byte-compiled Python modules needlessly generated by build system:"
534 fi
535 for file in "${files[@]}"; do
536 if [[ "${quiet}" == "0" ]]; then
537 ewarn " ${file}"
538 fi
539 rm -f "${file}"
540
541 # Delete empty __pycache__ directories.
542 if [[ "${file%/*}" == *"/__pycache__" ]]; then
543 rmdir "${file%/*}" 2> /dev/null
544 fi
545 done
546 fi
547
548 python_clean_sitedirs() {
549 if [[ -d "${ED}$(python_get_sitedir)" ]]; then
550 find "${ED}$(python_get_sitedir)" "(" -name "*.c" -o -name "*.h" -o -name "*.la" ")" -type f -print0 | xargs -0 rm -f
551 fi
552 }
553 if _python_package_supporting_installation_for_multiple_python_abis; then
554 python_execute_function -q python_clean_sitedirs
555 else
556 python_clean_sitedirs
557 fi
558
559 unset -f python_clean_sitedirs
560 }
561
562 # ================================================================================================
563 # =========== FUNCTIONS FOR PACKAGES SUPPORTING INSTALLATION FOR MULTIPLE PYTHON ABIS ============
564 # ================================================================================================
565
566 # @ECLASS-VARIABLE: SUPPORT_PYTHON_ABIS
567 # @DESCRIPTION:
568 # Set this in EAPI <= 4 to indicate that current package supports installation for
569 # multiple Python ABIs.
570
571 # @ECLASS-VARIABLE: PYTHON_EXPORT_PHASE_FUNCTIONS
572 # @DESCRIPTION:
573 # Set this to export phase functions for the following ebuild phases:
574 # src_prepare, src_configure, src_compile, src_test, src_install.
575 if ! has "${EAPI:-0}" 0 1; then
576 python_src_prepare() {
577 _python_check_python_pkg_setup_execution
578
579 if ! _python_package_supporting_installation_for_multiple_python_abis; then
580 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
581 fi
582
583 if [[ "$#" -ne 0 ]]; then
584 die "${FUNCNAME}() does not accept arguments"
585 fi
586
587 python_copy_sources
588 }
589
590 for python_default_function in src_configure src_compile src_test src_install; do
591 eval "python_${python_default_function}() {
592 _python_check_python_pkg_setup_execution
593
594 if ! _python_package_supporting_installation_for_multiple_python_abis; then
595 die \"\${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs\"
596 fi
597
598 python_execute_function -d -s -- \"\$@\"
599 }"
600 done
601 unset python_default_function
602
603 if [[ -n "${PYTHON_EXPORT_PHASE_FUNCTIONS}" ]]; then
604 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
605 fi
606 fi
607
608 unset PYTHON_ABIS
609
610 _python_calculate_PYTHON_ABIS() {
611 if ! _python_package_supporting_installation_for_multiple_python_abis; then
612 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
613 fi
614
615 _python_initial_sanity_checks
616
617 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 5.
618 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3 4; then
619 local PYTHON_ABI restricted_ABI support_ABI supported_PYTHON_ABIS=
620 PYTHON_ABI_SUPPORTED_VALUES="${_CPYTHON2_SUPPORTED_ABIS[@]} ${_CPYTHON3_SUPPORTED_ABIS[@]} ${_JYTHON_SUPPORTED_ABIS[@]}"
621
622 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
623 local cpython_enabled="0"
624
625 if [[ -z "${USE_PYTHON}" ]]; then
626 die "USE_PYTHON variable is empty"
627 fi
628
629 for PYTHON_ABI in ${USE_PYTHON}; do
630 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
631 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
632 fi
633
634 if has "${PYTHON_ABI}" "${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}"; then
635 cpython_enabled="1"
636 fi
637
638 support_ABI="1"
639 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
640 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
641 support_ABI="0"
642 break
643 fi
644 done
645 [[ "${support_ABI}" == "1" ]] && export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
646 done
647
648 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
649 die "USE_PYTHON variable does not enable any Python ABI supported by ${CATEGORY}/${PF}"
650 fi
651
652 if [[ "${cpython_enabled}" == "0" ]]; then
653 die "USE_PYTHON variable does not enable any CPython ABI"
654 fi
655 else
656 local python_version python2_version= python3_version= support_python_major_version
657
658 if ! has_version "dev-lang/python"; then
659 die "${FUNCNAME}(): 'dev-lang/python' is not installed"
660 fi
661
662 python_version="$("${EPREFIX}/usr/bin/python" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
663
664 if has_version "=dev-lang/python-2*"; then
665 if [[ "$(readlink "${EPREFIX}/usr/bin/python2")" != "python2."* ]]; then
666 die "'${EPREFIX}/usr/bin/python2' is not valid symlink"
667 fi
668
669 python2_version="$("${EPREFIX}/usr/bin/python2" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
670
671 for PYTHON_ABI in "${_CPYTHON2_SUPPORTED_ABIS[@]}"; do
672 support_python_major_version="1"
673 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
674 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
675 support_python_major_version="0"
676 fi
677 done
678 [[ "${support_python_major_version}" == "1" ]] && break
679 done
680 if [[ "${support_python_major_version}" == "1" ]]; then
681 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
682 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
683 die "Active version of Python 2 is not supported by ${CATEGORY}/${PF}"
684 fi
685 done
686 else
687 python2_version=""
688 fi
689 fi
690
691 if has_version "=dev-lang/python-3*"; then
692 if [[ "$(readlink "${EPREFIX}/usr/bin/python3")" != "python3."* ]]; then
693 die "'${EPREFIX}/usr/bin/python3' is not valid symlink"
694 fi
695
696 python3_version="$("${EPREFIX}/usr/bin/python3" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
697
698 for PYTHON_ABI in "${_CPYTHON3_SUPPORTED_ABIS[@]}"; do
699 support_python_major_version="1"
700 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
701 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
702 support_python_major_version="0"
703 fi
704 done
705 [[ "${support_python_major_version}" == "1" ]] && break
706 done
707 if [[ "${support_python_major_version}" == "1" ]]; then
708 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
709 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
710 die "Active version of Python 3 is not supported by ${CATEGORY}/${PF}"
711 fi
712 done
713 else
714 python3_version=""
715 fi
716 fi
717
718 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
719 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python2' symlink"
720 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
721 die "Incorrect configuration of Python"
722 fi
723 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
724 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python3' symlink"
725 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
726 die "Incorrect configuration of Python"
727 fi
728
729 PYTHON_ABIS="${python2_version} ${python3_version}"
730 PYTHON_ABIS="${PYTHON_ABIS# }"
731 export PYTHON_ABIS="${PYTHON_ABIS% }"
732 fi
733 fi
734
735 _python_final_sanity_checks
736 }
737
738 _python_prepare_flags() {
739 local array=() deleted_flag element flags new_value old_flag old_value operator pattern prefix variable
740
741 for variable in CPPFLAGS CFLAGS CXXFLAGS LDFLAGS; do
742 eval "_PYTHON_SAVED_${variable}=\"\${!variable}\""
743 for prefix in PYTHON_USER_ PYTHON_; do
744 if [[ "$(declare -p ${prefix}${variable} 2> /dev/null)" == "declare -a ${prefix}${variable}="* ]]; then
745 eval "array=(\"\${${prefix}${variable}[@]}\")"
746 for element in "${array[@]}"; do
747 if [[ "${element}" =~ ^([[:alnum:]]|\.|-|\*|\[|\])+\ (\+|-)\ .+ ]]; then
748 pattern="${element%% *}"
749 element="${element#* }"
750 operator="${element%% *}"
751 flags="${element#* }"
752 if [[ "${PYTHON_ABI}" == ${pattern} ]]; then
753 if [[ "${operator}" == "+" ]]; then
754 eval "export ${variable}+=\"\${variable:+ }${flags}\""
755 elif [[ "${operator}" == "-" ]]; then
756 flags="${flags// /$'\n'}"
757 old_value="${!variable// /$'\n'}"
758 new_value=""
759 while read old_flag; do
760 while read deleted_flag; do
761 if [[ "${old_flag}" == ${deleted_flag} ]]; then
762 continue 2
763 fi
764 done <<< "${flags}"
765 new_value+="${new_value:+ }${old_flag}"
766 done <<< "${old_value}"
767 eval "export ${variable}=\"\${new_value}\""
768 fi
769 fi
770 else
771 die "Element '${element}' of ${prefix}${variable} array has invalid syntax"
772 fi
773 done
774 elif [[ -n "$(declare -p ${prefix}${variable} 2> /dev/null)" ]]; then
775 die "${prefix}${variable} should be indexed array"
776 fi
777 done
778 done
779 }
780
781 _python_restore_flags() {
782 local variable
783
784 for variable in CPPFLAGS CFLAGS CXXFLAGS LDFLAGS; do
785 eval "${variable}=\"\${_PYTHON_SAVED_${variable}}\""
786 unset _PYTHON_SAVED_${variable}
787 done
788 }
789
790 # @FUNCTION: python_execute_function
791 # @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [-f|--final-ABI] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
792 # @DESCRIPTION:
793 # Execute specified function for each value of PYTHON_ABIS, optionally passing additional
794 # arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
795 python_execute_function() {
796 _python_check_python_pkg_setup_execution
797
798 if ! _python_package_supporting_installation_for_multiple_python_abis; then
799 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
800 fi
801
802 _python_set_color_variables
803
804 local action action_message action_message_template= default_function="0" failure_message failure_message_template= final_ABI="0" function iterated_PYTHON_ABIS nonfatal="0" previous_directory previous_directory_stack previous_directory_stack_length PYTHON_ABI quiet="0" return_code separate_build_dirs="0" source_dir=
805
806 while (($#)); do
807 case "$1" in
808 --action-message)
809 action_message_template="$2"
810 shift
811 ;;
812 -d|--default-function)
813 default_function="1"
814 ;;
815 --failure-message)
816 failure_message_template="$2"
817 shift
818 ;;
819 -f|--final-ABI)
820 final_ABI="1"
821 ;;
822 --nonfatal)
823 nonfatal="1"
824 ;;
825 -q|--quiet)
826 quiet="1"
827 ;;
828 -s|--separate-build-dirs)
829 separate_build_dirs="1"
830 ;;
831 --source-dir)
832 source_dir="$2"
833 shift
834 ;;
835 --)
836 shift
837 break
838 ;;
839 -*)
840 die "${FUNCNAME}(): Unrecognized option '$1'"
841 ;;
842 *)
843 break
844 ;;
845 esac
846 shift
847 done
848
849 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
850 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
851 fi
852
853 if [[ "${default_function}" == "0" ]]; then
854 if [[ "$#" -eq 0 ]]; then
855 die "${FUNCNAME}(): Missing function name"
856 fi
857 function="$1"
858 shift
859
860 if [[ -z "$(type -t "${function}")" ]]; then
861 die "${FUNCNAME}(): '${function}' function is not defined"
862 fi
863 else
864 if has "${EAPI:-0}" 0 1; then
865 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
866 fi
867
868 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
869 if has "${EAPI}" 2 3; then
870 python_default_function() {
871 econf "$@"
872 }
873 else
874 python_default_function() {
875 nonfatal econf "$@"
876 }
877 fi
878 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
879 python_default_function() {
880 emake "$@"
881 }
882 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
883 python_default_function() {
884 if emake -j1 -n check &> /dev/null; then
885 emake -j1 check "$@"
886 elif emake -j1 -n test &> /dev/null; then
887 emake -j1 test "$@"
888 fi
889 }
890 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
891 python_default_function() {
892 emake DESTDIR="${D}" install "$@"
893 }
894 else
895 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
896 fi
897 function="python_default_function"
898 fi
899
900 # Ensure that python_execute_function() cannot be directly or indirectly called by python_execute_function().
901 if _python_abi-specific_local_scope; then
902 die "${FUNCNAME}(): Invalid call stack"
903 fi
904
905 if [[ "${quiet}" == "0" ]]; then
906 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
907 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
908 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
909 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
910 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
911 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
912 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
913 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
914 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
915 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
916 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
917 fi
918
919 _python_calculate_PYTHON_ABIS
920 if [[ "${final_ABI}" == "1" ]]; then
921 iterated_PYTHON_ABIS="$(PYTHON -f --ABI)"
922 else
923 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
924 fi
925 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
926 _python_prepare_flags
927
928 if [[ "${quiet}" == "0" ]]; then
929 if [[ -n "${action_message_template}" ]]; then
930 action_message="$(eval echo -n "${action_message_template}")"
931 else
932 action_message="${action} of ${CATEGORY}/${PF} with $(python_get_implementation) $(python_get_version)..."
933 fi
934 echo " ${_GREEN}*${_NORMAL} ${_BLUE}${action_message}${_NORMAL}"
935 fi
936
937 if [[ "${separate_build_dirs}" == "1" ]]; then
938 if [[ -n "${source_dir}" ]]; then
939 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
940 else
941 export BUILDDIR="${S}-${PYTHON_ABI}"
942 fi
943 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
944 else
945 export BUILDDIR="${S}"
946 fi
947
948 previous_directory="$(pwd)"
949 previous_directory_stack="$(dirs -p)"
950 previous_directory_stack_length="$(dirs -p | wc -l)"
951
952 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
953 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
954 else
955 EPYTHON="$(PYTHON)" "${function}" "$@"
956 fi
957
958 return_code="$?"
959
960 _python_restore_flags
961
962 if [[ "${return_code}" -ne 0 ]]; then
963 if [[ -n "${failure_message_template}" ]]; then
964 failure_message="$(eval echo -n "${failure_message_template}")"
965 else
966 failure_message="${action} failed with $(python_get_implementation) $(python_get_version) in ${function}() function"
967 fi
968
969 if [[ "${nonfatal}" == "1" ]]; then
970 if [[ "${quiet}" == "0" ]]; then
971 ewarn "${_RED}${failure_message}${_NORMAL}"
972 fi
973 elif [[ "${final_ABI}" == "0" ]] && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
974 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
975 local enabled_PYTHON_ABIS= other_PYTHON_ABI
976 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
977 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
978 done
979 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
980 fi
981 if [[ "${quiet}" == "0" ]]; then
982 ewarn "${_RED}${failure_message}${_NORMAL}"
983 fi
984 if [[ -z "${PYTHON_ABIS}" ]]; then
985 die "${function}() function failed with all enabled Python ABIs"
986 fi
987 else
988 die "${failure_message}"
989 fi
990 fi
991
992 # Ensure that directory stack has not been decreased.
993 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
994 die "Directory stack decreased illegally"
995 fi
996
997 # Avoid side effects of earlier returning from the specified function.
998 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
999 popd > /dev/null || die "popd failed"
1000 done
1001
1002 # Ensure that the bottom part of directory stack has not been changed. Restore
1003 # previous directory (from before running of the specified function) before
1004 # comparison of directory stacks to avoid mismatch of directory stacks after
1005 # potential using of 'cd' to change current directory. Restoration of previous
1006 # directory allows to safely use 'cd' to change current directory in the
1007 # specified function without changing it back to original directory.
1008 cd "${previous_directory}"
1009 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
1010 die "Directory stack changed illegally"
1011 fi
1012
1013 if [[ "${separate_build_dirs}" == "1" ]]; then
1014 popd > /dev/null || die "popd failed"
1015 fi
1016 unset BUILDDIR
1017 done
1018
1019 if [[ "${default_function}" == "1" ]]; then
1020 unset -f python_default_function
1021 fi
1022 }
1023
1024 # @FUNCTION: python_copy_sources
1025 # @USAGE: <directory="${S}"> [directory]
1026 # @DESCRIPTION:
1027 # Copy unpacked sources of current package to separate build directory for each Python ABI.
1028 python_copy_sources() {
1029 _python_check_python_pkg_setup_execution
1030
1031 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1032 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1033 fi
1034
1035 local dir dirs=() PYTHON_ABI
1036
1037 if [[ "$#" -eq 0 ]]; then
1038 if [[ "${WORKDIR}" == "${S}" ]]; then
1039 die "${FUNCNAME}() cannot be used with current value of S variable"
1040 fi
1041 dirs=("${S%/}")
1042 else
1043 dirs=("$@")
1044 fi
1045
1046 _python_calculate_PYTHON_ABIS
1047 for PYTHON_ABI in ${PYTHON_ABIS}; do
1048 for dir in "${dirs[@]}"; do
1049 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
1050 done
1051 done
1052 }
1053
1054 # @FUNCTION: python_generate_wrapper_scripts
1055 # @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
1056 # @DESCRIPTION:
1057 # Generate wrapper scripts. Existing files are overwritten only with --force option.
1058 # If --respect-EPYTHON option is specified, then generated wrapper scripts will
1059 # respect EPYTHON variable at run time.
1060 python_generate_wrapper_scripts() {
1061 _python_check_python_pkg_setup_execution
1062
1063 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1064 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1065 fi
1066
1067 _python_initialize_prefix_variables
1068
1069 local eselect_python_option file force="0" quiet="0" PYTHON_ABI python2_enabled="0" python3_enabled="0" respect_EPYTHON="0"
1070
1071 while (($#)); do
1072 case "$1" in
1073 -E|--respect-EPYTHON)
1074 respect_EPYTHON="1"
1075 ;;
1076 -f|--force)
1077 force="1"
1078 ;;
1079 -q|--quiet)
1080 quiet="1"
1081 ;;
1082 --)
1083 shift
1084 break
1085 ;;
1086 -*)
1087 die "${FUNCNAME}(): Unrecognized option '$1'"
1088 ;;
1089 *)
1090 break
1091 ;;
1092 esac
1093 shift
1094 done
1095
1096 if [[ "$#" -eq 0 ]]; then
1097 die "${FUNCNAME}(): Missing arguments"
1098 fi
1099
1100 _python_calculate_PYTHON_ABIS
1101 for PYTHON_ABI in "${_CPYTHON2_SUPPORTED_ABIS[@]}"; do
1102 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
1103 python2_enabled="1"
1104 fi
1105 done
1106 for PYTHON_ABI in "${_CPYTHON3_SUPPORTED_ABIS[@]}"; do
1107 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
1108 python3_enabled="1"
1109 fi
1110 done
1111
1112 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
1113 eselect_python_option=
1114 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
1115 eselect_python_option="--python2"
1116 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
1117 eselect_python_option="--python3"
1118 else
1119 die "${FUNCNAME}(): Unsupported environment"
1120 fi
1121
1122 for file in "$@"; do
1123 if [[ -f "${file}" && "${force}" == "0" ]]; then
1124 die "${FUNCNAME}(): '$1' already exists"
1125 fi
1126
1127 if [[ "${quiet}" == "0" ]]; then
1128 einfo "Generating '${file#${ED%/}}' wrapper script"
1129 fi
1130
1131 cat << EOF > "${file}"
1132 #!/usr/bin/env python
1133 # Gentoo '${file##*/}' wrapper script generated by python_generate_wrapper_scripts()
1134
1135 import os
1136 import re
1137 import subprocess
1138 import sys
1139
1140 EPYTHON_re = re.compile(r"^python(\d+\.\d+)$")
1141 python_shebang_re = re.compile(r"^#! *(${EPREFIX}/usr/bin/python|(${EPREFIX})?/usr/bin/env +(${EPREFIX}/usr/bin/)?python)")
1142 python_verification_output_re = re.compile("^GENTOO_PYTHON_TARGET_SCRIPT_PATH supported\n$")
1143
1144 EOF
1145 if [[ "$?" != "0" ]]; then
1146 die "${FUNCNAME}(): Generation of '$1' failed"
1147 fi
1148 if [[ "${respect_EPYTHON}" == "1" ]]; then
1149 cat << EOF >> "${file}"
1150 EPYTHON = os.environ.get("EPYTHON")
1151 if EPYTHON:
1152 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
1153 if EPYTHON_matched:
1154 PYTHON_ABI = EPYTHON_matched.group(1)
1155 else:
1156 sys.stderr.write("EPYTHON variable has unrecognized value '%s'\n" % EPYTHON)
1157 sys.exit(1)
1158 else:
1159 try:
1160 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
1161 if eselect_process.wait() != 0:
1162 raise ValueError
1163 except (OSError, ValueError):
1164 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
1165 sys.exit(1)
1166
1167 EPYTHON = eselect_process.stdout.read()
1168 if not isinstance(EPYTHON, str):
1169 # Python 3
1170 EPYTHON = EPYTHON.decode()
1171 EPYTHON = EPYTHON.rstrip("\n")
1172
1173 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
1174 if EPYTHON_matched:
1175 PYTHON_ABI = EPYTHON_matched.group(1)
1176 else:
1177 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s'\n" % EPYTHON)
1178 sys.exit(1)
1179 EOF
1180 if [[ "$?" != "0" ]]; then
1181 die "${FUNCNAME}(): Generation of '$1' failed"
1182 fi
1183 else
1184 cat << EOF >> "${file}"
1185 try:
1186 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
1187 if eselect_process.wait() != 0:
1188 raise ValueError
1189 except (OSError, ValueError):
1190 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
1191 sys.exit(1)
1192
1193 EPYTHON = eselect_process.stdout.read()
1194 if not isinstance(EPYTHON, str):
1195 # Python 3
1196 EPYTHON = EPYTHON.decode()
1197 EPYTHON = EPYTHON.rstrip("\n")
1198
1199 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
1200 if EPYTHON_matched:
1201 PYTHON_ABI = EPYTHON_matched.group(1)
1202 else:
1203 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s'\n" % EPYTHON)
1204 sys.exit(1)
1205 EOF
1206 if [[ "$?" != "0" ]]; then
1207 die "${FUNCNAME}(): Generation of '$1' failed"
1208 fi
1209 fi
1210 cat << EOF >> "${file}"
1211
1212 wrapper_script_path = os.path.realpath(sys.argv[0])
1213 target_executable_path = "%s-%s" % (wrapper_script_path, PYTHON_ABI)
1214 os.environ["GENTOO_PYTHON_PROCESS_NAME"] = os.path.basename(sys.argv[0])
1215 os.environ["GENTOO_PYTHON_WRAPPER_SCRIPT_PATH"] = sys.argv[0]
1216 os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH"] = target_executable_path
1217 if not os.path.exists(target_executable_path):
1218 sys.stderr.write("'%s' does not exist\n" % target_executable_path)
1219 sys.exit(1)
1220
1221 target_executable = open(target_executable_path, "rb")
1222 target_executable_first_line = target_executable.readline()
1223 if not isinstance(target_executable_first_line, str):
1224 # Python 3
1225 target_executable_first_line = target_executable_first_line.decode("utf_8", "replace")
1226
1227 python_shebang_matched = python_shebang_re.match(target_executable_first_line)
1228 target_executable.close()
1229
1230 if python_shebang_matched:
1231 try:
1232 python_interpreter_path = "${EPREFIX}/usr/bin/%s" % EPYTHON
1233 os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"] = "1"
1234 python_verification_process = subprocess.Popen([python_interpreter_path, "-c", "pass"], stdout=subprocess.PIPE)
1235 del os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"]
1236 if python_verification_process.wait() != 0:
1237 raise ValueError
1238
1239 python_verification_output = python_verification_process.stdout.read()
1240 if not isinstance(python_verification_output, str):
1241 # Python 3
1242 python_verification_output = python_verification_output.decode()
1243
1244 if not python_verification_output_re.match(python_verification_output):
1245 raise ValueError
1246
1247 os.execv(python_interpreter_path, [python_interpreter_path] + sys.argv)
1248 except:
1249 pass
1250 if "GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION" in os.environ:
1251 del os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"]
1252
1253 os.execv(target_executable_path, sys.argv)
1254 EOF
1255 if [[ "$?" != "0" ]]; then
1256 die "${FUNCNAME}(): Generation of '$1' failed"
1257 fi
1258 fperms +x "${file#${ED%/}}" || die "fperms '${file}' failed"
1259 done
1260 }
1261
1262 # ================================================================================================
1263 # ========= FUNCTIONS FOR PACKAGES NOT SUPPORTING INSTALLATION FOR MULTIPLE PYTHON ABIS ==========
1264 # ================================================================================================
1265
1266 unset EPYTHON PYTHON_ABI
1267
1268 # @FUNCTION: python_set_active_version
1269 # @USAGE: <CPython_ABI|2|3>
1270 # @DESCRIPTION:
1271 # Set specified version of CPython as active version of Python.
1272 #
1273 # This function can be used only in pkg_setup() phase.
1274 python_set_active_version() {
1275 # Check if phase is pkg_setup().
1276 [[ "${EBUILD_PHASE}" != "setup" ]] && die "${FUNCNAME}() can be used only in pkg_setup() phase"
1277
1278 if _python_package_supporting_installation_for_multiple_python_abis; then
1279 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
1280 fi
1281
1282 if [[ "$#" -ne 1 ]]; then
1283 die "${FUNCNAME}() requires 1 argument"
1284 fi
1285
1286 _python_initial_sanity_checks
1287
1288 if [[ -z "${PYTHON_ABI}" ]]; then
1289 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
1290 if ! _python_implementation && ! has_version "dev-lang/python:$1"; then
1291 die "${FUNCNAME}(): 'dev-lang/python:$1' is not installed"
1292 fi
1293 export EPYTHON="$(PYTHON "$1")"
1294 elif [[ "$1" == "2" ]]; then
1295 if ! _python_implementation && ! has_version "=dev-lang/python-2*"; then
1296 die "${FUNCNAME}(): '=dev-lang/python-2*' is not installed"
1297 fi
1298 export EPYTHON="$(PYTHON -2)"
1299 elif [[ "$1" == "3" ]]; then
1300 if ! _python_implementation && ! has_version "=dev-lang/python-3*"; then
1301 die "${FUNCNAME}(): '=dev-lang/python-3*' is not installed"
1302 fi
1303 export EPYTHON="$(PYTHON -3)"
1304 else
1305 die "${FUNCNAME}(): Unrecognized argument '$1'"
1306 fi
1307
1308 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
1309 # so it does not need to be exported to subprocesses.
1310 PYTHON_ABI="${EPYTHON#python}"
1311 PYTHON_ABI="${PYTHON_ABI%%-*}"
1312 fi
1313
1314 _python_final_sanity_checks
1315
1316 # python-updater checks PYTHON_REQUESTED_ACTIVE_VERSION variable.
1317 PYTHON_REQUESTED_ACTIVE_VERSION="$1"
1318 }
1319
1320 # @FUNCTION: python_need_rebuild
1321 # @DESCRIPTION: Mark current package for rebuilding by python-updater after
1322 # switching of active version of Python.
1323 python_need_rebuild() {
1324 _python_check_python_pkg_setup_execution
1325
1326 if _python_package_supporting_installation_for_multiple_python_abis; then
1327 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
1328 fi
1329
1330 if [[ "$#" -ne 0 ]]; then
1331 die "${FUNCNAME}() does not accept arguments"
1332 fi
1333
1334 export PYTHON_NEED_REBUILD="$(PYTHON --ABI)"
1335 }
1336
1337 # ================================================================================================
1338 # ======================================= GETTER FUNCTIONS =======================================
1339 # ================================================================================================
1340
1341 _PYTHON_ABI_EXTRACTION_COMMAND='import platform
1342 import sys
1343 sys.stdout.write(".".join(str(x) for x in sys.version_info[:2]))
1344 if platform.system()[:4] == "Java":
1345 sys.stdout.write("-jython")'
1346
1347 _python_get_implementation() {
1348 if [[ "$#" -ne 1 ]]; then
1349 die "${FUNCNAME}() requires 1 argument"
1350 fi
1351
1352 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
1353 echo "CPython"
1354 elif [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+-jython$ ]]; then
1355 echo "Jython"
1356 else
1357 die "${FUNCNAME}(): Unrecognized Python ABI '$1'"
1358 fi
1359 }
1360
1361 # @FUNCTION: PYTHON
1362 # @USAGE: [-2] [-3] [--ABI] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
1363 # @DESCRIPTION:
1364 # Print filename of Python interpreter for specified Python ABI. If Python_ABI argument
1365 # is ommitted, then PYTHON_ABI environment variable must be set and is used.
1366 # If -2 option is specified, then active version of Python 2 is used.
1367 # If -3 option is specified, then active version of Python 3 is used.
1368 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1369 # -2, -3 and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
1370 # If --ABI option is specified, then only specified Python ABI is printed instead of
1371 # filename of Python interpreter.
1372 # If --absolute-path option is specified, then absolute path to Python interpreter is printed.
1373 # --ABI and --absolute-path options cannot be specified simultaneously.
1374 PYTHON() {
1375 _python_check_python_pkg_setup_execution
1376
1377 local ABI_output="0" absolute_path_output="0" final_ABI="0" PYTHON_ABI="${PYTHON_ABI}" python_interpreter python2="0" python3="0"
1378
1379 while (($#)); do
1380 case "$1" in
1381 -2)
1382 python2="1"
1383 ;;
1384 -3)
1385 python3="1"
1386 ;;
1387 --ABI)
1388 ABI_output="1"
1389 ;;
1390 -a|--absolute-path)
1391 absolute_path_output="1"
1392 ;;
1393 -f|--final-ABI)
1394 final_ABI="1"
1395 ;;
1396 --)
1397 shift
1398 break
1399 ;;
1400 -*)
1401 die "${FUNCNAME}(): Unrecognized option '$1'"
1402 ;;
1403 *)
1404 break
1405 ;;
1406 esac
1407 shift
1408 done
1409
1410 if [[ "${ABI_output}" == "1" && "${absolute_path_output}" == "1" ]]; then
1411 die "${FUNCNAME}(): '--ABI' and '--absolute-path' options cannot be specified simultaneously"
1412 fi
1413
1414 if [[ "$((${python2} + ${python3} + ${final_ABI}))" -gt 1 ]]; then
1415 die "${FUNCNAME}(): '-2', '-3' or '--final-ABI' options cannot be specified simultaneously"
1416 fi
1417
1418 if [[ "$#" -eq 0 ]]; then
1419 if [[ "${final_ABI}" == "1" ]]; then
1420 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1421 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1422 fi
1423 _python_calculate_PYTHON_ABIS
1424 PYTHON_ABI="${PYTHON_ABIS##* }"
1425 elif [[ "${python2}" == "1" ]]; then
1426 PYTHON_ABI="$(eselect python show --python2 --ABI)"
1427 if [[ -z "${PYTHON_ABI}" ]]; then
1428 die "${FUNCNAME}(): Active version of Python 2 not set"
1429 elif [[ "${PYTHON_ABI}" != "2."* ]]; then
1430 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
1431 fi
1432 elif [[ "${python3}" == "1" ]]; then
1433 PYTHON_ABI="$(eselect python show --python3 --ABI)"
1434 if [[ -z "${PYTHON_ABI}" ]]; then
1435 die "${FUNCNAME}(): Active version of Python 3 not set"
1436 elif [[ "${PYTHON_ABI}" != "3."* ]]; then
1437 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
1438 fi
1439 elif _python_package_supporting_installation_for_multiple_python_abis; then
1440 if ! _python_abi-specific_local_scope; then
1441 die "${FUNCNAME}() should be used in ABI-specific local scope"
1442 fi
1443 else
1444 PYTHON_ABI="$("${EPREFIX}/usr/bin/python" -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")"
1445 if [[ -z "${PYTHON_ABI}" ]]; then
1446 die "${FUNCNAME}(): Failure of extraction of locally active version of Python"
1447 fi
1448 fi
1449 elif [[ "$#" -eq 1 ]]; then
1450 if [[ "${final_ABI}" == "1" ]]; then
1451 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
1452 fi
1453 if [[ "${python2}" == "1" ]]; then
1454 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
1455 fi
1456 if [[ "${python3}" == "1" ]]; then
1457 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
1458 fi
1459 PYTHON_ABI="$1"
1460 else
1461 die "${FUNCNAME}(): Invalid usage"
1462 fi
1463
1464 if [[ "${ABI_output}" == "1" ]]; then
1465 echo -n "${PYTHON_ABI}"
1466 return
1467 else
1468 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1469 python_interpreter="python${PYTHON_ABI}"
1470 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1471 python_interpreter="jython-${PYTHON_ABI%-jython}"
1472 fi
1473
1474 if [[ "${absolute_path_output}" == "1" ]]; then
1475 echo -n "${EPREFIX}/usr/bin/${python_interpreter}"
1476 else
1477 echo -n "${python_interpreter}"
1478 fi
1479 fi
1480
1481 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
1482 echo -n "-${ABI}"
1483 fi
1484 }
1485
1486 # @FUNCTION: python_get_implementation
1487 # @USAGE: [-f|--final-ABI]
1488 # @DESCRIPTION:
1489 # Print name of Python implementation.
1490 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1491 python_get_implementation() {
1492 _python_check_python_pkg_setup_execution
1493
1494 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1495
1496 while (($#)); do
1497 case "$1" in
1498 -f|--final-ABI)
1499 final_ABI="1"
1500 ;;
1501 -*)
1502 die "${FUNCNAME}(): Unrecognized option '$1'"
1503 ;;
1504 *)
1505 die "${FUNCNAME}(): Invalid usage"
1506 ;;
1507 esac
1508 shift
1509 done
1510
1511 if [[ "${final_ABI}" == "1" ]]; then
1512 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1513 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1514 fi
1515 PYTHON_ABI="$(PYTHON -f --ABI)"
1516 else
1517 if _python_package_supporting_installation_for_multiple_python_abis; then
1518 if ! _python_abi-specific_local_scope; then
1519 die "${FUNCNAME}() should be used in ABI-specific local scope"
1520 fi
1521 else
1522 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1523 fi
1524 fi
1525
1526 echo "$(_python_get_implementation "${PYTHON_ABI}")"
1527 }
1528
1529 # @FUNCTION: python_get_implementational_package
1530 # @USAGE: [-f|--final-ABI]
1531 # @DESCRIPTION:
1532 # Print category, name and slot of package providing Python implementation.
1533 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1534 python_get_implementational_package() {
1535 _python_check_python_pkg_setup_execution
1536
1537 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1538
1539 while (($#)); do
1540 case "$1" in
1541 -f|--final-ABI)
1542 final_ABI="1"
1543 ;;
1544 -*)
1545 die "${FUNCNAME}(): Unrecognized option '$1'"
1546 ;;
1547 *)
1548 die "${FUNCNAME}(): Invalid usage"
1549 ;;
1550 esac
1551 shift
1552 done
1553
1554 if [[ "${final_ABI}" == "1" ]]; then
1555 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1556 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1557 fi
1558 PYTHON_ABI="$(PYTHON -f --ABI)"
1559 else
1560 if _python_package_supporting_installation_for_multiple_python_abis; then
1561 if ! _python_abi-specific_local_scope; then
1562 die "${FUNCNAME}() should be used in ABI-specific local scope"
1563 fi
1564 else
1565 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1566 fi
1567 fi
1568
1569 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1570 echo "dev-lang/python:${PYTHON_ABI}"
1571 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1572 echo "dev-java/jython:${PYTHON_ABI%-jython}"
1573 fi
1574 }
1575
1576 # @FUNCTION: python_get_includedir
1577 # @USAGE: [-b|--base-path] [-f|--final-ABI]
1578 # @DESCRIPTION:
1579 # Print path to Python include directory.
1580 # If --base-path option is specified, then path not prefixed with "/" is printed.
1581 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1582 python_get_includedir() {
1583 _python_check_python_pkg_setup_execution
1584
1585 local base_path="0" final_ABI="0" prefix PYTHON_ABI="${PYTHON_ABI}"
1586
1587 while (($#)); do
1588 case "$1" in
1589 -b|--base-path)
1590 base_path="1"
1591 ;;
1592 -f|--final-ABI)
1593 final_ABI="1"
1594 ;;
1595 -*)
1596 die "${FUNCNAME}(): Unrecognized option '$1'"
1597 ;;
1598 *)
1599 die "${FUNCNAME}(): Invalid usage"
1600 ;;
1601 esac
1602 shift
1603 done
1604
1605 if [[ "${base_path}" == "0" ]]; then
1606 prefix="/"
1607 fi
1608
1609 if [[ "${final_ABI}" == "1" ]]; then
1610 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1611 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1612 fi
1613 PYTHON_ABI="$(PYTHON -f --ABI)"
1614 else
1615 if _python_package_supporting_installation_for_multiple_python_abis; then
1616 if ! _python_abi-specific_local_scope; then
1617 die "${FUNCNAME}() should be used in ABI-specific local scope"
1618 fi
1619 else
1620 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1621 fi
1622 fi
1623
1624 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1625 echo "${prefix}usr/include/python${PYTHON_ABI}"
1626 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1627 echo "${prefix}usr/share/jython-${PYTHON_ABI%-jython}/Include"
1628 fi
1629 }
1630
1631 # @FUNCTION: python_get_libdir
1632 # @USAGE: [-b|--base-path] [-f|--final-ABI]
1633 # @DESCRIPTION:
1634 # Print path to Python library directory.
1635 # If --base-path option is specified, then path not prefixed with "/" is printed.
1636 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1637 python_get_libdir() {
1638 _python_check_python_pkg_setup_execution
1639
1640 local base_path="0" final_ABI="0" prefix PYTHON_ABI="${PYTHON_ABI}"
1641
1642 while (($#)); do
1643 case "$1" in
1644 -b|--base-path)
1645 base_path="1"
1646 ;;
1647 -f|--final-ABI)
1648 final_ABI="1"
1649 ;;
1650 -*)
1651 die "${FUNCNAME}(): Unrecognized option '$1'"
1652 ;;
1653 *)
1654 die "${FUNCNAME}(): Invalid usage"
1655 ;;
1656 esac
1657 shift
1658 done
1659
1660 if [[ "${base_path}" == "0" ]]; then
1661 prefix="/"
1662 fi
1663
1664 if [[ "${final_ABI}" == "1" ]]; then
1665 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1666 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1667 fi
1668 PYTHON_ABI="$(PYTHON -f --ABI)"
1669 else
1670 if _python_package_supporting_installation_for_multiple_python_abis; then
1671 if ! _python_abi-specific_local_scope; then
1672 die "${FUNCNAME}() should be used in ABI-specific local scope"
1673 fi
1674 else
1675 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1676 fi
1677 fi
1678
1679 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1680 echo "${prefix}usr/$(get_libdir)/python${PYTHON_ABI}"
1681 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1682 echo "${prefix}usr/share/jython-${PYTHON_ABI%-jython}/Lib"
1683 fi
1684 }
1685
1686 # @FUNCTION: python_get_sitedir
1687 # @USAGE: [-b|--base-path] [-f|--final-ABI]
1688 # @DESCRIPTION:
1689 # Print path to Python site-packages directory.
1690 # If --base-path option is specified, then path not prefixed with "/" is printed.
1691 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1692 python_get_sitedir() {
1693 _python_check_python_pkg_setup_execution
1694
1695 local final_ABI="0" options=()
1696
1697 while (($#)); do
1698 case "$1" in
1699 -b|--base-path)
1700 options+=("$1")
1701 ;;
1702 -f|--final-ABI)
1703 final_ABI="1"
1704 options+=("$1")
1705 ;;
1706 -*)
1707 die "${FUNCNAME}(): Unrecognized option '$1'"
1708 ;;
1709 *)
1710 die "${FUNCNAME}(): Invalid usage"
1711 ;;
1712 esac
1713 shift
1714 done
1715
1716 if [[ "${final_ABI}" == "1" ]]; then
1717 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1718 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1719 fi
1720 else
1721 if _python_package_supporting_installation_for_multiple_python_abis && ! _python_abi-specific_local_scope; then
1722 die "${FUNCNAME}() should be used in ABI-specific local scope"
1723 fi
1724 fi
1725
1726 echo "$(python_get_libdir "${options[@]}")/site-packages"
1727 }
1728
1729 # @FUNCTION: python_get_library
1730 # @USAGE: [-b|--base-path] [-f|--final-ABI] [-l|--linker-option]
1731 # @DESCRIPTION:
1732 # Print path to Python library.
1733 # If --base-path option is specified, then path not prefixed with "/" is printed.
1734 # If --linker-option is specified, then "-l${library}" linker option is printed.
1735 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1736 python_get_library() {
1737 _python_check_python_pkg_setup_execution
1738
1739 local base_path="0" final_ABI="0" linker_option="0" prefix PYTHON_ABI="${PYTHON_ABI}"
1740
1741 while (($#)); do
1742 case "$1" in
1743 -b|--base-path)
1744 base_path="1"
1745 ;;
1746 -f|--final-ABI)
1747 final_ABI="1"
1748 ;;
1749 -l|--linker-option)
1750 linker_option="1"
1751 ;;
1752 -*)
1753 die "${FUNCNAME}(): Unrecognized option '$1'"
1754 ;;
1755 *)
1756 die "${FUNCNAME}(): Invalid usage"
1757 ;;
1758 esac
1759 shift
1760 done
1761
1762 if [[ "${base_path}" == "0" ]]; then
1763 prefix="/"
1764 fi
1765
1766 if [[ "${base_path}" == "1" && "${linker_option}" == "1" ]]; then
1767 die "${FUNCNAME}(): '--base-path' and '--linker-option' options cannot be specified simultaneously"
1768 fi
1769
1770 if [[ "${final_ABI}" == "1" ]]; then
1771 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1772 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1773 fi
1774 PYTHON_ABI="$(PYTHON -f --ABI)"
1775 else
1776 if _python_package_supporting_installation_for_multiple_python_abis; then
1777 if ! _python_abi-specific_local_scope; then
1778 die "${FUNCNAME}() should be used in ABI-specific local scope"
1779 fi
1780 else
1781 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1782 fi
1783 fi
1784
1785 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1786 if [[ "${linker_option}" == "1" ]]; then
1787 echo "-lpython${PYTHON_ABI}"
1788 else
1789 echo "${prefix}usr/$(get_libdir)/libpython${PYTHON_ABI}$(get_libname)"
1790 fi
1791 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1792 die "${FUNCNAME}(): Jython does not have shared library"
1793 fi
1794 }
1795
1796 # @FUNCTION: python_get_version
1797 # @USAGE: [-f|--final-ABI] [--full] [--major] [--minor] [--micro]
1798 # @DESCRIPTION:
1799 # Print Python version.
1800 # --full, --major, --minor and --micro options cannot be specified simultaneously.
1801 # If --full, --major, --minor and --micro options are not specified, then "${major_version}.${minor_version}" is printed.
1802 # If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1803 python_get_version() {
1804 _python_check_python_pkg_setup_execution
1805
1806 local final_ABI="0" full="0" major="0" minor="0" micro="0" python_command
1807
1808 while (($#)); do
1809 case "$1" in
1810 -f|--final-ABI)
1811 final_ABI="1"
1812 ;;
1813 --full)
1814 full="1"
1815 ;;
1816 --major)
1817 major="1"
1818 ;;
1819 --minor)
1820 minor="1"
1821 ;;
1822 --micro)
1823 micro="1"
1824 ;;
1825 -*)
1826 die "${FUNCNAME}(): Unrecognized option '$1'"
1827 ;;
1828 *)
1829 die "${FUNCNAME}(): Invalid usage"
1830 ;;
1831 esac
1832 shift
1833 done
1834
1835 if [[ "$((${full} + ${major} + ${minor} + ${micro}))" -gt 1 ]]; then
1836 die "${FUNCNAME}(): '--full', '--major', '--minor' or '--micro' options cannot be specified simultaneously"
1837 fi
1838
1839 if [[ "${full}" == "1" ]]; then
1840 python_command="from sys import version_info; print('.'.join(str(x) for x in version_info[:3]))"
1841 elif [[ "${major}" == "1" ]]; then
1842 python_command="from sys import version_info; print(version_info[0])"
1843 elif [[ "${minor}" == "1" ]]; then
1844 python_command="from sys import version_info; print(version_info[1])"
1845 elif [[ "${micro}" == "1" ]]; then
1846 python_command="from sys import version_info; print(version_info[2])"
1847 else
1848 if [[ -n "${PYTHON_ABI}" && "${final_ABI}" == "0" ]]; then
1849 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1850 echo "${PYTHON_ABI}"
1851 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1852 echo "${PYTHON_ABI%-jython}"
1853 fi
1854 return
1855 fi
1856 python_command="from sys import version_info; print('.'.join(str(x) for x in version_info[:2]))"
1857 fi
1858
1859 if [[ "${final_ABI}" == "1" ]]; then
1860 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1861 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1862 fi
1863 "$(PYTHON -f)" -c "${python_command}"
1864 else
1865 if _python_package_supporting_installation_for_multiple_python_abis && ! _python_abi-specific_local_scope; then
1866 die "${FUNCNAME}() should be used in ABI-specific local scope"
1867 fi
1868 "$(PYTHON ${PYTHON_ABI})" -c "${python_command}"
1869 fi
1870 }
1871
1872 # ================================================================================================
1873 # ================================ FUNCTIONS FOR RUNNING OF TESTS ================================
1874 # ================================================================================================
1875
1876 # @ECLASS-VARIABLE: PYTHON_TEST_VERBOSITY
1877 # @DESCRIPTION:
1878 # User-configurable verbosity of tests of Python modules.
1879 # Supported values: 0, 1, 2, 3, 4.
1880 PYTHON_TEST_VERBOSITY="${PYTHON_TEST_VERBOSITY:-1}"
1881
1882 _python_test_hook() {
1883 if [[ "$#" -ne 1 ]]; then
1884 die "${FUNCNAME}() requires 1 argument"
1885 fi
1886
1887 if _python_package_supporting_installation_for_multiple_python_abis && [[ "$(type -t "${FUNCNAME[3]}_$1_hook")" == "function" ]]; then
1888 "${FUNCNAME[3]}_$1_hook"
1889 fi
1890 }
1891
1892 # @FUNCTION: python_execute_nosetests
1893 # @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
1894 # @DESCRIPTION:
1895 # Execute nosetests for all enabled Python ABIs.
1896 # In ebuilds of packages supporting installation for multiple Python ABIs, this function calls
1897 # python_execute_nosetests_pre_hook() and python_execute_nosetests_post_hook(), if they are defined.
1898 python_execute_nosetests() {
1899 _python_check_python_pkg_setup_execution
1900 _python_set_color_variables
1901
1902 local PYTHONPATH_template= separate_build_dirs=
1903
1904 while (($#)); do
1905 case "$1" in
1906 -P|--PYTHONPATH)
1907 PYTHONPATH_template="$2"
1908 shift
1909 ;;
1910 -s|--separate-build-dirs)
1911 separate_build_dirs="1"
1912 ;;
1913 --)
1914 shift
1915 break
1916 ;;
1917 -*)
1918 die "${FUNCNAME}(): Unrecognized option '$1'"
1919 ;;
1920 *)
1921 break
1922 ;;
1923 esac
1924 shift
1925 done
1926
1927 python_test_function() {
1928 local evaluated_PYTHONPATH
1929
1930 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")"
1931
1932 _python_test_hook pre
1933
1934 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
1935 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL}
1936 PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" || return "$?"
1937 else
1938 echo ${_BOLD}nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL}
1939 nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" || return "$?"
1940 fi
1941
1942 _python_test_hook post
1943 }
1944 if _python_package_supporting_installation_for_multiple_python_abis; then
1945 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
1946 else
1947 if [[ -n "${separate_build_dirs}" ]]; then
1948 die "${FUNCNAME}(): Invalid usage"
1949 fi
1950 python_test_function "$@" || die "Testing failed"
1951 fi
1952
1953 unset -f python_test_function
1954 }
1955
1956 # @FUNCTION: python_execute_py.test
1957 # @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
1958 # @DESCRIPTION:
1959 # Execute py.test for all enabled Python ABIs.
1960 # In ebuilds of packages supporting installation for multiple Python ABIs, this function calls
1961 # python_execute_py.test_pre_hook() and python_execute_py.test_post_hook(), if they are defined.
1962 python_execute_py.test() {
1963 _python_check_python_pkg_setup_execution
1964 _python_set_color_variables
1965
1966 local PYTHONPATH_template= separate_build_dirs=
1967
1968 while (($#)); do
1969 case "$1" in
1970 -P|--PYTHONPATH)
1971 PYTHONPATH_template="$2"
1972 shift
1973 ;;
1974 -s|--separate-build-dirs)
1975 separate_build_dirs="1"
1976 ;;
1977 --)
1978 shift
1979 break
1980 ;;
1981 -*)
1982 die "${FUNCNAME}(): Unrecognized option '$1'"
1983 ;;
1984 *)
1985 break
1986 ;;
1987 esac
1988 shift
1989 done
1990
1991 python_test_function() {
1992 local evaluated_PYTHONPATH
1993
1994 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")"
1995
1996 _python_test_hook pre
1997
1998 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
1999 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@"${_NORMAL}
2000 PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@" || return "$?"
2001 else
2002 echo ${_BOLD}py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@"${_NORMAL}
2003 py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@" || return "$?"
2004 fi
2005
2006 _python_test_hook post
2007 }
2008 if _python_package_supporting_installation_for_multiple_python_abis; then
2009 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
2010 else
2011 if [[ -n "${separate_build_dirs}" ]]; then
2012 die "${FUNCNAME}(): Invalid usage"
2013 fi
2014 python_test_function "$@" || die "Testing failed"
2015 fi
2016
2017 unset -f python_test_function
2018 }
2019
2020 # @FUNCTION: python_execute_trial
2021 # @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
2022 # @DESCRIPTION:
2023 # Execute trial for all enabled Python ABIs.
2024 # In ebuilds of packages supporting installation for multiple Python ABIs, this function
2025 # calls python_execute_trial_pre_hook() and python_execute_trial_post_hook(), if they are defined.
2026 python_execute_trial() {
2027 _python_check_python_pkg_setup_execution
2028 _python_set_color_variables
2029
2030 local PYTHONPATH_template= separate_build_dirs=
2031
2032 while (($#)); do
2033 case "$1" in
2034 -P|--PYTHONPATH)
2035 PYTHONPATH_template="$2"
2036 shift
2037 ;;
2038 -s|--separate-build-dirs)
2039 separate_build_dirs="1"
2040 ;;
2041 --)
2042 shift
2043 break
2044 ;;
2045 -*)
2046 die "${FUNCNAME}(): Unrecognized option '$1'"
2047 ;;
2048 *)
2049 break
2050 ;;
2051 esac
2052 shift
2053 done
2054
2055 python_test_function() {
2056 local evaluated_PYTHONPATH
2057
2058 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")"
2059
2060 _python_test_hook pre
2061
2062 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
2063 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL}
2064 PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" || return "$?"
2065 else
2066 echo ${_BOLD}trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL}
2067 trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" || return "$?"
2068 fi
2069
2070 _python_test_hook post
2071 }
2072 if _python_package_supporting_installation_for_multiple_python_abis; then
2073 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
2074 else
2075 if [[ -n "${separate_build_dirs}" ]]; then
2076 die "${FUNCNAME}(): Invalid usage"
2077 fi
2078 python_test_function "$@" || die "Testing failed"
2079 fi
2080
2081 unset -f python_test_function
2082 }
2083
2084 # ================================================================================================
2085 # ======================= FUNCTIONS FOR HANDLING OF BYTE-COMPILED MODULES ========================
2086 # ================================================================================================
2087
2088 # @FUNCTION: python_enable_pyc
2089 # @DESCRIPTION:
2090 # Tell Python to automatically recompile modules to .pyc/.pyo if the
2091 # timestamps/version stamps have changed.
2092 python_enable_pyc() {
2093 _python_check_python_pkg_setup_execution
2094
2095 if [[ "$#" -ne 0 ]]; then
2096 die "${FUNCNAME}() does not accept arguments"
2097 fi
2098
2099 unset PYTHONDONTWRITEBYTECODE
2100 }
2101
2102 # @FUNCTION: python_disable_pyc
2103 # @DESCRIPTION:
2104 # Tell Python not to automatically recompile modules to .pyc/.pyo
2105 # even if the timestamps/version stamps do not match. This is done
2106 # to protect sandbox.
2107 python_disable_pyc() {
2108 _python_check_python_pkg_setup_execution
2109
2110 if [[ "$#" -ne 0 ]]; then
2111 die "${FUNCNAME}() does not accept arguments"
2112 fi
2113
2114 export PYTHONDONTWRITEBYTECODE="1"
2115 }
2116
2117 _python_clean_compiled_modules() {
2118 _python_initialize_prefix_variables
2119 _python_set_color_variables
2120
2121 [[ "${FUNCNAME[1]}" =~ ^(python_mod_optimize|python_mod_compile|python_mod_cleanup)$ ]] || die "${FUNCNAME}(): Invalid usage"
2122
2123 local base_module_name compiled_file compiled_files=() dir path py_file root
2124
2125 # Strip trailing slash from EROOT.
2126 root="${EROOT%/}"
2127
2128 for path in "$@"; do
2129 compiled_files=()
2130 if [[ -d "${path}" ]]; then
2131 while read -d $'\0' -r compiled_file; do
2132 compiled_files+=("${compiled_file}")
2133 done < <(find "${path}" "(" -name "*.py[co]" -o -name "*\$py.class" ")" -print0)
2134
2135 if [[ "${EBUILD_PHASE}" == "postrm" ]]; then
2136 # Delete empty child directories.
2137 find "${path}" -type d | sort -r | while read -r dir; do
2138 if rmdir "${dir}" 2> /dev/null; then
2139 echo "${_CYAN}<<< ${dir}${_NORMAL}"
2140 fi
2141 done
2142 fi
2143 elif [[ "${path}" == *.py ]]; then
2144 base_module_name="${path##*/}"
2145 base_module_name="${base_module_name%.py}"
2146 if [[ -d "${path%/*}/__pycache__" ]]; then
2147 while read -d $'\0' -r compiled_file; do
2148 compiled_files+=("${compiled_file}")
2149 done < <(find "${path%/*}/__pycache__" "(" -name "${base_module_name}.*.py[co]" -o -name "${base_module_name}\$py.class" ")" -print0)
2150 fi
2151 compiled_files+=("${path}c" "${path}o" "${path%.py}\$py.class")
2152 fi
2153
2154 for compiled_file in "${compiled_files[@]}"; do
2155 [[ ! -f "${compiled_file}" ]] && continue
2156 dir="${compiled_file%/*}"
2157 dir="${dir##*/}"
2158 if [[ "${compiled_file}" == *.py[co] ]]; then
2159 if [[ "${dir}" == "__pycache__" ]]; then
2160 base_module_name="${compiled_file##*/}"
2161 base_module_name="${base_module_name%.*py[co]}"
2162 base_module_name="${base_module_name%.*}"
2163 py_file="${compiled_file%__pycache__/*}${base_module_name}.py"
2164 else
2165 py_file="${compiled_file%[co]}"
2166 fi
2167 if [[ "${EBUILD_PHASE}" == "postinst" ]]; then
2168 [[ -f "${py_file}" && "${compiled_file}" -nt "${py_file}" ]] && continue
2169 else
2170 [[ -f "${py_file}" ]] && continue
2171 fi
2172 echo "${_BLUE}<<< ${compiled_file%[co]}[co]${_NORMAL}"
2173 rm -f "${compiled_file%[co]}"[co]
2174 elif [[ "${compiled_file}" == *\$py.class ]]; then
2175 if [[ "${dir}" == "__pycache__" ]]; then
2176 base_module_name="${compiled_file##*/}"
2177 base_module_name="${base_module_name%\$py.class}"
2178 py_file="${compiled_file%__pycache__/*}${base_module_name}.py"
2179 else
2180 py_file="${compiled_file%\$py.class}"
2181 fi
2182 if [[ "${EBUILD_PHASE}" == "postinst" ]]; then
2183 [[ -f "${py_file}" && "${compiled_file}" -nt "${py_file}" ]] && continue
2184 else
2185 [[ -f "${py_file}" ]] && continue
2186 fi
2187 echo "${_BLUE}<<< ${compiled_file}${_NORMAL}"
2188 rm -f "${compiled_file}"
2189 else
2190 die "${FUNCNAME}(): Unrecognized file type: '${compiled_file}'"
2191 fi
2192
2193 # Delete empty parent directories.
2194 dir="${compiled_file%/*}"
2195 while [[ "${dir}" != "${root}" ]]; do
2196 if rmdir "${dir}" 2> /dev/null; then
2197 echo "${_CYAN}<<< ${dir}${_NORMAL}"
2198 else
2199 break
2200 fi
2201 dir="${dir%/*}"
2202 done
2203 done
2204 done
2205 }
2206
2207 # @FUNCTION: python_mod_optimize
2208 # @USAGE: [options] [directory|file]
2209 # @DESCRIPTION:
2210 # If no arguments supplied, it will recompile not recursively all modules
2211 # under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
2212 #
2213 # If supplied with arguments, it will recompile all modules recursively
2214 # in the supplied directory.
2215 #
2216 # Options passed to this function are passed to compileall.py.
2217 #
2218 # This function can be used only in pkg_postinst() phase.
2219 python_mod_optimize() {
2220 _python_check_python_pkg_setup_execution
2221 _python_initialize_prefix_variables
2222
2223 # Check if phase is pkg_postinst().
2224 [[ "${EBUILD_PHASE}" != "postinst" ]] && die "${FUNCNAME}() can be used only in pkg_postinst() phase"
2225
2226 if ! has "${EAPI:-0}" 0 1 2 || _python_package_supporting_installation_for_multiple_python_abis; then
2227 # PYTHON_ABI variable cannot be local in packages not supporting installation for multiple Python ABIs.
2228 local dir file iterated_PYTHON_ABIS options=() other_dirs=() other_files=() previous_PYTHON_ABI="${PYTHON_ABI}" return_code root site_packages_absolute_dirs=() site_packages_dirs=() site_packages_absolute_files=() site_packages_files=()
2229
2230 if _python_package_supporting_installation_for_multiple_python_abis; then
2231 if has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_ABIS}" ]]; then
2232 die "${FUNCNAME}(): python_pkg_setup() or python_execute_function() not called"
2233 fi
2234 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
2235 else
2236 if has "${EAPI:-0}" 0 1 2 3; then
2237 iterated_PYTHON_ABIS="${PYTHON_ABI:=$(PYTHON --ABI)}"
2238 else
2239 iterated_PYTHON_ABIS="${PYTHON_ABI}"
2240 fi
2241 fi
2242
2243 # Strip trailing slash from EROOT.
2244 root="${EROOT%/}"
2245
2246 while (($#)); do
2247 case "$1" in
2248 -l|-f|-q)
2249 options+=("$1")
2250 ;;
2251 -d|-x)
2252 options+=("$1" "$2")
2253 shift
2254 ;;
2255 --)
2256 shift
2257 break
2258 ;;
2259 -*)
2260 die "${FUNCNAME}(): Unrecognized option '$1'"
2261 ;;
2262 *)
2263 break
2264 ;;
2265 esac
2266 shift
2267 done
2268
2269 if [[ "$#" -eq 0 ]]; then
2270 _python_set_color_variables
2271
2272 echo
2273 echo " ${_RED}*${_NORMAL} ${_RED}Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be${_NORMAL}"
2274 echo " ${_RED}*${_NORMAL} ${_RED}disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules.${_NORMAL}"
2275 echo " ${_RED}*${_NORMAL} ${_RED}The ebuild needs to be fixed. Please report a bug, if it has not been already reported.${_NORMAL}"
2276 echo
2277
2278 einfo &> /dev/null
2279 einfo "Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be" &> /dev/null
2280 einfo "disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules." &> /dev/null
2281 einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." &> /dev/null
2282 einfo &> /dev/null
2283 fi
2284
2285 while (($#)); do
2286 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
2287 die "${FUNCNAME}(): Invalid argument '$1'"
2288 elif ! _python_implementation && [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
2289 die "${FUNCNAME}(): Paths of directories / files in site-packages directories must be relative to site-packages directories"
2290 elif [[ "$1" =~ ^/ ]]; then
2291 if _python_package_supporting_installation_for_multiple_python_abis; then
2292 die "${FUNCNAME}(): Absolute paths cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
2293 fi
2294 if [[ -d "${root}$1" ]]; then
2295 other_dirs+=("${root}$1")
2296 elif [[ -f "${root}$1" ]]; then
2297 other_files+=("${root}$1")
2298 elif [[ -e "${root}$1" ]]; then
2299 eerror "${FUNCNAME}(): '${root}$1' is not a regular file or a directory"
2300 else
2301 eerror "${FUNCNAME}(): '${root}$1' does not exist"
2302 fi
2303 else
2304 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
2305 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
2306 site_packages_dirs+=("$1")
2307 break
2308 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
2309 site_packages_files+=("$1")
2310 break
2311 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
2312 eerror "${FUNCNAME}(): '$1' is not a regular file or a directory"
2313 else
2314 eerror "${FUNCNAME}(): '$1' does not exist"
2315 fi
2316 done
2317 fi
2318 shift
2319 done
2320
2321 # Set additional options.
2322 options+=("-q")
2323
2324 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
2325 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
2326 return_code="0"
2327 ebegin "Compilation and optimization of Python modules for $(python_get_implementation) $(python_get_version)"
2328 if ((${#site_packages_dirs[@]})); then
2329 for dir in "${site_packages_dirs[@]}"; do
2330 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
2331 done
2332 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
2333 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then
2334 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
2335 fi
2336 _python_clean_compiled_modules "${site_packages_absolute_dirs[@]}"
2337 fi
2338 if ((${#site_packages_files[@]})); then
2339 for file in "${site_packages_files[@]}"; do
2340 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
2341 done
2342 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
2343 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then
2344 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
2345 fi
2346 _python_clean_compiled_modules "${site_packages_absolute_files[@]}"
2347 fi
2348 eend "${return_code}"
2349 fi
2350 unset site_packages_absolute_dirs site_packages_absolute_files
2351 done
2352
2353 if _python_package_supporting_installation_for_multiple_python_abis; then
2354 # Restore previous value of PYTHON_ABI.
2355 if [[ -n "${previous_PYTHON_ABI}" ]]; then
2356 PYTHON_ABI="${previous_PYTHON_ABI}"
2357 else
2358 unset PYTHON_ABI
2359 fi
2360 fi
2361
2362 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
2363 return_code="0"
2364 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for $(python_get_implementation) $(python_get_version)"
2365 if ((${#other_dirs[@]})); then
2366 "$(PYTHON ${PYTHON_ABI})" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
2367 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then
2368 "$(PYTHON ${PYTHON_ABI})" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
2369 fi
2370 _python_clean_compiled_modules "${other_dirs[@]}"
2371 fi
2372 if ((${#other_files[@]})); then
2373 "$(PYTHON ${PYTHON_ABI})" "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
2374 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then
2375 "$(PYTHON ${PYTHON_ABI})" -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
2376 fi
2377 _python_clean_compiled_modules "${other_dirs[@]}"
2378 fi
2379 eend "${return_code}"
2380 fi
2381 else
2382 # Deprecated part of python_mod_optimize()
2383
2384 local myroot mydirs=() myfiles=() myopts=() return_code="0"
2385
2386 # strip trailing slash
2387 myroot="${EROOT%/}"
2388
2389 # respect EROOT and options passed to compileall.py
2390 while (($#)); do
2391 case "$1" in
2392 -l|-f|-q)
2393 myopts+=("$1")
2394 ;;
2395 -d|-x)
2396 myopts+=("$1" "$2")
2397 shift
2398 ;;
2399 --)
2400 shift
2401 break
2402 ;;
2403 -*)
2404 die "${FUNCNAME}(): Unrecognized option '$1'"
2405 ;;
2406 *)
2407 break
2408 ;;
2409 esac
2410 shift
2411 done
2412
2413 if [[ "$#" -eq 0 ]]; then
2414 _python_set_color_variables
2415
2416 echo
2417 echo " ${_RED}*${_NORMAL} ${_RED}Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be${_NORMAL}"
2418 echo " ${_RED}*${_NORMAL} ${_RED}disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules.${_NORMAL}"
2419 echo " ${_RED}*${_NORMAL} ${_RED}The ebuild needs to be fixed. Please report a bug, if it has not been already reported.${_NORMAL}"
2420 echo
2421
2422 einfo &> /dev/null
2423 einfo "Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be" &> /dev/null
2424 einfo "disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules." &> /dev/null
2425 einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." &> /dev/null
2426 einfo &> /dev/null
2427 fi
2428
2429 while (($#)); do
2430 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
2431 die "${FUNCNAME}(): Invalid argument '$1'"
2432 elif [[ -d "${myroot}/${1#/}" ]]; then
2433 mydirs+=("${myroot}/${1#/}")
2434 elif [[ -f "${myroot}/${1#/}" ]]; then
2435 # Files are passed to python_mod_compile which is EROOT-aware
2436 myfiles+=("$1")
2437 elif [[ -e "${myroot}/${1#/}" ]]; then
2438 eerror "${FUNCNAME}(): ${myroot}/${1#/} is not a regular file or directory"
2439 else
2440 eerror "${FUNCNAME}(): ${myroot}/${1#/} does not exist"
2441 fi
2442 shift
2443 done
2444
2445 # set additional opts
2446 myopts+=(-q)
2447
2448 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2449
2450 ebegin "Compilation and optimization of Python modules for $(python_get_implementation) $(python_get_version)"
2451 if ((${#mydirs[@]})); then
2452 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" || return_code="1"
2453 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
2454 _python_clean_compiled_modules "${mydirs[@]}"
2455 fi
2456
2457 if ((${#myfiles[@]})); then
2458 python_mod_compile "${myfiles[@]}"
2459 fi
2460
2461 eend "${return_code}"
2462 fi
2463 }
2464
2465 # @FUNCTION: python_mod_cleanup
2466 # @USAGE: [directory|file]
2467 # @DESCRIPTION:
2468 # Run with optional arguments, where arguments are Python modules. If none given,
2469 # it will look in /usr/lib/python[0-9].[0-9].
2470 #
2471 # It will recursively scan all compiled Python modules in the directories and
2472 # determine if they are orphaned (i.e. their corresponding .py files are missing.)
2473 # If they are, then it will remove their corresponding .pyc and .pyo files.
2474 #
2475 # This function can be used only in pkg_postrm() phase.
2476 python_mod_cleanup() {
2477 _python_check_python_pkg_setup_execution
2478 _python_initialize_prefix_variables
2479
2480 local dir iterated_PYTHON_ABIS PYTHON_ABI="${PYTHON_ABI}" root search_paths=() sitedir
2481
2482 # Check if phase is pkg_postrm().
2483 [[ "${EBUILD_PHASE}" != "postrm" ]] && die "${FUNCNAME}() can be used only in pkg_postrm() phase"
2484
2485 if _python_package_supporting_installation_for_multiple_python_abis; then
2486 if has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_ABIS}" ]]; then
2487 die "${FUNCNAME}(): python_pkg_setup() or python_execute_function() not called"
2488 fi
2489 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
2490 else
2491 if has "${EAPI:-0}" 0 1 2 3; then
2492 iterated_PYTHON_ABIS="${PYTHON_ABI:-$(PYTHON --ABI)}"
2493 else
2494 iterated_PYTHON_ABIS="${PYTHON_ABI}"
2495 fi
2496 fi
2497
2498 # Strip trailing slash from EROOT.
2499 root="${EROOT%/}"
2500
2501 if [[ "$#" -gt 0 ]]; then
2502 if ! has "${EAPI:-0}" 0 1 2 || _python_package_supporting_installation_for_multiple_python_abis; then
2503 while (($#)); do
2504 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
2505 die "${FUNCNAME}(): Invalid argument '$1'"
2506 elif ! _python_implementation && [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
2507 die "${FUNCNAME}(): Paths of directories / files in site-packages directories must be relative to site-packages directories"
2508 elif [[ "$1" =~ ^/ ]]; then
2509 if _python_package_supporting_installation_for_multiple_python_abis; then
2510 die "${FUNCNAME}(): Absolute paths cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
2511 fi
2512 search_paths+=("${root}$1")
2513 else
2514 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
2515 search_paths+=("${root}$(python_get_sitedir)/$1")
2516 done
2517 fi
2518 shift
2519 done
2520 else
2521 # Deprecated part of python_mod_cleanup()
2522
2523 search_paths=("${@#/}")
2524 search_paths=("${search_paths[@]/#/${root}/}")
2525 fi
2526 else
2527 _python_set_color_variables
2528
2529 echo
2530 echo " ${_RED}*${_NORMAL} ${_RED}Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be${_NORMAL}"
2531 echo " ${_RED}*${_NORMAL} ${_RED}disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules.${_NORMAL}"
2532 echo " ${_RED}*${_NORMAL} ${_RED}The ebuild needs to be fixed. Please report a bug, if it has not been already reported.${_NORMAL}"
2533 echo
2534
2535 einfo &> /dev/null
2536 einfo "Deprecation Warning: Not passing of paths to ${FUNCNAME}() is deprecated and will be" &> /dev/null
2537 einfo "disallowed on 2010-09-01. Call ${FUNCNAME}() with paths to Python modules." &> /dev/null
2538 einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." &> /dev/null
2539 einfo &> /dev/null
2540
2541 for dir in "${root}"/usr/lib*; do
2542 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
2543 for sitedir in "${dir}"/python*/site-packages; do
2544 if [[ -d "${sitedir}" ]]; then
2545 search_paths+=("${sitedir}")
2546 fi
2547 done
2548 fi
2549 done
2550 for sitedir in "${root}"/usr/share/jython-*/Lib/site-packages; do
2551 if [[ -d "${sitedir}" ]]; then
2552 search_paths+=("${sitedir}")
2553 fi
2554 done
2555 fi
2556
2557 _python_clean_compiled_modules "${search_paths[@]}"
2558 }
2559
2560 # ================================================================================================
2561 # ===================================== DEPRECATED FUNCTIONS =====================================
2562 # ================================================================================================
2563
2564 # Scheduled for deletion on 2011-01-01.
2565 python_version() {
2566 eerror "Use PYTHON() instead of python variable. Use python_get_*() instead of PYVER* variables."
2567 die "${FUNCNAME}() is banned"
2568 }
2569
2570 # Scheduled for deletion on 2011-01-01.
2571 python_mod_exists() {
2572 eerror "Use USE dependencies and/or has_version() instead of ${FUNCNAME}()."
2573 die "${FUNCNAME}() is banned"
2574 }
2575
2576 # Scheduled for deletion on 2011-01-01.
2577 python_tkinter_exists() {
2578 eerror "Use PYTHON_USE_WITH=\"xml\" and python_pkg_setup() instead of ${FUNCNAME}()."
2579 die "${FUNCNAME}() is banned"
2580 }
2581
2582 # @FUNCTION: python_mod_compile
2583 # @USAGE: <file> [more files ...]
2584 # @DESCRIPTION:
2585 # Given filenames, it will pre-compile the module's .pyc and .pyo.
2586 # This function can be used only in pkg_postinst() phase.
2587 #
2588 # Example:
2589 # python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
2590 #
2591 python_mod_compile() {
2592 if ! has "${EAPI:-0}" 0 1 2 || _python_package_supporting_installation_for_multiple_python_abis; then
2593 eerror "Use python_mod_optimize() instead of ${FUNCNAME}()."
2594 die "${FUNCNAME}() cannot be used in this EAPI"
2595 fi
2596
2597 _python_initialize_prefix_variables
2598 _python_set_color_variables
2599
2600 if [[ "${FUNCNAME[1]}" != "python_mod_optimize" ]]; then
2601 echo
2602 echo " ${_RED}*${_NORMAL} ${_RED}Deprecation Warning: ${FUNCNAME}() is deprecated and will be banned on 2010-09-01.${_NORMAL}"
2603 echo " ${_RED}*${_NORMAL} ${_RED}Use python_mod_optimize() instead of ${FUNCNAME}().${_NORMAL}"
2604 echo " ${_RED}*${_NORMAL} ${_RED}The ebuild needs to be fixed. Please report a bug, if it has not been already reported.${_NORMAL}"
2605 echo
2606
2607 einfo &> /dev/null
2608 einfo "Deprecation Warning: ${FUNCNAME}() is deprecated and will be banned on 2010-09-01." &> /dev/null
2609 einfo "Use python_mod_optimize() instead of ${FUNCNAME}()." &> /dev/null
2610 einfo "The ebuild needs to be fixed. Please report a bug, if it has not been already reported." &> /dev/null
2611 einfo &> /dev/null
2612 fi
2613
2614 local f myroot myfiles=()
2615
2616 # Check if phase is pkg_postinst()
2617 [[ "${EBUILD_PHASE}" != "postinst" ]] && die "${FUNCNAME}() can be used only in pkg_postinst() phase"
2618
2619 # strip trailing slash
2620 myroot="${EROOT%/}"
2621
2622 # respect EROOT
2623 for f in "$@"; do
2624 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
2625 done
2626
2627 PYTHON_ABI="$(PYTHON --ABI)"
2628
2629 if ((${#myfiles[@]})); then
2630 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}"
2631 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" &> /dev/null
2632 _python_clean_compiled_modules "${myfiles[@]}"
2633 else
2634 ewarn "No files to compile!"
2635 fi
2636 }

  ViewVC Help
Powered by ViewVC 1.1.20