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

  ViewVC Help
Powered by ViewVC 1.1.20