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

Diff of /eclass/python.eclass

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

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

Legend:
Removed from v.1.48  
changed lines
  Added in v.1.84

  ViewVC Help
Powered by ViewVC 1.1.20