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

Diff of /eclass/python.eclass

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

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

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.77

  ViewVC Help
Powered by ViewVC 1.1.20