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

Diff of /eclass/python.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.54 Revision 1.83
1# Copyright 1999-2008 Gentoo Foundation 1# Copyright 1999-2010 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.54 2008/10/30 05:21:46 zmedico Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.83 2010/01/10 17:03:08 arfrever Exp $
4 4
5# @ECLASS: python.eclass 5# @ECLASS: python.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# python@gentoo.org 7# python@gentoo.org
8#
9# original author: Alastair Tse <liquidx@gentoo.org>
10# @BLURB: A Utility Eclass that should be inherited by anything that deals with Python or Python modules. 8# @BLURB: A utility eclass that should be inherited by anything that deals with Python or Python modules.
11# @DESCRIPTION: 9# @DESCRIPTION:
12# Some useful functions for dealing with python. 10# Some useful functions for dealing with Python.
13inherit alternatives multilib
14 11
12inherit multilib
15 13
14if ! has "${EAPI:-0}" 0 1 2; then
15 die "API of python.eclass in EAPI=\"${EAPI}\" not established"
16fi
17
16if [[ -n "${NEED_PYTHON}" ]] ; then 18if [[ -n "${NEED_PYTHON}" ]]; then
17 DEPEND=">=dev-lang/python-${NEED_PYTHON}" 19 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
20 DEPEND="${PYTHON_ATOM}"
18 RDEPEND="${DEPEND}" 21 RDEPEND="${DEPEND}"
22else
23 PYTHON_ATOM="dev-lang/python"
19fi 24fi
25
26DEPEND+=" >=app-admin/eselect-python-20090804"
20 27
21__python_eclass_test() { 28__python_eclass_test() {
22 __python_version_extract 2.3 29 __python_version_extract 2.3
23 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 30 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
24 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 31 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
52 59
53python_version() { 60python_version() {
54 [[ -n "${PYVER}" ]] && return 0 61 [[ -n "${PYVER}" ]] && return 0
55 local tmpstr 62 local tmpstr
56 python=${python:-/usr/bin/python} 63 python=${python:-/usr/bin/python}
57 tmpstr="$(${python} -V 2>&1 )" 64 tmpstr="$(EPYTHON= ${python} -V 2>&1 )"
58 export PYVER_ALL="${tmpstr#Python }" 65 export PYVER_ALL="${tmpstr#Python }"
59 __python_version_extract $PYVER_ALL 66 __python_version_extract $PYVER_ALL
60} 67}
61 68
69# @FUNCTION: PYTHON
70# @USAGE: [-2] [-3] [--ABI] [-A|--active] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
71# @DESCRIPTION:
72# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
73# is ommitted, then PYTHON_ABI environment variable must be set and is used.
74# If -2 option is specified, then active version of Python 2 is used.
75# If -3 option is specified, then active version of Python 3 is used.
76# If --active option is specified, then active version of Python is used.
77# Active version of Python can be set by python_set_active_version().
78# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
79# -2, -3, --active and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
80# If --ABI option is specified, then only specified Python ABI is printed instead of
81# Python interpreter filename.
82# --ABI and --absolute-path options cannot be specified simultaneously.
83PYTHON() {
84 local ABI_output="0" absolute_path_output="0" active="0" final_ABI="0" python2="0" python3="0" slot=
85
86 while (($#)); do
87 case "$1" in
88 -2)
89 python2="1"
90 ;;
91 -3)
92 python3="1"
93 ;;
94 --ABI)
95 ABI_output="1"
96 ;;
97 -A|--active)
98 active="1"
99 ;;
100 -a|--absolute-path)
101 absolute_path_output="1"
102 ;;
103 -f|--final-ABI)
104 final_ABI="1"
105 ;;
106 --)
107 break
108 ;;
109 -*)
110 die "${FUNCNAME}(): Unrecognized option '$1'"
111 ;;
112 *)
113 break
114 ;;
115 esac
116 shift
117 done
118
119 if [[ "${ABI_output}" == "1" && "${absolute_path_output}" == "1" ]]; then
120 die "${FUNCNAME}(): '--ABI and '--absolute-path' options cannot be specified simultaneously"
121 fi
122
123 if [[ "$((${python2} + ${python3} + ${active} + ${final_ABI}))" -gt 1 ]]; then
124 die "${FUNCNAME}(): '-2', '-3', '--active' or '--final-ABI' options cannot be specified simultaneously"
125 fi
126
127 if [[ "$#" -eq 0 ]]; then
128 if [[ "${active}" == "1" ]]; then
129 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
130 die "${FUNCNAME}(): '--active' option cannot be used in ebuilds of packages supporting installation for multiple versions of Python"
131 fi
132 slot="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
133 elif [[ "${final_ABI}" == "1" ]]; then
134 validate_PYTHON_ABIS
135 slot="${PYTHON_ABIS##* }"
136 elif [[ "${python2}" == "1" ]]; then
137 slot="$(eselect python show --python2)"
138 if [[ -z "${slot}" ]]; then
139 die "${FUNCNAME}(): Active Python 2 interpreter not set"
140 elif [[ "${slot}" != "python2."* ]]; then
141 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
142 fi
143 slot="${slot#python}"
144 elif [[ "${python3}" == "1" ]]; then
145 slot="$(eselect python show --python3)"
146 if [[ -z "${slot}" ]]; then
147 die "${FUNCNAME}(): Active Python 3 interpreter not set"
148 elif [[ "${slot}" != "python3."* ]]; then
149 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
150 fi
151 slot="${slot#python}"
152 elif [[ -n "${PYTHON_ABI}" ]]; then
153 slot="${PYTHON_ABI}"
154 else
155 die "${FUNCNAME}(): Invalid usage"
156 fi
157 elif [[ "$#" -eq 1 ]]; then
158 if [[ "${active}" == "1" ]]; then
159 die "${FUNCNAME}(): '--active' option and Python ABI cannot be specified simultaneously"
160 fi
161 if [[ "${final_ABI}" == "1" ]]; then
162 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
163 fi
164 if [[ "${python2}" == "1" ]]; then
165 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
166 fi
167 if [[ "${python3}" == "1" ]]; then
168 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
169 fi
170 slot="$1"
171 else
172 die "${FUNCNAME}(): Invalid usage"
173 fi
174
175 if [[ "${ABI_output}" == "1" ]]; then
176 echo -n "${slot}"
177 return
178 elif [[ "${absolute_path_output}" == "1" ]]; then
179 echo -n "/usr/bin/python${slot}"
180 else
181 echo -n "python${slot}"
182 fi
183
184 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
185 echo -n "-${ABI}"
186 fi
187}
188
189# @FUNCTION: python_set_active_version
190# @USAGE: <Python_ABI|2|3>
191# @DESCRIPTION:
192# Set active version of Python.
193python_set_active_version() {
194 if [[ "$#" -ne "1" ]]; then
195 die "${FUNCNAME}() requires 1 argument"
196 fi
197
198 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
199 if ! has_version "dev-lang/python:$1"; then
200 die "${FUNCNAME}(): 'dev-lang/python:$1' isn't installed"
201 fi
202 export EPYTHON="$(PYTHON "$1")"
203 elif [[ "$1" == "2" ]]; then
204 if ! has_version "=dev-lang/python-2*"; then
205 die "${FUNCNAME}(): '=dev-lang/python-2*' isn't installed"
206 fi
207 export EPYTHON="$(PYTHON -2)"
208 elif [[ "$1" == "3" ]]; then
209 if ! has_version "=dev-lang/python-3*"; then
210 die "${FUNCNAME}(): '=dev-lang/python-3*' isn't installed"
211 fi
212 export EPYTHON="$(PYTHON -3)"
213 else
214 die "${FUNCNAME}(): Unrecognized argument '$1'"
215 fi
216
217 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
218 # so it doesn't need to be exported to subprocesses.
219 PYTHON_ABI="${EPYTHON#python}"
220 PYTHON_ABI="${PYTHON_ABI%%-*}"
221}
222
223unset PYTHON_ABIS
224unset PYTHON_ABIS_SANITY_CHECKS
225
226# @FUNCTION: validate_PYTHON_ABIS
227# @DESCRIPTION:
228# Ensure that PYTHON_ABIS variable has valid value.
229validate_PYTHON_ABIS() {
230 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
231 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
232 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
233 fi
234
235 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
236 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
237 eerror "'/usr/bin/python' is not valid symlink."
238 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
239 die "'/usr/bin/python' is not valid symlink"
240 fi
241 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
242 eerror "'/usr/bin/python-config' is not valid script"
243 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
244 die "'/usr/bin/python-config' is not valid script"
245 fi
246
247 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 5.
248 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3 4; then
249 local PYTHON_ABI python2_supported_versions python3_supported_versions restricted_ABI support_ABI supported_PYTHON_ABIS=
250 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
251 python2_supported_versions="2.4 2.5 2.6 2.7"
252 python3_supported_versions="3.0 3.1 3.2"
253
254 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
255 local python2_enabled="0" python3_enabled="0"
256
257 if [[ -z "${USE_PYTHON}" ]]; then
258 die "USE_PYTHON variable is empty"
259 fi
260
261 for PYTHON_ABI in ${USE_PYTHON}; do
262 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
263 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
264 fi
265
266 if has "${PYTHON_ABI}" ${python2_supported_versions}; then
267 python2_enabled="1"
268 fi
269 if has "${PYTHON_ABI}" ${python3_supported_versions}; then
270 python3_enabled="1"
271 fi
272
273 support_ABI="1"
274 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
275 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
276 support_ABI="0"
277 break
278 fi
279 done
280 [[ "${support_ABI}" == "1" ]] && export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
281 done
282
283 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
284 die "USE_PYTHON variable doesn't enable any version of Python supported by ${CATEGORY}/${PF}"
285 fi
286
287 if [[ "${python2_enabled}" == "0" ]]; then
288 ewarn "USE_PYTHON variable doesn't enable any version of Python 2. This configuration is unsupported."
289 fi
290 if [[ "${python3_enabled}" == "0" ]]; then
291 ewarn "USE_PYTHON variable doesn't enable any version of Python 3. This configuration is unsupported."
292 fi
293 else
294 local python_version python2_version= python3_version= support_python_major_version
295
296 python_version="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
297
298 if has_version "=dev-lang/python-2*"; then
299 if [[ "$(readlink /usr/bin/python2)" != "python2."* ]]; then
300 die "'/usr/bin/python2' isn't valid symlink"
301 fi
302
303 python2_version="$(/usr/bin/python2 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
304
305 for PYTHON_ABI in ${python2_supported_versions}; do
306 support_python_major_version="1"
307 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
308 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
309 support_python_major_version="0"
310 fi
311 done
312 [[ "${support_python_major_version}" == "1" ]] && break
313 done
314 if [[ "${support_python_major_version}" == "1" ]]; then
315 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
316 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
317 die "Active version of Python 2 isn't supported by ${CATEGORY}/${PF}"
318 fi
319 done
320 else
321 python2_version=""
322 fi
323 fi
324
325 if has_version "=dev-lang/python-3*"; then
326 if [[ "$(readlink /usr/bin/python3)" != "python3."* ]]; then
327 die "'/usr/bin/python3' isn't valid symlink"
328 fi
329
330 python3_version="$(/usr/bin/python3 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
331
332 for PYTHON_ABI in ${python3_supported_versions}; do
333 support_python_major_version="1"
334 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
335 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
336 support_python_major_version="0"
337 fi
338 done
339 [[ "${support_python_major_version}" == "1" ]] && break
340 done
341 if [[ "${support_python_major_version}" == "1" ]]; then
342 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
343 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
344 die "Active version of Python 3 isn't supported by ${CATEGORY}/${PF}"
345 fi
346 done
347 else
348 python3_version=""
349 fi
350 fi
351
352 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
353 eerror "Python wrapper is configured incorrectly or /usr/bin/python2 symlink"
354 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
355 die "Incorrect configuration of Python"
356 fi
357 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
358 eerror "Python wrapper is configured incorrectly or /usr/bin/python3 symlink"
359 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
360 die "Incorrect configuration of Python"
361 fi
362
363 PYTHON_ABIS="${python2_version} ${python3_version}"
364 PYTHON_ABIS="${PYTHON_ABIS# }"
365 export PYTHON_ABIS="${PYTHON_ABIS% }"
366 fi
367 fi
368
369 if [[ "$(declare -p PYTHON_ABIS_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_ABIS_SANITY_CHECKS="* ]]; then
370 local PYTHON_ABI
371 for PYTHON_ABI in ${PYTHON_ABIS}; do
372 # Ensure that appropriate version of Python is installed.
373 if ! has_version "dev-lang/python:${PYTHON_ABI}"; then
374 die "dev-lang/python:${PYTHON_ABI} isn't installed"
375 fi
376
377 # Ensure that EPYTHON variable is respected.
378 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
379 eerror "python: '$(type -p python)'"
380 eerror "ABI: '${ABI}'"
381 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'"
382 eerror "EPYTHON: '$(PYTHON)'"
383 eerror "PYTHON_ABI: '${PYTHON_ABI}'"
384 eerror "Version of enabled Python: '$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')'"
385 die "'python' doesn't respect EPYTHON variable"
386 fi
387 done
388 PYTHON_ABIS_SANITY_CHECKS="1"
389 fi
390}
391
392# @FUNCTION: python_copy_sources
393# @USAGE: [--no-link] [--] [directory]
394# @DESCRIPTION:
395# Copy unpacked sources of given package for each Python ABI.
396python_copy_sources() {
397 local dir dirs=() no_link="0" PYTHON_ABI
398
399 while (($#)); do
400 case "$1" in
401 --no-link)
402 no_link="1"
403 ;;
404 --)
405 break
406 ;;
407 -*)
408 die "${FUNCNAME}(): Unrecognized option '$1'"
409 ;;
410 *)
411 break
412 ;;
413 esac
414 shift
415 done
416
417 if [[ "$#" -eq 0 ]]; then
418 if [[ "${WORKDIR}" == "${S}" ]]; then
419 die "${FUNCNAME}() cannot be used"
420 fi
421 dirs="${S}"
422 else
423 dirs="$@"
424 fi
425
426 validate_PYTHON_ABIS
427 for PYTHON_ABI in ${PYTHON_ABIS}; do
428 for dir in "${dirs[@]}"; do
429 if [[ "${no_link}" == "1" ]]; then
430 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
431 else
432 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
433 fi
434 done
435 done
436}
437
438# @FUNCTION: python_set_build_dir_symlink
439# @USAGE: [directory="build"]
440# @DESCRIPTION:
441# Create build directory symlink.
442python_set_build_dir_symlink() {
443 local dir="$1"
444
445 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
446 [[ -z "${dir}" ]] && dir="build"
447
448 # Don't delete preexistent directories.
449 rm -f "${dir}" || die "Deletion of '${dir}' failed"
450 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
451}
452
453# @FUNCTION: python_execute_function
454# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
455# @DESCRIPTION:
456# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
457# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
458python_execute_function() {
459 local action action_message action_message_template= default_function="0" failure_message failure_message_template= function nonfatal="0" previous_directory previous_directory_stack previous_directory_stack_length PYTHON_ABI quiet="0" separate_build_dirs="0" source_dir=
460
461 while (($#)); do
462 case "$1" in
463 --action-message)
464 action_message_template="$2"
465 shift
466 ;;
467 -d|--default-function)
468 default_function="1"
469 ;;
470 --failure-message)
471 failure_message_template="$2"
472 shift
473 ;;
474 --nonfatal)
475 nonfatal="1"
476 ;;
477 -q|--quiet)
478 quiet="1"
479 ;;
480 -s|--separate-build-dirs)
481 separate_build_dirs="1"
482 ;;
483 --source-dir)
484 source_dir="$2"
485 shift
486 ;;
487 --)
488 break
489 ;;
490 -*)
491 die "${FUNCNAME}(): Unrecognized option '$1'"
492 ;;
493 *)
494 break
495 ;;
496 esac
497 shift
498 done
499
500 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
501 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
502 fi
503
504 if [[ "${default_function}" == "0" ]]; then
505 if [[ "$#" -eq 0 ]]; then
506 die "${FUNCNAME}(): Missing function name"
507 fi
508 function="$1"
509 shift
510
511 if [[ -z "$(type -t "${function}")" ]]; then
512 die "${FUNCNAME}(): '${function}' function isn't defined"
513 fi
514 else
515 if [[ "$#" -ne "0" ]]; then
516 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
517 fi
518 if has "${EAPI:-0}" 0 1; then
519 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
520 fi
521
522 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
523 if has "${EAPI}" 2 3; then
524 python_default_function() {
525 econf
526 }
527 else
528 python_default_function() {
529 nonfatal econf
530 }
531 fi
532 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
533 python_default_function() {
534 emake
535 }
536 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
537 python_default_function() {
538 if emake -j1 -n check &> /dev/null; then
539 emake -j1 check
540 elif emake -j1 -n test &> /dev/null; then
541 emake -j1 test
542 fi
543 }
544 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
545 python_default_function() {
546 emake DESTDIR="${D}" install
547 }
548 else
549 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
550 fi
551 function="python_default_function"
552 fi
553
554 if [[ "${quiet}" == "0" ]]; then
555 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
556 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
557 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
558 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
559 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
560 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
561 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
562 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
563 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
564 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
565 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
566 fi
567
568 local RED GREEN BLUE NORMAL
569 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
570 RED=$'\e[1;31m'
571 GREEN=$'\e[1;32m'
572 BLUE=$'\e[1;34m'
573 NORMAL=$'\e[0m'
574 else
575 RED=
576 GREEN=
577 BLUE=
578 NORMAL=
579 fi
580
581 validate_PYTHON_ABIS
582 for PYTHON_ABI in ${PYTHON_ABIS}; do
583 if [[ "${quiet}" == "0" ]]; then
584 if [[ -n "${action_message_template}" ]]; then
585 action_message="$(eval echo -n "${action_message_template}")"
586 else
587 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
588 fi
589 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
590 fi
591
592 if [[ "${separate_build_dirs}" == "1" ]]; then
593 if [[ -n "${source_dir}" ]]; then
594 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
595 else
596 export BUILDDIR="${S}-${PYTHON_ABI}"
597 fi
598 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
599 else
600 export BUILDDIR="${S}"
601 fi
602
603 previous_directory="$(pwd)"
604 previous_directory_stack="$(dirs -p)"
605 previous_directory_stack_length="$(dirs -p | wc -l)"
606
607 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
608 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
609 else
610 EPYTHON="$(PYTHON)" "${function}" "$@"
611 fi
612
613 if [[ "$?" != "0" ]]; then
614 if [[ -n "${failure_message_template}" ]]; then
615 failure_message="$(eval echo -n "${failure_message_template}")"
616 else
617 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
618 fi
619
620 if [[ "${nonfatal}" == "1" ]]; then
621 if [[ "${quiet}" == "0" ]]; then
622 ewarn "${RED}${failure_message}${NORMAL}"
623 fi
624 elif has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
625 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
626 local enabled_PYTHON_ABIS= other_PYTHON_ABI
627 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
628 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
629 done
630 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
631 fi
632 if [[ "${quiet}" == "0" ]]; then
633 ewarn "${RED}${failure_message}${NORMAL}"
634 fi
635 if [[ -z "${PYTHON_ABIS}" ]]; then
636 die "${function}() function failed with all enabled versions of Python"
637 fi
638 else
639 die "${failure_message}"
640 fi
641 fi
642
643 # Ensure that directory stack hasn't been decreased.
644 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
645 die "Directory stack decreased illegally"
646 fi
647
648 # Avoid side effects of earlier returning from the specified function.
649 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
650 popd > /dev/null || die "popd failed"
651 done
652
653 # Ensure that the bottom part of directory stack hasn't been changed. Restore
654 # previous directory (from before running of the specified function) before
655 # comparison of directory stacks to avoid mismatch of directory stacks after
656 # potential using of 'cd' to change current directory. Restoration of previous
657 # directory allows to safely use 'cd' to change current directory in the
658 # specified function without changing it back to original directory.
659 cd "${previous_directory}"
660 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
661 die "Directory stack changed illegally"
662 fi
663
664 if [[ "${separate_build_dirs}" == "1" ]]; then
665 popd > /dev/null || die "popd failed"
666 fi
667 unset BUILDDIR
668 done
669
670 if [[ "${default_function}" == "1" ]]; then
671 unset -f python_default_function
672 fi
673}
674
675# @FUNCTION: python_convert_shebangs
676# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories]
677# @DESCRIPTION:
678# Convert shebangs in specified files. Directories can be specified only with --recursive option.
679python_convert_shebangs() {
680 local argument file files=() only_executables="0" python_version quiet="0" recursive="0"
681
682 while (($#)); do
683 case "$1" in
684 -r|--recursive)
685 recursive="1"
686 ;;
687 -q|--quiet)
688 quiet="1"
689 ;;
690 -x|--only-executables)
691 only_executables="1"
692 ;;
693 --)
694 break
695 ;;
696 -*)
697 die "${FUNCNAME}(): Unrecognized option '$1'"
698 ;;
699 *)
700 break
701 ;;
702 esac
703 shift
704 done
705
706 if [[ "$#" -eq 0 ]]; then
707 die "${FUNCNAME}(): Missing Python version and files or directories"
708 elif [[ "$#" -eq 1 ]]; then
709 die "${FUNCNAME}(): Missing files or directories"
710 fi
711
712 python_version="$1"
713 shift
714
715 for argument in "$@"; do
716 if [[ ! -e "${argument}" ]]; then
717 die "${FUNCNAME}(): '${argument}' doesn't exist"
718 elif [[ -f "${argument}" ]]; then
719 files+=("${argument}")
720 elif [[ -d "${argument}" ]]; then
721 if [[ "${recursive}" == "1" ]]; then
722 if [[ "${only_executables}" == "1" ]]; then
723 files+=($(find "${argument}" -perm /111 -type f))
724 else
725 files+=($(find "${argument}" -type f))
726 fi
727 else
728 die "${FUNCNAME}(): '${argument}' isn't a regular file"
729 fi
730 else
731 die "${FUNCNAME}(): '${argument}' isn't a regular file or a directory"
732 fi
733 done
734
735 for file in "${files[@]}"; do
736 file="${file#./}"
737 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
738
739 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then
740 if [[ "${quiet}" == "0" ]]; then
741 einfo "Converting shebang in '${file}'"
742 fi
743 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
744
745 # Delete potential whitespace after "#!".
746 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed"
747 fi
748 done
749}
750
751# @FUNCTION: python_generate_wrapper_scripts
752# @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
753# @DESCRIPTION:
754# Generate wrapper scripts. Existing files are overwritten only with --force option.
755# If --respect-EPYTHON option is specified, then generated wrapper scripts will
756# respect EPYTHON variable at run time.
757python_generate_wrapper_scripts() {
758 local eselect_python_option file force="0" quiet="0" PYTHON_ABI python2_enabled="0" python2_supported_versions python3_enabled="0" python3_supported_versions respect_EPYTHON="0"
759 python2_supported_versions="2.4 2.5 2.6 2.7"
760 python3_supported_versions="3.0 3.1 3.2"
761
762 while (($#)); do
763 case "$1" in
764 -E|--respect-EPYTHON)
765 respect_EPYTHON="1"
766 ;;
767 -f|--force)
768 force="1"
769 ;;
770 -q|--quiet)
771 quiet="1"
772 ;;
773 --)
774 break
775 ;;
776 -*)
777 die "${FUNCNAME}(): Unrecognized option '$1'"
778 ;;
779 *)
780 break
781 ;;
782 esac
783 shift
784 done
785
786 if [[ "$#" -eq 0 ]]; then
787 die "${FUNCNAME}(): Missing arguments"
788 fi
789
790 validate_PYTHON_ABIS
791 for PYTHON_ABI in ${python2_supported_versions}; do
792 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
793 python2_enabled="1"
794 fi
795 done
796 for PYTHON_ABI in ${python3_supported_versions}; do
797 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
798 python3_enabled="1"
799 fi
800 done
801
802 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
803 eselect_python_option=
804 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
805 eselect_python_option="--python2"
806 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
807 eselect_python_option="--python3"
808 else
809 die "${FUNCNAME}(): Unsupported environment"
810 fi
811
812 for file in "$@"; do
813 if [[ -f "${file}" && "${force}" == "0" ]]; then
814 die "${FUNCNAME}(): '$1' already exists"
815 fi
816
817 if [[ "${quiet}" == "0" ]]; then
818 einfo "Generating '${file#${D%/}}' wrapper script"
819 fi
820
821 cat << EOF > "${file}"
822#!/usr/bin/env python
823# Gentoo '${file##*/}' wrapper script
824
825import os
826import re
827import subprocess
828import sys
829
830EPYTHON_re = re.compile(r"^python(\d+\.\d+)$")
831
832EOF
833 if [[ "$?" != "0" ]]; then
834 die "${FUNCNAME}(): Generation of '$1' failed"
835 fi
836 if [[ "${respect_EPYTHON}" == "1" ]]; then
837 cat << EOF >> "${file}"
838EPYTHON = os.environ.get("EPYTHON")
839if EPYTHON:
840 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
841 if EPYTHON_matched:
842 PYTHON_ABI = EPYTHON_matched.group(1)
843 else:
844 sys.stderr.write("EPYTHON variable has unrecognized value '%s'\n" % EPYTHON)
845 sys.exit(1)
846else:
847 try:
848 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
849 if eselect_process.wait() != 0:
850 raise ValueError
851 except (OSError, ValueError):
852 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
853 sys.exit(1)
854
855 eselect_output = eselect_process.stdout.read()
856 if not isinstance(eselect_output, str):
857 # Python 3
858 eselect_output = eselect_output.decode()
859
860 EPYTHON_matched = EPYTHON_re.match(eselect_output)
861 if EPYTHON_matched:
862 PYTHON_ABI = EPYTHON_matched.group(1)
863 else:
864 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
865 sys.exit(1)
866EOF
867 if [[ "$?" != "0" ]]; then
868 die "${FUNCNAME}(): Generation of '$1' failed"
869 fi
870 else
871 cat << EOF >> "${file}"
872try:
873 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
874 if eselect_process.wait() != 0:
875 raise ValueError
876except (OSError, ValueError):
877 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
878 sys.exit(1)
879
880eselect_output = eselect_process.stdout.read()
881if not isinstance(eselect_output, str):
882 # Python 3
883 eselect_output = eselect_output.decode()
884
885EPYTHON_matched = EPYTHON_re.match(eselect_output)
886if EPYTHON_matched:
887 PYTHON_ABI = EPYTHON_matched.group(1)
888else:
889 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
890 sys.exit(1)
891EOF
892 if [[ "$?" != "0" ]]; then
893 die "${FUNCNAME}(): Generation of '$1' failed"
894 fi
895 fi
896 cat << EOF >> "${file}"
897
898os.environ["PYTHON_PROCESS_NAME"] = sys.argv[0]
899target_executable = "%s-%s" % (os.path.realpath(sys.argv[0]), PYTHON_ABI)
900if not os.path.exists(target_executable):
901 sys.stderr.write("'%s' does not exist\n" % target_executable)
902 sys.exit(1)
903
904os.execv(target_executable, sys.argv)
905EOF
906 if [[ "$?" != "0" ]]; then
907 die "${FUNCNAME}(): Generation of '$1' failed"
908 fi
909 fperms +x "${file#${D%/}}" || die "fperms '${file}' failed"
910 done
911}
912
913# @ECLASS-VARIABLE: PYTHON_USE_WITH
914# @DESCRIPTION:
915# Set this to a space separated list of use flags
916# the python slot in use must be built with.
917
918# @ECLASS-VARIABLE: PYTHON_USE_WITH_OR
919# @DESCRIPTION:
920# Set this to a space separated list of use flags
921# of which one must be turned on for the slot of
922# in use.
923
924# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
925# @DESCRIPTION:
926# Set this if you need to make either PYTHON_USE_WITH or
927# PYTHON_USE_WITH_OR atoms conditional under a use flag.
928
929# @FUNCTION: python_pkg_setup
930# @DESCRIPTION:
931# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
932# are respected. Only exported if one of those variables is set.
933if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
934 python_pkg_setup() {
935 python_pkg_setup_fail() {
936 eerror "${1}"
937 die "${1}"
938 }
939
940 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
941
942 python_pkg_setup_check_USE_flags() {
943 local pyatom use
944 if [[ -n "${PYTHON_ABI}" ]]; then
945 pyatom="dev-lang/python:${PYTHON_ABI}"
946 else
947 pyatom="dev-lang/python:$(PYTHON -A --ABI)"
948 fi
949
950 for use in ${PYTHON_USE_WITH}; do
951 if ! has_version "${pyatom}[${use}]"; then
952 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
953 fi
954 done
955
956 for use in ${PYTHON_USE_WITH_OR}; do
957 if has_version "${pyatom}[${use}]"; then
958 return
959 fi
960 done
961
962 if [[ ${PYTHON_USE_WITH_OR} ]]; then
963 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
964 fi
965 }
966
967 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
968 python_execute_function -q python_pkg_setup_check_USE_flags
969 else
970 python_pkg_setup_check_USE_flags
971 fi
972 }
973
974 EXPORT_FUNCTIONS pkg_setup
975
976 if [[ -n "${PYTHON_USE_WITH}" ]]; then
977 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
978 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
979 PYTHON_USE_WITH_ATOM="|| ( "
980 for use in ${PYTHON_USE_WITH_OR}; do
981 PYTHON_USE_WITH_ATOM+=" ${PYTHON_ATOM}[${use}]"
982 done
983 unset use
984 PYTHON_USE_WITH_ATOM+=" )"
985 fi
986 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
987 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
988 fi
989 DEPEND+=" ${PYTHON_USE_WITH_ATOM}"
990 RDEPEND+=" ${PYTHON_USE_WITH_ATOM}"
991fi
992
993# @ECLASS-VARIABLE: PYTHON_DEFINE_DEFAULT_FUNCTIONS
994# @DESCRIPTION:
995# Set this to define default functions for the following ebuild phases:
996# src_prepare, src_configure, src_compile, src_test, src_install.
997if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_DEFINE_DEFAULT_FUNCTIONS}" ]]; then
998 python_src_prepare() {
999 python_copy_sources
1000 }
1001
1002 for python_default_function in src_configure src_compile src_test src_install; do
1003 eval "python_${python_default_function}() { python_execute_function -d -s; }"
1004 done
1005 unset python_default_function
1006
1007 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
1008fi
1009
62# @FUNCTION: python_disable_pyc 1010# @FUNCTION: python_disable_pyc
63# @DESCRIPTION: 1011# @DESCRIPTION:
64# Tells python not to automatically recompile modules to .pyc/.pyo 1012# Tell Python not to automatically recompile modules to .pyc/.pyo
65# even if the timestamps/version stamps don't match. This is done 1013# even if the timestamps/version stamps don't match. This is done
66# to protect sandbox. 1014# to protect sandbox.
67#
68# note: supported by >=dev-lang/python-2.2.3-r3 only.
69#
70python_disable_pyc() { 1015python_disable_pyc() {
71 export PYTHONDONTWRITEBYTECODE=1 # For 2.6 and above 1016 export PYTHONDONTWRITEBYTECODE="1"
72 export PYTHON_DONTCOMPILE=1 # For 2.5 and below
73} 1017}
74 1018
75# @FUNCTION: python_enable_pyc 1019# @FUNCTION: python_enable_pyc
76# @DESCRIPTION: 1020# @DESCRIPTION:
77# Tells python to automatically recompile modules to .pyc/.pyo if the 1021# Tell Python to automatically recompile modules to .pyc/.pyo if the
78# timestamps/version stamps change 1022# timestamps/version stamps have changed.
79python_enable_pyc() { 1023python_enable_pyc() {
80 unset PYTHONDONTWRITEBYTECODE 1024 unset PYTHONDONTWRITEBYTECODE
81 unset PYTHON_DONTCOMPILE
82} 1025}
83
84python_disable_pyc
85 1026
86# @FUNCTION: python_need_rebuild 1027# @FUNCTION: python_need_rebuild
87# @DESCRIPTION: Run without arguments, specifies that the package should be 1028# @DESCRIPTION: Run without arguments, specifies that the package should be
88# rebuilt after a python upgrade. 1029# rebuilt after a python upgrade.
89python_need_rebuild() { 1030python_need_rebuild() {
90 python_version 1031 export PYTHON_NEED_REBUILD="$(PYTHON -A --ABI)"
91 export PYTHON_NEED_REBUILD=${PYVER} 1032}
1033
1034# @FUNCTION: python_get_includedir
1035# @DESCRIPTION:
1036# Run without arguments, returns the Python include directory.
1037python_get_includedir() {
1038 if [[ -n "${PYTHON_ABI}" ]]; then
1039 echo "/usr/include/python${PYTHON_ABI}"
1040 else
1041 echo "/usr/include/python$(PYTHON -A --ABI)"
1042 fi
92} 1043}
93 1044
94# @FUNCTION: python_get_libdir 1045# @FUNCTION: python_get_libdir
95# @DESCRIPTION: 1046# @DESCRIPTION:
96# Run without arguments, returns the python library dir 1047# Run without arguments, returns the Python library directory.
97python_get_libdir() { 1048python_get_libdir() {
98 python_version 1049 if [[ -n "${PYTHON_ABI}" ]]; then
99 echo "/usr/$(get_libdir)/python${PYVER}" 1050 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
1051 else
1052 echo "/usr/$(get_libdir)/python$(PYTHON -A --ABI)"
1053 fi
100} 1054}
101 1055
102# @FUNCTION: python_get_sitedir 1056# @FUNCTION: python_get_sitedir
103# @DESCRIPTION: 1057# @DESCRIPTION:
104# Run without arguments, returns the python site-packages dir 1058# Run without arguments, returns the Python site-packages directory.
105python_get_sitedir() { 1059python_get_sitedir() {
106 echo "$(python_get_libdir)/site-packages" 1060 echo "$(python_get_libdir)/site-packages"
107}
108
109# @FUNCTION: python_makesym
110# @DESCRIPTION:
111# Run without arguments, it will create the /usr/bin/python symlinks
112# to the latest installed version
113python_makesym() {
114 alternatives_auto_makesym "/usr/bin/python" "python[0-9].[0-9]"
115 alternatives_auto_makesym "/usr/bin/python2" "python2.[0-9]"
116} 1061}
117 1062
118# @FUNCTION: python_tkinter_exists 1063# @FUNCTION: python_tkinter_exists
119# @DESCRIPTION: 1064# @DESCRIPTION:
120# Run without arguments, checks if python was compiled with Tkinter 1065# Run without arguments, checks if python was compiled with Tkinter
128 die "missing tkinter support with installed python" 1073 die "missing tkinter support with installed python"
129 fi 1074 fi
130} 1075}
131 1076
132# @FUNCTION: python_mod_exists 1077# @FUNCTION: python_mod_exists
133# @USAGE: < module > 1078# @USAGE: <module>
134# @DESCRIPTION: 1079# @DESCRIPTION:
135# Run with the module name as an argument. it will check if a 1080# Run with the module name as an argument. it will check if a
136# python module is installed and loadable. it will return 1081# python module is installed and loadable. it will return
137# TRUE(0) if the module exists, and FALSE(1) if the module does 1082# TRUE(0) if the module exists, and FALSE(1) if the module does
138# not exist. 1083# not exist.
141# if python_mod_exists gtk; then 1086# if python_mod_exists gtk; then
142# echo "gtk support enabled" 1087# echo "gtk support enabled"
143# fi 1088# fi
144python_mod_exists() { 1089python_mod_exists() {
145 [[ "$1" ]] || die "${FUNCNAME} requires an argument!" 1090 [[ "$1" ]] || die "${FUNCNAME} requires an argument!"
146 python -c "import $1" >/dev/null 2>&1 1091 python -c "import $1" &>/dev/null
147} 1092}
148 1093
149# @FUNCTION: python_mod_compile 1094# @FUNCTION: python_mod_compile
150# @USAGE: < file > [more files ...] 1095# @USAGE: <file> [more files ...]
151# @DESCRIPTION: 1096# @DESCRIPTION:
152# Given filenames, it will pre-compile the module's .pyc and .pyo. 1097# Given filenames, it will pre-compile the module's .pyc and .pyo.
153# This function should only be run in pkg_postinst() 1098# This function should only be run in pkg_postinst()
154# 1099#
155# Example: 1100# Example:
156# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py 1101# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
157# 1102#
158python_mod_compile() { 1103python_mod_compile() {
1104 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
1105 die "${FUNCNAME}() cannot be used in this EAPI"
1106 fi
1107
159 local f myroot myfiles=() 1108 local f myroot myfiles=()
160 1109
161 # Check if phase is pkg_postinst() 1110 # Check if phase is pkg_postinst()
162 [[ ${EBUILD_PHASE} != postinst ]] &&\ 1111 [[ ${EBUILD_PHASE} != postinst ]] &&\
163 die "${FUNCNAME} should only be run in pkg_postinst()" 1112 die "${FUNCNAME} should only be run in pkg_postinst()"
164 1113
165 # allow compiling for older python versions
166 if [[ "${PYTHON_OVERRIDE_PYVER}" ]]; then
167 PYVER=${PYTHON_OVERRIDE_PYVER}
168 else
169 python_version
170 fi
171
172 # strip trailing slash 1114 # strip trailing slash
173 myroot="${ROOT%/}" 1115 myroot="${ROOT%/}"
174 1116
175 # respect ROOT 1117 # respect ROOT
176 for f in "$@"; do 1118 for f in "$@"; do
177 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}") 1119 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
178 done 1120 done
179 1121
180 if ((${#myfiles[@]})); then 1122 if ((${#myfiles[@]})); then
181 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1123 "$(PYTHON -A)" "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}"
182 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1124 "$(PYTHON -A)" -O "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" &> /dev/null
183 else 1125 else
184 ewarn "No files to compile!" 1126 ewarn "No files to compile!"
185 fi 1127 fi
186} 1128}
187 1129
188# @FUNCTION: python_mod_optimize 1130# @FUNCTION: python_mod_optimize
189# @USAGE: [ path ] 1131# @USAGE: [options] [directory|file]
190# @DESCRIPTION: 1132# @DESCRIPTION:
191# If no arguments supplied, it will recompile all modules under 1133# If no arguments supplied, it will recompile not recursively all modules
192# sys.path (eg. /usr/lib/python2.3, /usr/lib/python2.3/site-packages/ ..) 1134# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
193# no recursively
194# 1135#
195# If supplied with arguments, it will recompile all modules recursively 1136# If supplied with arguments, it will recompile all modules recursively
196# in the supplied directory 1137# in the supplied directory.
197# This function should only be run in pkg_postinst() 1138# This function should only be run in pkg_postinst().
198# 1139#
199# Options passed to this function are passed to compileall.py 1140# Options passed to this function are passed to compileall.py.
200# 1141#
201# Example: 1142# Example:
202# python_mod_optimize /usr/share/codegen 1143# python_mod_optimize ctypesgencore
203python_mod_optimize() { 1144python_mod_optimize() {
204 local myroot mydirs=() myfiles=() myopts=()
205
206 # Check if phase is pkg_postinst() 1145 # Check if phase is pkg_postinst().
207 [[ ${EBUILD_PHASE} != postinst ]] &&\ 1146 [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME} should only be run in pkg_postinst()"
208 die "${FUNCNAME} should only be run in pkg_postinst()"
209 1147
1148 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
1149 local dir file options=() other_dirs=() other_files=() PYTHON_ABI return_code root site_packages_absolute_dirs=() site_packages_dirs=() site_packages_absolute_files=() site_packages_files=()
1150
1151 # Strip trailing slash from ROOT.
1152 root="${ROOT%/}"
1153
1154 # Respect ROOT and options passed to compileall.py.
1155 while (($#)); do
1156 case "$1" in
1157 -l|-f|-q)
1158 options+=("$1")
1159 ;;
1160 -d|-x)
1161 options+=("$1" "$2")
1162 shift
1163 ;;
1164 -*)
1165 ewarn "${FUNCNAME}: Ignoring compile option $1"
1166 ;;
1167 *)
1168 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
1169 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
1170 elif [[ "$1" =~ ^/ ]]; then
1171 if [[ -d "${root}/$1" ]]; then
1172 other_dirs+=("${root}/$1")
1173 elif [[ -f "${root}/$1" ]]; then
1174 other_files+=("${root}/$1")
1175 elif [[ -e "${root}/$1" ]]; then
1176 ewarn "'${root}/$1' is not a file or a directory!"
1177 else
1178 ewarn "'${root}/$1' doesn't exist!"
1179 fi
1180 else
1181 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
1182 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
1183 site_packages_dirs+=("$1")
1184 break
1185 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
1186 site_packages_files+=("$1")
1187 break
1188 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
1189 ewarn "'$1' is not a file or a directory!"
1190 else
1191 ewarn "'$1' doesn't exist!"
1192 fi
1193 done
1194 fi
1195 ;;
1196 esac
1197 shift
1198 done
1199
1200 # Set additional options.
1201 options+=("-q")
1202
1203 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
1204 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
1205 return_code="0"
1206 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
1207 if ((${#site_packages_dirs[@]})); then
1208 for dir in "${site_packages_dirs[@]}"; do
1209 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
1210 done
1211 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
1212 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
1213 fi
1214 if ((${#site_packages_files[@]})); then
1215 for file in "${site_packages_files[@]}"; do
1216 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
1217 done
1218 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
1219 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
1220 fi
1221 eend "${return_code}"
1222 fi
1223 unset site_packages_absolute_dirs site_packages_absolute_files
1224 done
1225
1226 # Don't use PYTHON_ABI in next calls to python_get_libdir().
1227 unset PYTHON_ABI
1228
1229 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
1230 return_code="0"
1231 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python $(PYTHON -A --ABI)"
1232 if ((${#other_dirs[@]})); then
1233 "$(PYTHON -A)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
1234 "$(PYTHON -A)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
1235 fi
1236 if ((${#other_files[@]})); then
1237 "$(PYTHON -A)" "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
1238 "$(PYTHON -A)" -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
1239 fi
1240 eend "${return_code}"
1241 fi
1242 else
1243 local myroot mydirs=() myfiles=() myopts=() return_code="0"
1244
210 # strip trailing slash 1245 # strip trailing slash
211 myroot="${ROOT%/}" 1246 myroot="${ROOT%/}"
212 1247
213 # respect ROOT and options passed to compileall.py 1248 # respect ROOT and options passed to compileall.py
214 while (($#)); do 1249 while (($#)); do
215 case $1 in 1250 case "$1" in
216 -l|-f|-q) 1251 -l|-f|-q)
217 myopts+=("$1") 1252 myopts+=("$1")
218 ;; 1253 ;;
219 -d|-x) 1254 -d|-x)
220 myopts+=("$1" "$2") 1255 myopts+=("$1" "$2")
1256 shift
1257 ;;
1258 -*)
1259 ewarn "${FUNCNAME}: Ignoring compile option $1"
1260 ;;
1261 *)
1262 if [[ -d "${myroot}"/$1 ]]; then
1263 mydirs+=("${myroot}/$1")
1264 elif [[ -f "${myroot}"/$1 ]]; then
1265 # Files are passed to python_mod_compile which is ROOT-aware
1266 myfiles+=("$1")
1267 elif [[ -e "${myroot}/$1" ]]; then
1268 ewarn "${myroot}/$1 is not a file or directory!"
1269 else
1270 ewarn "${myroot}/$1 doesn't exist!"
1271 fi
1272 ;;
1273 esac
1274 shift
1275 done
1276
1277 # set additional opts
1278 myopts+=(-q)
1279
1280 ebegin "Compilation and optimization of Python modules for Python $(PYTHON -A --ABI)"
1281 if ((${#mydirs[@]})); then
1282 "$(PYTHON -A)" "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" || return_code="1"
1283 "$(PYTHON -A)" -O "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
1284 fi
1285
1286 if ((${#myfiles[@]})); then
1287 python_mod_compile "${myfiles[@]}"
1288 fi
1289
1290 eend "${return_code}"
1291 fi
1292}
1293
1294# @FUNCTION: python_mod_cleanup
1295# @USAGE: [directory|file]
1296# @DESCRIPTION:
1297# Run with optional arguments, where arguments are Python modules. If none given,
1298# it will look in /usr/lib/python[0-9].[0-9].
1299#
1300# It will recursively scan all compiled Python modules in the directories and
1301# determine if they are orphaned (i.e. their corresponding .py files are missing.)
1302# If they are, then it will remove their corresponding .pyc and .pyo files.
1303#
1304# This function should only be run in pkg_postrm().
1305python_mod_cleanup() {
1306 local path py_file PYTHON_ABI SEARCH_PATH=() root
1307
1308 # Check if phase is pkg_postrm().
1309 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
1310
1311 # Strip trailing slash from ROOT.
1312 root="${ROOT%/}"
1313
1314 if (($#)); then
1315 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
1316 while (($#)); do
1317 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
1318 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
1319 elif [[ "$1" =~ ^/ ]]; then
1320 SEARCH_PATH+=("${root}/${1#/}")
1321 else
1322 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI-$(PYTHON -A --ABI)}}; do
1323 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
1324 done
1325 fi
221 shift 1326 shift
222 ;; 1327 done
223 -*)
224 ewarn "${FUNCNAME}: Ignoring compile option $1"
225 ;;
226 *)
227 if [[ -d "${myroot}"/$1 ]]; then
228 mydirs+=("${myroot}/$1")
229 elif [[ -f "${myroot}"/$1 ]]; then
230 # Files are passed to python_mod_compile which is ROOT-aware
231 myfiles+=("$1")
232 elif [[ -e "${myroot}/$1" ]]; then
233 ewarn "${myroot}/$1 is not a file or directory!"
234 else 1328 else
235 ewarn "${myroot}/$1 doesn't exist!" 1329 SEARCH_PATH=("${@#/}")
1330 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
236 fi 1331 fi
237 ;;
238 esac
239 shift
240 done
241
242 # allow compiling for older python versions
243 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
244 PYVER=${PYTHON_OVERRIDE_PYVER}
245 else 1332 else
246 python_version 1333 local dir sitedir
1334 for dir in "${root}"/usr/lib*; do
1335 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
1336 for sitedir in "${dir}"/python*/site-packages; do
1337 if [[ -d "${sitedir}" ]]; then
1338 SEARCH_PATH+=("${sitedir}")
1339 fi
1340 done
247 fi 1341 fi
248 1342 done
249 # set additional opts
250 myopts+=(-q)
251
252 ebegin "Byte compiling python modules for python-${PYVER} .."
253 if ((${#mydirs[@]})); then
254 python${PYVER} \
255 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
256 "${myopts[@]}" "${mydirs[@]}"
257 python${PYVER} -O \
258 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
259 "${myopts[@]}" "${mydirs[@]}"
260 fi 1343 fi
261 1344
262 if ((${#myfiles[@]})); then 1345 local BLUE CYAN NORMAL
263 python_mod_compile "${myfiles[@]}" 1346 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
264 fi 1347 BLUE=$'\e[1;34m'
265 1348 CYAN=$'\e[1;36m'
266 eend $? 1349 NORMAL=$'\e[0m'
267}
268
269# @FUNCTION: python_mod_cleanup
270# @USAGE: [ dir ]
271# @DESCRIPTION:
272# Run with optional arguments, where arguments are directories of
273# python modules. if none given, it will look in /usr/lib/python[0-9].[0-9]
274#
275# It will recursively scan all compiled python modules in the directories
276# and determine if they are orphaned (eg. their corresponding .py is missing.)
277# if they are, then it will remove their corresponding .pyc and .pyo
278#
279# This function should only be run in pkg_postrm()
280python_mod_cleanup() {
281 local SEARCH_PATH=() myroot src_py
282
283 # Check if phase is pkg_postrm()
284 [[ ${EBUILD_PHASE} != postrm ]] &&\
285 die "${FUNCNAME} should only be run in pkg_postrm()"
286
287 # strip trailing slash
288 myroot="${ROOT%/}"
289
290 if (($#)); then
291 SEARCH_PATH=("${@#/}")
292 SEARCH_PATH=("${SEARCH_PATH[@]/#/$myroot/}")
293 else 1350 else
294 SEARCH_PATH=("${myroot}"/usr/lib*/python*/site-packages) 1351 BLUE=
1352 CYAN=
1353 NORMAL=
295 fi 1354 fi
296 1355
297 for path in "${SEARCH_PATH[@]}"; do 1356 for path in "${SEARCH_PATH[@]}"; do
298 einfo "Cleaning orphaned Python bytecode from ${path} .." 1357 if [[ -d "${path}" ]]; then
299 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do 1358 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
300 src_py="${REPLY%[co]}" 1359 py_file="${REPLY%[co]}"
301 [[ -f "${src_py}" ]] && continue 1360 [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue
302 einfo "Purging ${src_py}[co]" 1361 einfo "${BLUE}<<< ${py_file}[co]${NORMAL}"
303 rm -f "${src_py}"[co] 1362 rm -f "${py_file}"[co]
304 done 1363 done
305 1364
306 # attempt to remove directories that maybe empty 1365 # Attempt to delete directories, which may be empty.
307 find "${path}" -type d | sort -r | while read -r dir; do 1366 find "${path}" -type d | sort -r | while read -r dir; do
308 rmdir "${dir}" 2>/dev/null 1367 rmdir "${dir}" 2>/dev/null && einfo "${CYAN}<<< ${dir}${NORMAL}"
309 done 1368 done
1369 elif [[ "${path}" == *.py && ! -f "${path}" && (-f "${path}c" || -f "${path}o") ]]; then
1370 einfo "${BLUE}<<< ${path}[co]${NORMAL}"
1371 rm -f "${path}"[co]
1372 fi
310 done 1373 done
311} 1374}

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.83

  ViewVC Help
Powered by ViewVC 1.1.20