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

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

  ViewVC Help
Powered by ViewVC 1.1.20