/[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.78
1# Copyright 1999-2008 Gentoo Foundation 1# Copyright 1999-2009 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.78 2009/11/15 14:25:55 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
16if [[ -n "${NEED_PYTHON}" ]] ; then 14if [[ -n "${NEED_PYTHON}" ]]; then
17 DEPEND=">=dev-lang/python-${NEED_PYTHON}" 15 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
16 DEPEND="${PYTHON_ATOM}"
18 RDEPEND="${DEPEND}" 17 RDEPEND="${DEPEND}"
18else
19 PYTHON_ATOM="dev-lang/python"
19fi 20fi
21
22DEPEND+=" >=app-admin/eselect-python-20090804
23 >=app-shells/bash-3.2"
20 24
21__python_eclass_test() { 25__python_eclass_test() {
22 __python_version_extract 2.3 26 __python_version_extract 2.3
23 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 27 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
24 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 28 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
57 tmpstr="$(${python} -V 2>&1 )" 61 tmpstr="$(${python} -V 2>&1 )"
58 export PYVER_ALL="${tmpstr#Python }" 62 export PYVER_ALL="${tmpstr#Python }"
59 __python_version_extract $PYVER_ALL 63 __python_version_extract $PYVER_ALL
60} 64}
61 65
66# @FUNCTION: PYTHON
67# @USAGE: [-a|--absolute-path] [--] <Python_ABI="${PYTHON_ABI}">
68# @DESCRIPTION:
69# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
70# is ommitted, then PYTHON_ABI environment variable must be set and is used.
71PYTHON() {
72 local absolute_path="0" slot=
73
74 while (($#)); do
75 case "$1" in
76 -a|--absolute-path)
77 absolute_path="1"
78 ;;
79 --)
80 break
81 ;;
82 -*)
83 die "${FUNCNAME}(): Unrecognized option $1"
84 ;;
85 *)
86 break
87 ;;
88 esac
89 shift
90 done
91
92 if [[ "$#" -eq "0" ]]; then
93 if [[ -n "${PYTHON_ABI}" ]]; then
94 slot="${PYTHON_ABI}"
95 else
96 die "${FUNCNAME}(): Invalid usage"
97 fi
98 elif [[ "$#" -eq "1" ]]; then
99 slot="$1"
100 else
101 die "${FUNCNAME}(): Invalid usage"
102 fi
103
104 if [[ "${absolute_path}" == "1" ]]; then
105 echo -n "/usr/bin/python${slot}"
106 else
107 echo -n "python${slot}"
108 fi
109
110 if [[ "${ABI}" != "${DEFAULT_ABI}" ]]; then
111 echo -n "-${ABI}"
112 fi
113}
114
115unset PYTHON_ABIS
116unset PYTHON_ABIS_SANITY_CHECKS
117
118# @FUNCTION: validate_PYTHON_ABIS
119# @DESCRIPTION:
120# Ensure that PYTHON_ABIS variable has valid value.
121validate_PYTHON_ABIS() {
122 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
123 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
124 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
125 fi
126
127 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
128 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
129 die "'/usr/bin/python' isn't valid symlink"
130 fi
131 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
132 die "'/usr/bin/python-config' isn't valid script"
133 fi
134
135 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4.
136 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3; then
137 local PYTHON_ABI python2_supported_versions python3_supported_versions restricted_ABI support_ABI supported_PYTHON_ABIS=
138 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
139 python2_supported_versions="2.4 2.5 2.6 2.7"
140 python3_supported_versions="3.0 3.1 3.2"
141
142 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
143 local python2_enabled="0" python3_enabled="0"
144
145 if [[ -z "${USE_PYTHON}" ]]; then
146 die "USE_PYTHON variable is empty"
147 fi
148
149 for PYTHON_ABI in ${USE_PYTHON}; do
150 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
151 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
152 fi
153
154 if has "${PYTHON_ABI}" ${python2_supported_versions}; then
155 python2_enabled="1"
156 fi
157 if has "${PYTHON_ABI}" ${python3_supported_versions}; then
158 python3_enabled="1"
159 fi
160
161 support_ABI="1"
162 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
163 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
164 support_ABI="0"
165 break
166 fi
167 done
168 [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${PYTHON_ABI}"
169 done
170 export PYTHON_ABIS="${supported_PYTHON_ABIS# }"
171
172 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
173 die "USE_PYTHON variable doesn't enable any version of Python supported by ${CATEGORY}/${PF}"
174 fi
175
176 if [[ "${python2_enabled}" == "0" ]]; then
177 ewarn "USE_PYTHON variable doesn't enable any version of Python 2. This configuration is unsupported."
178 fi
179 if [[ "${python3_enabled}" == "0" ]]; then
180 ewarn "USE_PYTHON variable doesn't enable any version of Python 3. This configuration is unsupported."
181 fi
182 else
183 local python_version python2_version= python3_version= support_python_major_version
184
185 python_version="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
186
187 if has_version "=dev-lang/python-2*"; then
188 if [[ "$(readlink /usr/bin/python2)" != "python2."* ]]; then
189 die "'/usr/bin/python2' isn't valid symlink"
190 fi
191
192 python2_version="$(/usr/bin/python2 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
193
194 for PYTHON_ABI in ${python2_supported_versions}; do
195 support_python_major_version="1"
196 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
197 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
198 support_python_major_version="0"
199 fi
200 done
201 [[ "${support_python_major_version}" == "1" ]] && break
202 done
203 if [[ "${support_python_major_version}" == "1" ]]; then
204 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
205 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
206 die "Active version of Python 2 isn't supported by ${CATEGORY}/${PF}"
207 fi
208 done
209 else
210 python2_version=""
211 fi
212 fi
213
214 if has_version "=dev-lang/python-3*"; then
215 if [[ "$(readlink /usr/bin/python3)" != "python3."* ]]; then
216 die "'/usr/bin/python3' isn't valid symlink"
217 fi
218
219 python3_version="$(/usr/bin/python3 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
220
221 for PYTHON_ABI in ${python3_supported_versions}; do
222 support_python_major_version="1"
223 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
224 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
225 support_python_major_version="0"
226 fi
227 done
228 [[ "${support_python_major_version}" == "1" ]] && break
229 done
230 if [[ "${support_python_major_version}" == "1" ]]; then
231 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
232 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
233 die "Active version of Python 3 isn't supported by ${CATEGORY}/${PF}"
234 fi
235 done
236 else
237 python3_version=""
238 fi
239 fi
240
241 if ! has "${python_version}" "${python2_version}" "${python3_version}"; then
242 eerror "Python wrapper is configured incorrectly or /usr/bin/python2 or /usr/bin/python3 symlink"
243 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
244 die "Incorrect configuration of Python"
245 fi
246
247 PYTHON_ABIS="${python2_version} ${python3_version}"
248 PYTHON_ABIS="${PYTHON_ABIS# }"
249 export PYTHON_ABIS="${PYTHON_ABIS% }"
250 fi
251 fi
252
253 if [[ "$(declare -p PYTHON_ABIS_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_ABIS_SANITY_CHECKS="* ]]; then
254 local PYTHON_ABI
255 for PYTHON_ABI in ${PYTHON_ABIS}; do
256 # Ensure that appropriate Python version is installed.
257 if ! has_version "dev-lang/python:${PYTHON_ABI}"; then
258 die "dev-lang/python:${PYTHON_ABI} isn't installed"
259 fi
260
261 # Ensure that EPYTHON variable is respected.
262 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
263 die "'python' doesn't respect EPYTHON variable"
264 fi
265 done
266 PYTHON_ABIS_SANITY_CHECKS="1"
267 fi
268}
269
270# @FUNCTION: python_copy_sources
271# @USAGE: [--no-link] [--] [directory]
272# @DESCRIPTION:
273# Copy unpacked sources of given package for each Python ABI.
274python_copy_sources() {
275 local dir dirs=() no_link="0" PYTHON_ABI
276
277 while (($#)); do
278 case "$1" in
279 --no-link)
280 no_link="1"
281 ;;
282 --)
283 break
284 ;;
285 -*)
286 die "${FUNCNAME}(): Unrecognized option '$1'"
287 ;;
288 *)
289 break
290 ;;
291 esac
292 shift
293 done
294
295 if [[ "$#" -eq "0" ]]; then
296 if [[ "${WORKDIR}" == "${S}" ]]; then
297 die "${FUNCNAME}() cannot be used"
298 fi
299 dirs="${S}"
300 else
301 dirs="$@"
302 fi
303
304 validate_PYTHON_ABIS
305 for PYTHON_ABI in ${PYTHON_ABIS}; do
306 for dir in "${dirs[@]}"; do
307 if [[ "${no_link}" == "1" ]]; then
308 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
309 else
310 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
311 fi
312 done
313 done
314}
315
316# @FUNCTION: python_set_build_dir_symlink
317# @USAGE: [directory="build"]
318# @DESCRIPTION:
319# Create build directory symlink.
320python_set_build_dir_symlink() {
321 local dir="$1"
322
323 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
324 [[ -z "${dir}" ]] && dir="build"
325
326 # Don't delete preexistent directories.
327 rm -f "${dir}" || die "Deletion of '${dir}' failed"
328 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
329}
330
331# @FUNCTION: python_execute_function
332# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--] <function> [arguments]
333# @DESCRIPTION:
334# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
335# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
336python_execute_function() {
337 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"
338
339 while (($#)); do
340 case "$1" in
341 --action-message)
342 action_message_template="$2"
343 shift
344 ;;
345 -d|--default-function)
346 default_function="1"
347 ;;
348 --failure-message)
349 failure_message_template="$2"
350 shift
351 ;;
352 --nonfatal)
353 nonfatal="1"
354 ;;
355 -q|--quiet)
356 quiet="1"
357 ;;
358 -s|--separate-build-dirs)
359 separate_build_dirs="1"
360 ;;
361 --)
362 break
363 ;;
364 -*)
365 die "${FUNCNAME}(): Unrecognized option '$1'"
366 ;;
367 *)
368 break
369 ;;
370 esac
371 shift
372 done
373
374 if [[ "${default_function}" == "0" ]]; then
375 if [[ "$#" -eq "0" ]]; then
376 die "${FUNCNAME}(): Missing function name"
377 fi
378 function="$1"
379 shift
380
381 if [[ -z "$(type -t "${function}")" ]]; then
382 die "${FUNCNAME}(): '${function}' function isn't defined"
383 fi
384 else
385 if [[ "$#" -ne "0" ]]; then
386 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
387 fi
388 if has "${EAPI:-0}" 0 1; then
389 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
390 fi
391
392 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
393 if has "${EAPI}" 2; then
394 python_default_function() {
395 econf
396 }
397 else
398 python_default_function() {
399 nonfatal econf
400 }
401 fi
402 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
403 python_default_function() {
404 emake
405 }
406 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
407 python_default_function() {
408 if emake -j1 -n check &> /dev/null; then
409 emake -j1 check
410 elif emake -j1 -n test &> /dev/null; then
411 emake -j1 test
412 fi
413 }
414 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
415 python_default_function() {
416 emake DESTDIR="${D}" install
417 }
418 else
419 die "${FUNCNAME}(): --default-function option cannot be used in this ebuild phase"
420 fi
421 function="python_default_function"
422 fi
423
424 if [[ "${quiet}" == "0" ]]; then
425 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
426 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
427 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
428 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
429 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
430 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
431 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
432 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
433 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
434 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
435 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
436 fi
437
438 local RED GREEN BLUE NORMAL
439 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
440 RED=$'\e[1;31m'
441 GREEN=$'\e[1;32m'
442 BLUE=$'\e[1;34m'
443 NORMAL=$'\e[0m'
444 else
445 RED=
446 GREEN=
447 BLUE=
448 NORMAL=
449 fi
450
451 validate_PYTHON_ABIS
452 for PYTHON_ABI in ${PYTHON_ABIS}; do
453 if [[ "${quiet}" == "0" ]]; then
454 if [[ -n "${action_message_template}" ]]; then
455 action_message="$(eval echo -n "${action_message_template}")"
456 else
457 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
458 fi
459 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
460 fi
461
462 if [[ "${separate_build_dirs}" == "1" ]]; then
463 export BUILDDIR="${S}-${PYTHON_ABI}"
464 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
465 else
466 export BUILDDIR="${S}"
467 fi
468
469 previous_directory="$(pwd)"
470 previous_directory_stack="$(dirs -p)"
471 previous_directory_stack_length="$(dirs -p | wc -l)"
472
473 if ! has "${EAPI}" 0 1 2 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
474 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
475 else
476 EPYTHON="$(PYTHON)" "${function}" "$@"
477 fi
478
479 if [[ "$?" != "0" ]]; then
480 if [[ -n "${failure_message_template}" ]]; then
481 failure_message="$(eval echo -n "${failure_message_template}")"
482 else
483 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
484 fi
485
486 if [[ "${nonfatal}" == "1" ]]; then
487 if [[ "${quiet}" == "0" ]]; then
488 ewarn "${RED}${failure_message}${NORMAL}"
489 fi
490 elif has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
491 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
492 local enabled_PYTHON_ABIS= other_PYTHON_ABI
493 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
494 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${other_PYTHON_ABI}"
495 done
496 export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
497 fi
498 if [[ "${quiet}" == "0" ]]; then
499 ewarn "${RED}${failure_message}${NORMAL}"
500 fi
501 if [[ -z "${PYTHON_ABIS}" ]]; then
502 die "${function}() function failed with all enabled versions of Python"
503 fi
504 else
505 die "${failure_message}"
506 fi
507 fi
508
509 # Ensure that directory stack hasn't been decreased.
510 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
511 die "Directory stack decreased illegally"
512 fi
513
514 # Avoid side effects of earlier returning from the specified function.
515 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
516 popd > /dev/null || die "popd failed"
517 done
518
519 # Ensure that the bottom part of directory stack hasn't been changed. Restore
520 # previous directory (from before running of the specified function) before
521 # comparison of directory stacks to avoid mismatch of directory stacks after
522 # potential using of 'cd' to change current directory. Restoration of previous
523 # directory allows to safely use 'cd' to change current directory in the
524 # specified function without changing it back to original directory.
525 cd "${previous_directory}"
526 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
527 die "Directory stack changed illegally"
528 fi
529
530 if [[ "${separate_build_dirs}" == "1" ]]; then
531 popd > /dev/null || die "popd failed"
532 fi
533 unset BUILDDIR
534 done
535
536 if [[ "${default_function}" == "1" ]]; then
537 unset -f python_default_function
538 fi
539}
540
541# @FUNCTION: python_convert_shebangs
542# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories]
543# @DESCRIPTION:
544# Convert shebangs in specified files. Directories can be specified only with --recursive option.
545python_convert_shebangs() {
546 local argument file files=() only_executables="0" python_version quiet="0" recursive="0"
547
548 while (($#)); do
549 case "$1" in
550 -r|--recursive)
551 recursive="1"
552 ;;
553 -q|--quiet)
554 quiet="1"
555 ;;
556 -x|--only-executables)
557 only_executables="1"
558 ;;
559 --)
560 break
561 ;;
562 -*)
563 die "${FUNCNAME}(): Unrecognized option '$1'"
564 ;;
565 *)
566 break
567 ;;
568 esac
569 shift
570 done
571
572 if [[ "$#" -eq 0 ]]; then
573 die "${FUNCNAME}(): Missing Python version and files or directories"
574 elif [[ "$#" -eq 1 ]]; then
575 die "${FUNCNAME}(): Missing files or directories"
576 fi
577
578 python_version="$1"
579 shift
580
581 for argument in "$@"; do
582 if [[ ! -e "${argument}" ]]; then
583 die "${FUNCNAME}(): '${argument}' doesn't exist"
584 elif [[ -f "${argument}" ]]; then
585 files+=("${argument}")
586 elif [[ -d "${argument}" ]]; then
587 if [[ "${recursive}" == "1" ]]; then
588 if [[ "${only_executables}" == "1" ]]; then
589 files+=($(find "${argument}" -perm /111 -type f))
590 else
591 files+=($(find "${argument}" -type f))
592 fi
593 else
594 die "${FUNCNAME}(): '${argument}' isn't a regular file"
595 fi
596 else
597 die "${FUNCNAME}(): '${argument}' isn't a regular file or a directory"
598 fi
599 done
600
601 for file in "${files[@]}"; do
602 file="${file#./}"
603 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
604
605 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then
606 [[ "${quiet}" == "0" ]] && einfo "Converting shebang in '${file}'"
607 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
608
609 # Delete potential whitespace after "#!".
610 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed"
611 fi
612 done
613}
614
615# @ECLASS-VARIABLE: PYTHON_USE_WITH
616# @DESCRIPTION:
617# Set this to a space separated list of use flags
618# the python slot in use must be built with.
619
620# @ECLASS-VARIABLE: PYTHON_USE_WITH_OR
621# @DESCRIPTION:
622# Set this to a space separated list of use flags
623# of which one must be turned on for the slot of
624# in use.
625
626# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
627# @DESCRIPTION:
628# Set this if you need to make either PYTHON_USE_WITH or
629# PYTHON_USE_WITH_OR atoms conditional under a use flag.
630
631# @FUNCTION: python_pkg_setup
632# @DESCRIPTION:
633# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
634# are respected. Only exported if one of those variables is set.
635if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
636 python_pkg_setup() {
637 python_pkg_setup_fail() {
638 eerror "${1}"
639 die "${1}"
640 }
641
642 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
643
644 python_pkg_setup_check_USE_flags() {
645 local pyatom use
646 if [[ -n "${PYTHON_ABI}" ]]; then
647 pyatom="dev-lang/python:${PYTHON_ABI}"
648 else
649 python_version
650 pyatom="dev-lang/python:${PYVER}"
651 fi
652
653 for use in ${PYTHON_USE_WITH}; do
654 if ! has_version "${pyatom}[${use}]"; then
655 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
656 fi
657 done
658
659 for use in ${PYTHON_USE_WITH_OR}; do
660 if has_version "${pyatom}[${use}]"; then
661 return
662 fi
663 done
664
665 if [[ ${PYTHON_USE_WITH_OR} ]]; then
666 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
667 fi
668 }
669
670 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
671 python_execute_function -q python_pkg_setup_check_USE_flags
672 else
673 python_pkg_setup_check_USE_flags
674 fi
675 }
676
677 EXPORT_FUNCTIONS pkg_setup
678
679 if [[ -n "${PYTHON_USE_WITH}" ]]; then
680 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
681 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
682 PYTHON_USE_WITH_ATOM="|| ( "
683 for use in ${PYTHON_USE_WITH_OR}; do
684 PYTHON_USE_WITH_ATOM+=" ${PYTHON_ATOM}[${use}]"
685 done
686 unset use
687 PYTHON_USE_WITH_ATOM+=" )"
688 fi
689 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
690 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
691 fi
692 DEPEND+=" ${PYTHON_USE_WITH_ATOM}"
693 RDEPEND+=" ${PYTHON_USE_WITH_ATOM}"
694fi
695
696# @ECLASS-VARIABLE: PYTHON_DEFINE_DEFAULT_FUNCTIONS
697# @DESCRIPTION:
698# Set this to define default functions for the following ebuild phases:
699# src_prepare, src_configure, src_compile, src_test, src_install.
700if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_DEFINE_DEFAULT_FUNCTIONS}" ]]; then
701 python_src_prepare() {
702 python_copy_sources
703 }
704
705 for python_default_function in src_configure src_compile src_test src_install; do
706 eval "python_${python_default_function}() { python_execute_function -d -s; }"
707 done
708 unset python_default_function
709
710 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
711fi
712
62# @FUNCTION: python_disable_pyc 713# @FUNCTION: python_disable_pyc
63# @DESCRIPTION: 714# @DESCRIPTION:
64# Tells python not to automatically recompile modules to .pyc/.pyo 715# Tell Python not to automatically recompile modules to .pyc/.pyo
65# even if the timestamps/version stamps don't match. This is done 716# even if the timestamps/version stamps don't match. This is done
66# to protect sandbox. 717# to protect sandbox.
67#
68# note: supported by >=dev-lang/python-2.2.3-r3 only.
69#
70python_disable_pyc() { 718python_disable_pyc() {
71 export PYTHONDONTWRITEBYTECODE=1 # For 2.6 and above 719 export PYTHONDONTWRITEBYTECODE="1"
72 export PYTHON_DONTCOMPILE=1 # For 2.5 and below
73} 720}
74 721
75# @FUNCTION: python_enable_pyc 722# @FUNCTION: python_enable_pyc
76# @DESCRIPTION: 723# @DESCRIPTION:
77# Tells python to automatically recompile modules to .pyc/.pyo if the 724# Tell Python to automatically recompile modules to .pyc/.pyo if the
78# timestamps/version stamps change 725# timestamps/version stamps have changed.
79python_enable_pyc() { 726python_enable_pyc() {
80 unset PYTHONDONTWRITEBYTECODE 727 unset PYTHONDONTWRITEBYTECODE
81 unset PYTHON_DONTCOMPILE
82} 728}
83
84python_disable_pyc
85 729
86# @FUNCTION: python_need_rebuild 730# @FUNCTION: python_need_rebuild
87# @DESCRIPTION: Run without arguments, specifies that the package should be 731# @DESCRIPTION: Run without arguments, specifies that the package should be
88# rebuilt after a python upgrade. 732# rebuilt after a python upgrade.
89python_need_rebuild() { 733python_need_rebuild() {
90 python_version 734 python_version
91 export PYTHON_NEED_REBUILD=${PYVER} 735 export PYTHON_NEED_REBUILD=${PYVER}
92} 736}
93 737
738# @FUNCTION: python_get_includedir
739# @DESCRIPTION:
740# Run without arguments, returns the Python include directory.
741python_get_includedir() {
742 if [[ -n "${PYTHON_ABI}" ]]; then
743 echo "/usr/include/python${PYTHON_ABI}"
744 else
745 python_version
746 echo "/usr/include/python${PYVER}"
747 fi
748}
749
94# @FUNCTION: python_get_libdir 750# @FUNCTION: python_get_libdir
95# @DESCRIPTION: 751# @DESCRIPTION:
96# Run without arguments, returns the python library dir 752# Run without arguments, returns the Python library directory.
97python_get_libdir() { 753python_get_libdir() {
754 if [[ -n "${PYTHON_ABI}" ]]; then
755 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
756 else
98 python_version 757 python_version
99 echo "/usr/$(get_libdir)/python${PYVER}" 758 echo "/usr/$(get_libdir)/python${PYVER}"
759 fi
100} 760}
101 761
102# @FUNCTION: python_get_sitedir 762# @FUNCTION: python_get_sitedir
103# @DESCRIPTION: 763# @DESCRIPTION:
104# Run without arguments, returns the python site-packages dir 764# Run without arguments, returns the Python site-packages directory.
105python_get_sitedir() { 765python_get_sitedir() {
106 echo "$(python_get_libdir)/site-packages" 766 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} 767}
117 768
118# @FUNCTION: python_tkinter_exists 769# @FUNCTION: python_tkinter_exists
119# @DESCRIPTION: 770# @DESCRIPTION:
120# Run without arguments, checks if python was compiled with Tkinter 771# Run without arguments, checks if python was compiled with Tkinter
128 die "missing tkinter support with installed python" 779 die "missing tkinter support with installed python"
129 fi 780 fi
130} 781}
131 782
132# @FUNCTION: python_mod_exists 783# @FUNCTION: python_mod_exists
133# @USAGE: < module > 784# @USAGE: <module>
134# @DESCRIPTION: 785# @DESCRIPTION:
135# Run with the module name as an argument. it will check if a 786# Run with the module name as an argument. it will check if a
136# python module is installed and loadable. it will return 787# python module is installed and loadable. it will return
137# TRUE(0) if the module exists, and FALSE(1) if the module does 788# TRUE(0) if the module exists, and FALSE(1) if the module does
138# not exist. 789# not exist.
141# if python_mod_exists gtk; then 792# if python_mod_exists gtk; then
142# echo "gtk support enabled" 793# echo "gtk support enabled"
143# fi 794# fi
144python_mod_exists() { 795python_mod_exists() {
145 [[ "$1" ]] || die "${FUNCNAME} requires an argument!" 796 [[ "$1" ]] || die "${FUNCNAME} requires an argument!"
146 python -c "import $1" >/dev/null 2>&1 797 python -c "import $1" &>/dev/null
147} 798}
148 799
149# @FUNCTION: python_mod_compile 800# @FUNCTION: python_mod_compile
150# @USAGE: < file > [more files ...] 801# @USAGE: <file> [more files ...]
151# @DESCRIPTION: 802# @DESCRIPTION:
152# Given filenames, it will pre-compile the module's .pyc and .pyo. 803# Given filenames, it will pre-compile the module's .pyc and .pyo.
153# This function should only be run in pkg_postinst() 804# This function should only be run in pkg_postinst()
154# 805#
155# Example: 806# Example:
156# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py 807# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
157# 808#
158python_mod_compile() { 809python_mod_compile() {
810 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
811 die "${FUNCNAME}() cannot be used in this EAPI"
812 fi
813
159 local f myroot myfiles=() 814 local f myroot myfiles=()
160 815
161 # Check if phase is pkg_postinst() 816 # Check if phase is pkg_postinst()
162 [[ ${EBUILD_PHASE} != postinst ]] &&\ 817 [[ ${EBUILD_PHASE} != postinst ]] &&\
163 die "${FUNCNAME} should only be run in pkg_postinst()" 818 die "${FUNCNAME} should only be run in pkg_postinst()"
177 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}") 832 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
178 done 833 done
179 834
180 if ((${#myfiles[@]})); then 835 if ((${#myfiles[@]})); then
181 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 836 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}"
182 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 837 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" &> /dev/null
183 else 838 else
184 ewarn "No files to compile!" 839 ewarn "No files to compile!"
185 fi 840 fi
186} 841}
187 842
188# @FUNCTION: python_mod_optimize 843# @FUNCTION: python_mod_optimize
189# @USAGE: [ path ] 844# @USAGE: [options] [directory|file]
190# @DESCRIPTION: 845# @DESCRIPTION:
191# If no arguments supplied, it will recompile all modules under 846# 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/ ..) 847# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
193# no recursively
194# 848#
195# If supplied with arguments, it will recompile all modules recursively 849# If supplied with arguments, it will recompile all modules recursively
196# in the supplied directory 850# in the supplied directory.
197# This function should only be run in pkg_postinst() 851# This function should only be run in pkg_postinst().
198# 852#
199# Options passed to this function are passed to compileall.py 853# Options passed to this function are passed to compileall.py.
200# 854#
201# Example: 855# Example:
202# python_mod_optimize /usr/share/codegen 856# python_mod_optimize ctypesgencore
203python_mod_optimize() { 857python_mod_optimize() {
204 local myroot mydirs=() myfiles=() myopts=()
205
206 # Check if phase is pkg_postinst() 858 # Check if phase is pkg_postinst().
207 [[ ${EBUILD_PHASE} != postinst ]] &&\ 859 [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME} should only be run in pkg_postinst()"
208 die "${FUNCNAME} should only be run in pkg_postinst()"
209 860
861 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
862 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=()
863
864 # Strip trailing slash from ROOT.
865 root="${ROOT%/}"
866
867 # Respect ROOT and options passed to compileall.py.
868 while (($#)); do
869 case "$1" in
870 -l|-f|-q)
871 options+=("$1")
872 ;;
873 -d|-x)
874 options+=("$1" "$2")
875 shift
876 ;;
877 -*)
878 ewarn "${FUNCNAME}: Ignoring compile option $1"
879 ;;
880 *)
881 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
882 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
883 elif [[ "$1" =~ ^/ ]]; then
884 if [[ -d "${root}/$1" ]]; then
885 other_dirs+=("${root}/$1")
886 elif [[ -f "${root}/$1" ]]; then
887 other_files+=("${root}/$1")
888 elif [[ -e "${root}/$1" ]]; then
889 ewarn "'${root}/$1' is not a file or a directory!"
890 else
891 ewarn "'${root}/$1' doesn't exist!"
892 fi
893 else
894 for PYTHON_ABI in ${PYTHON_ABIS}; do
895 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
896 site_packages_dirs+=("$1")
897 break
898 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
899 site_packages_files+=("$1")
900 break
901 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
902 ewarn "'$1' is not a file or a directory!"
903 else
904 ewarn "'$1' doesn't exist!"
905 fi
906 done
907 fi
908 ;;
909 esac
910 shift
911 done
912
913 # Set additional options.
914 options+=("-q")
915
916 for PYTHON_ABI in ${PYTHON_ABIS}; do
917 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
918 return_code="0"
919 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
920 if ((${#site_packages_dirs[@]})); then
921 for dir in "${site_packages_dirs[@]}"; do
922 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
923 done
924 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
925 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
926 fi
927 if ((${#site_packages_files[@]})); then
928 for file in "${site_packages_files[@]}"; do
929 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
930 done
931 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
932 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
933 fi
934 eend "${return_code}"
935 fi
936 unset site_packages_absolute_dirs site_packages_absolute_files
937 done
938
939 # Don't use PYTHON_ABI in next calls to python_get_libdir().
940 unset PYTHON_ABI
941
942 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
943 return_code="0"
944 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}"
945 if ((${#other_dirs[@]})); then
946 python${PYVER} "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
947 python${PYVER} -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
948 fi
949 if ((${#other_files[@]})); then
950 python${PYVER} "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
951 python${PYVER} -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
952 fi
953 eend "${return_code}"
954 fi
955 else
956 local myroot mydirs=() myfiles=() myopts=() return_code="0"
957
210 # strip trailing slash 958 # strip trailing slash
211 myroot="${ROOT%/}" 959 myroot="${ROOT%/}"
212 960
213 # respect ROOT and options passed to compileall.py 961 # respect ROOT and options passed to compileall.py
214 while (($#)); do 962 while (($#)); do
215 case $1 in 963 case "$1" in
216 -l|-f|-q) 964 -l|-f|-q)
217 myopts+=("$1") 965 myopts+=("$1")
218 ;; 966 ;;
219 -d|-x) 967 -d|-x)
220 myopts+=("$1" "$2") 968 myopts+=("$1" "$2")
969 shift
970 ;;
971 -*)
972 ewarn "${FUNCNAME}: Ignoring compile option $1"
973 ;;
974 *)
975 if [[ -d "${myroot}"/$1 ]]; then
976 mydirs+=("${myroot}/$1")
977 elif [[ -f "${myroot}"/$1 ]]; then
978 # Files are passed to python_mod_compile which is ROOT-aware
979 myfiles+=("$1")
980 elif [[ -e "${myroot}/$1" ]]; then
981 ewarn "${myroot}/$1 is not a file or directory!"
982 else
983 ewarn "${myroot}/$1 doesn't exist!"
984 fi
985 ;;
986 esac
987 shift
988 done
989
990 # allow compiling for older python versions
991 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
992 PYVER=${PYTHON_OVERRIDE_PYVER}
993 else
994 python_version
995 fi
996
997 # set additional opts
998 myopts+=(-q)
999
1000 ebegin "Compilation and optimization of Python modules for Python ${PYVER}"
1001 if ((${#mydirs[@]})); then
1002 python${PYVER} \
1003 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
1004 "${myopts[@]}" "${mydirs[@]}" || return_code="1"
1005 python${PYVER} -O \
1006 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
1007 "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
1008 fi
1009
1010 if ((${#myfiles[@]})); then
1011 python_mod_compile "${myfiles[@]}"
1012 fi
1013
1014 eend "${return_code}"
1015 fi
1016}
1017
1018# @FUNCTION: python_mod_cleanup
1019# @USAGE: [directory]
1020# @DESCRIPTION:
1021# Run with optional arguments, where arguments are directories of
1022# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9].
1023#
1024# It will recursively scan all compiled Python modules in the directories and
1025# determine if they are orphaned (i.e. their corresponding .py files are missing.)
1026# If they are, then it will remove their corresponding .pyc and .pyo files.
1027#
1028# This function should only be run in pkg_postrm().
1029python_mod_cleanup() {
1030 local path py_file PYTHON_ABI SEARCH_PATH=() root
1031
1032 # Check if phase is pkg_postrm().
1033 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
1034
1035 # Strip trailing slash from ROOT.
1036 root="${ROOT%/}"
1037
1038 if (($#)); then
1039 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
1040 while (($#)); do
1041 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
1042 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
1043 elif [[ "$1" =~ ^/ ]]; then
1044 SEARCH_PATH+=("${root}/${1#/}")
1045 else
1046 for PYTHON_ABI in ${PYTHON_ABIS}; do
1047 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
1048 done
1049 fi
221 shift 1050 shift
222 ;; 1051 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 1052 else
235 ewarn "${myroot}/$1 doesn't exist!" 1053 SEARCH_PATH=("${@#/}")
1054 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
1055 fi
1056 else
1057 local dir sitedir
1058 for dir in "${root}"/usr/lib*; do
1059 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
1060 for sitedir in "${dir}"/python*/site-packages; do
1061 if [[ -d "${sitedir}" ]]; then
1062 SEARCH_PATH+=("${sitedir}")
236 fi 1063 fi
237 ;; 1064 done
238 esac 1065 fi
239 shift 1066 done
1067 fi
1068
1069 local BLUE CYAN NORMAL
1070 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
1071 BLUE=$'\e[34m'
1072 CYAN=$'\e[36m'
1073 NORMAL=$'\e[0m'
1074 else
1075 BLUE=
1076 CYAN=
1077 NORMAL=
1078 fi
1079
1080 for path in "${SEARCH_PATH[@]}"; do
1081 if [[ -d "${path}" ]]; then
1082 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
1083 py_file="${REPLY%[co]}"
1084 [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue
1085 einfo "${BLUE}<<< ${py_file}[co]${NORMAL}"
1086 rm -f "${py_file}"[co]
1087 done
1088
1089 # Attempt to delete directories, which may be empty.
1090 find "${path}" -type d | sort -r | while read -r dir; do
1091 rmdir "${dir}" 2>/dev/null && einfo "${CYAN}<<< ${dir}${NORMAL}"
1092 done
1093 elif [[ "${path}" == *.py && ! -f "${path}" && (-f "${path}c" || -f "${path}o") ]]; then
1094 einfo "${BLUE}<<< ${path}[co]${NORMAL}"
1095 rm -f "${path}"[co]
1096 fi
240 done 1097 done
241
242 # allow compiling for older python versions
243 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
244 PYVER=${PYTHON_OVERRIDE_PYVER}
245 else
246 python_version
247 fi
248
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
261
262 if ((${#myfiles[@]})); then
263 python_mod_compile "${myfiles[@]}"
264 fi
265
266 eend $?
267} 1098}
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
294 SEARCH_PATH=("${myroot}"/usr/lib*/python*/site-packages)
295 fi
296
297 for path in "${SEARCH_PATH[@]}"; do
298 einfo "Cleaning orphaned Python bytecode from ${path} .."
299 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
300 src_py="${REPLY%[co]}"
301 [[ -f "${src_py}" ]] && continue
302 einfo "Purging ${src_py}[co]"
303 rm -f "${src_py}"[co]
304 done
305
306 # attempt to remove directories that maybe empty
307 find "${path}" -type d | sort -r | while read -r dir; do
308 rmdir "${dir}" 2>/dev/null
309 done
310 done
311}

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

  ViewVC Help
Powered by ViewVC 1.1.20