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

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

  ViewVC Help
Powered by ViewVC 1.1.20