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