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

Diff of /eclass/python.eclass

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

Revision 1.33 Revision 1.66
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.33 2008/02/28 20:20:32 dev-zero Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.66 2009/08/28 16:08:51 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# 8#
9# original author: Alastair Tse <liquidx@gentoo.org> 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. 10# @BLURB: A Utility Eclass that should be inherited by anything that deals with Python or Python modules.
11# @DESCRIPTION: 11# @DESCRIPTION:
12# Some useful functions for dealing with python. 12# Some useful functions for dealing with Python.
13inherit alternatives multilib
14 13
14inherit multilib
15 15
16if [[ -n "${NEED_PYTHON}" ]] ; then 16if [[ -n "${NEED_PYTHON}" ]] ; then
17 DEPEND=">=dev-lang/python-${NEED_PYTHON}" 17 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
18 DEPEND="${PYTHON_ATOM}"
18 RDEPEND="${DEPEND}" 19 RDEPEND="${DEPEND}"
20else
21 PYTHON_ATOM="dev-lang/python"
22fi
23
24DEPEND="${DEPEND} >=app-shells/bash-3.2"
25if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
26 DEPEND="${DEPEND} >=app-admin/eselect-python-20090804"
19fi 27fi
20 28
21__python_eclass_test() { 29__python_eclass_test() {
22 __python_version_extract 2.3 30 __python_version_extract 2.3
23 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 31 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
34 __python_version_extract 2.5b3 42 __python_version_extract 2.5b3
35 echo -n "2.5b3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 43 echo -n "2.5b3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
36 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 44 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
37} 45}
38 46
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 47# @FUNCTION: python_version
62# @DESCRIPTION: 48# @DESCRIPTION:
63# Run without arguments and it will export the version of python 49# Run without arguments and it will export the version of python
64# currently in use as $PYVER; sets PYVER/PYVER_MAJOR/PYVER_MINOR 50# currently in use as $PYVER; sets PYVER/PYVER_MAJOR/PYVER_MINOR
65__python_version_extract() { 51__python_version_extract() {
66 verstr=$1 52 local verstr=$1
67 export PYVER_MAJOR=${verstr:0:1} 53 export PYVER_MAJOR=${verstr:0:1}
68 export PYVER_MINOR=${verstr:2:1} 54 export PYVER_MINOR=${verstr:2:1}
69 if [ "${verstr:3}x" = ".x" ]; then 55 if [[ ${verstr:3:1} == . ]]; then
70 export PYVER_MICRO=${verstr:4} 56 export PYVER_MICRO=${verstr:4}
71 fi 57 fi
72 export PYVER="${PYVER_MAJOR}.${PYVER_MINOR}" 58 export PYVER="${PYVER_MAJOR}.${PYVER_MINOR}"
73} 59}
74 60
75python_version() { 61python_version() {
62 [[ -n "${PYVER}" ]] && return 0
76 local tmpstr 63 local tmpstr
77 python=${python:-/usr/bin/python} 64 python=${python:-/usr/bin/python}
78 tmpstr="$(${python} -V 2>&1 )" 65 tmpstr="$(${python} -V 2>&1 )"
79 export PYVER_ALL="${tmpstr#Python }" 66 export PYVER_ALL="${tmpstr#Python }"
80 __python_version_extract $PYVER_ALL 67 __python_version_extract $PYVER_ALL
81} 68}
82 69
70# @FUNCTION: PYTHON
71# @USAGE: [-a|--absolute-path] <Python_ABI="${PYTHON_ABI}">
72# @DESCRIPTION:
73# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
74# is ommitted, then PYTHON_ABI environment variable must be set and is used.
75PYTHON() {
76 local absolute_path="0" slot=
77
78 while (($#)); do
79 case "$1" in
80 -a|--absolute-path)
81 absolute_path="1"
82 ;;
83 -*)
84 die "${FUNCNAME}(): Unrecognized option $1"
85 ;;
86 *)
87 break
88 ;;
89 esac
90 shift
91 done
92
93 if [[ "$#" -eq "0" ]]; then
94 if [[ -n "${PYTHON_ABI}" ]]; then
95 slot="${PYTHON_ABI}"
96 else
97 die "${FUNCNAME}(): Invalid usage"
98 fi
99 elif [[ "$#" -eq "1" ]]; then
100 slot="$1"
101 else
102 die "${FUNCNAME}(): Invalid usage"
103 fi
104
105 if [[ "${absolute_path}" == "1" ]]; then
106 echo -n "/usr/bin/python${slot}"
107 else
108 echo -n "python${slot}"
109 fi
110}
111
112# @FUNCTION: validate_PYTHON_ABIS
113# @DESCRIPTION:
114# Make sure PYTHON_ABIS variable has valid value.
115validate_PYTHON_ABIS() {
116 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
117 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
118 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
119 fi
120
121 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
122 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
123 die "'/usr/bin/python' isn't valid symlink"
124 fi
125 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
126 die "'/usr/bin/python-config' isn't valid script"
127 fi
128
129 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4.
130 if [[ -z "${PYTHON_ABIS}" ]] && has "${EAPI:-0}" 0 1 2 3; then
131 local ABI support_ABI supported_PYTHON_ABIS= restricted_ABI
132 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
133 for ABI in ${USE_PYTHON}; do
134 if ! has "${ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
135 ewarn "Ignoring unsupported Python ABI '${ABI}'"
136 continue
137 fi
138 support_ABI="1"
139 if [[ -z "${IGNORE_RESTRICT_PYTHON_ABIS}" ]]; then
140 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
141 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then
142 support_ABI="0"
143 break
144 fi
145 done
146 fi
147 [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${ABI}"
148 done
149 export PYTHON_ABIS="${supported_PYTHON_ABIS# }"
150 fi
151
152 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
153 python_version
154 export PYTHON_ABIS="${PYVER}"
155 fi
156
157 # Ensure that EPYTHON variable is respected.
158 local PYTHON_ABI
159 for PYTHON_ABI in ${PYTHON_ABIS}; do
160 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
161 die "'python' doesn't respect EPYTHON variable"
162 fi
163 done
164}
165
166# @FUNCTION: python_copy_sources
167# @USAGE: [directory]
168# @DESCRIPTION:
169# Copy unpacked sources of given package for each Python ABI.
170python_copy_sources() {
171 local dir dirs=() PYTHON_ABI
172
173 if [[ "$#" -eq "0" ]]; then
174 if [[ "${WORKDIR}" == "${S}" ]]; then
175 die "${FUNCNAME}() cannot be used"
176 fi
177 dirs="${S}"
178 else
179 dirs="$@"
180 fi
181
182 validate_PYTHON_ABIS
183 for PYTHON_ABI in ${PYTHON_ABIS}; do
184 for dir in "${dirs[@]}"; do
185 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
186 done
187 done
188}
189
190# @FUNCTION: python_set_build_dir_symlink
191# @USAGE: [directory="build"]
192# @DESCRIPTION:
193# Create build directory symlink.
194python_set_build_dir_symlink() {
195 local dir="$1"
196
197 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
198 [[ -z "${dir}" ]] && dir="build"
199
200 # Don't delete preexistent directories.
201 rm -f "${dir}" || die "Deletion of '${dir}' failed"
202 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
203}
204
205# @FUNCTION: python_execute_function
206# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] <function> [arguments]
207# @DESCRIPTION:
208# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
209# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
210python_execute_function() {
211 local action action_message action_message_template= default_function="0" failure_message failure_message_template= function nonfatal="0" PYTHON_ABI quiet="0" separate_build_dirs="0"
212
213 while (($#)); do
214 case "$1" in
215 --action-message)
216 action_message_template="$2"
217 shift
218 ;;
219 -d|--default-function)
220 default_function="1"
221 ;;
222 --failure-message)
223 failure_message_template="$2"
224 shift
225 ;;
226 --nonfatal)
227 nonfatal="1"
228 ;;
229 -q|--quiet)
230 quiet="1"
231 ;;
232 -s|--separate-build-dirs)
233 separate_build_dirs="1"
234 ;;
235 -*)
236 die "${FUNCNAME}(): Unrecognized option $1"
237 ;;
238 *)
239 break
240 ;;
241 esac
242 shift
243 done
244
245 if [[ "${default_function}" == "0" ]]; then
246 if [[ "$#" -eq "0" ]]; then
247 die "${FUNCNAME}(): Missing function name"
248 fi
249 function="$1"
250 shift
251 else
252 if [[ "$#" -ne "0" ]]; then
253 die "${FUNCNAME}(): --default-function option and function name cannot be specified simultaneously"
254 fi
255 if has "${EAPI:-0}" 0 1; then
256 die "${FUNCNAME}(): --default-function option cannot be used in this EAPI"
257 fi
258
259 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
260 if has "${EAPI}" 2; then
261 python_default_function() {
262 econf
263 }
264 else
265 python_default_function() {
266 nonfatal econf
267 }
268 fi
269 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
270 python_default_function() {
271 emake
272 }
273 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
274 python_default_function() {
275 if emake -j1 -n check &> /dev/null; then
276 emake -j1 check
277 elif emake -j1 -n test &> /dev/null; then
278 emake -j1 test
279 fi
280 }
281 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
282 python_default_function() {
283 emake DESTDIR="${D}" install
284 }
285 else
286 die "${FUNCNAME}(): --default-function option cannot be used in this ebuild phase"
287 fi
288 function="python_default_function"
289 fi
290
291 if [[ "${quiet}" == "0" ]]; then
292 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
293 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
294 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
295 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
296 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
297 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
298 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
299 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
300 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
301 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
302 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
303 fi
304
305 local RED GREEN BLUE NORMAL
306 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
307 RED=$'\e[1;31m'
308 GREEN=$'\e[1;32m'
309 BLUE=$'\e[1;34m'
310 NORMAL=$'\e[0m'
311 else
312 RED=
313 GREEN=
314 BLUE=
315 NORMAL=
316 fi
317
318 validate_PYTHON_ABIS
319 for PYTHON_ABI in ${PYTHON_ABIS}; do
320 if [[ "${quiet}" == "0" ]]; then
321 if [[ -n "${action_message_template}" ]]; then
322 action_message="$(eval echo -n "${action_message_template}")"
323 else
324 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
325 fi
326 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
327 fi
328
329 if [[ "${separate_build_dirs}" == "1" ]]; then
330 export BUILDDIR="${S}-${PYTHON_ABI}"
331 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
332 else
333 export BUILDDIR="${S}"
334 fi
335
336 if ! has "${EAPI}" 0 1 2 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
337 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
338 else
339 EPYTHON="$(PYTHON)" "${function}" "$@"
340 fi
341
342 if [[ "$?" != "0" ]]; then
343 if [[ -n "${failure_message_template}" ]]; then
344 failure_message="$(eval echo -n "${failure_message_template}")"
345 else
346 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
347 fi
348
349 if [[ "${nonfatal}" == "1" ]] || has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
350 local ABI enabled_PYTHON_ABIS
351 for ABI in ${PYTHON_ABIS}; do
352 [[ "${ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${ABI}"
353 done
354 export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
355 if [[ "${quiet}" == "0" ]]; then
356 ewarn "${RED}${failure_message}${NORMAL}"
357 fi
358 else
359 die "${failure_message}"
360 fi
361 fi
362
363 if [[ "${separate_build_dirs}" == "1" ]]; then
364 popd > /dev/null || die "popd failed"
365 fi
366 unset BUILDDIR
367 done
368
369 if [[ "${default_function}" == "1" ]]; then
370 unset -f python_default_function
371 fi
372}
373
374
375# @ECLASS-VARIABLE: PYTHON_USE_WITH
376# @DESCRIPTION:
377# Set this to a space separated list of use flags
378# the python slot in use must be built with.
379
380# @ECLASS-VARIABLE: PYTHON_USE_WITH_OR
381# @DESCRIPTION:
382# Set this to a space separated list of use flags
383# of which one must be turned on for the slot of
384# in use.
385
386# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
387# @DESCRIPTION:
388# Set this if you need to make either PYTHON_USE_WITH or
389# PYTHON_USE_WITH_OR atoms conditional under a use flag.
390
391# @FUNCTION: python_pkg_setup
392# @DESCRIPTION:
393# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
394# are respected. Only exported if one of those variables is set.
395if ! has ${EAPI:-0} 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
396 python_pkg_setup_fail() {
397 eerror "${1}"
398 die "${1}"
399 }
400
401 python_pkg_setup() {
402 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
403
404 python_version
405 local failed
406 local pyatom="dev-lang/python:${PYVER}"
407
408 for use in ${PYTHON_USE_WITH}; do
409 if ! has_version "${pyatom}[${use}]"; then
410 python_pkg_setup_fail \
411 "Please rebuild ${pyatom} with use flags: ${PYTHON_USE_WITH}"
412 fi
413 done
414
415 for use in ${PYTHON_USE_WITH_OR}; do
416 if has_version "${pyatom}[${use}]"; then
417 return
418 fi
419 done
420
421 if [[ ${PYTHON_USE_WITH_OR} ]]; then
422 python_pkg_setup_fail \
423 "Please rebuild ${pyatom} with one of: ${PYTHON_USE_WITH_OR}"
424 fi
425 }
426
427 EXPORT_FUNCTIONS pkg_setup
428
429 if [[ ${PYTHON_USE_WITH} ]]; then
430 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
431 elif [[ ${PYTHON_USE_WITH_OR} ]]; then
432 PYTHON_USE_WITH_ATOM="|| ( "
433 for use in ${PYTHON_USE_WITH_OR}; do
434 PYTHON_USE_WITH_ATOM="
435 ${PYTHON_USE_WITH_ATOM}
436 ${PYTHON_ATOM}[${use}]"
437 done
438 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_ATOM} )"
439 fi
440 if [[ ${PYTHON_USE_WITH_OPT} ]]; then
441 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
442 fi
443 DEPEND="${PYTHON_USE_WITH_ATOM}"
444 RDEPEND="${PYTHON_USE_WITH_ATOM}"
445fi
446
447# @FUNCTION: python_disable_pyc
448# @DESCRIPTION:
449# Tell Python not to automatically recompile modules to .pyc/.pyo
450# even if the timestamps/version stamps don't match. This is done
451# to protect sandbox.
452python_disable_pyc() {
453 export PYTHONDONTWRITEBYTECODE="1"
454}
455
83# @FUNCTION: python_makesym 456# @FUNCTION: python_enable_pyc
84# @DESCRIPTION: 457# @DESCRIPTION:
85# Run without arguments, it will create the /usr/bin/python symlinks 458# Tell Python to automatically recompile modules to .pyc/.pyo if the
86# to the latest installed version 459# timestamps/version stamps have changed.
87python_makesym() { 460python_enable_pyc() {
88 alternatives_auto_makesym "/usr/bin/python" "python[0-9].[0-9]" 461 unset PYTHONDONTWRITEBYTECODE
89 alternatives_auto_makesym "/usr/bin/python2" "python2.[0-9]" 462}
463
464python_disable_pyc
465
466# @FUNCTION: python_need_rebuild
467# @DESCRIPTION: Run without arguments, specifies that the package should be
468# rebuilt after a python upgrade.
469python_need_rebuild() {
470 python_version
471 export PYTHON_NEED_REBUILD=${PYVER}
472}
473
474# @FUNCTION: python_get_includedir
475# @DESCRIPTION:
476# Run without arguments, returns the Python include directory.
477python_get_includedir() {
478 if [[ -n "${PYTHON_ABI}" ]]; then
479 echo "/usr/include/python${PYTHON_ABI}"
480 else
481 python_version
482 echo "/usr/include/python${PYVER}"
483 fi
484}
485
486# @FUNCTION: python_get_libdir
487# @DESCRIPTION:
488# Run without arguments, returns the Python library directory.
489python_get_libdir() {
490 if [[ -n "${PYTHON_ABI}" ]]; then
491 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
492 else
493 python_version
494 echo "/usr/$(get_libdir)/python${PYVER}"
495 fi
496}
497
498# @FUNCTION: python_get_sitedir
499# @DESCRIPTION:
500# Run without arguments, returns the Python site-packages directory.
501python_get_sitedir() {
502 echo "$(python_get_libdir)/site-packages"
90} 503}
91 504
92# @FUNCTION: python_tkinter_exists 505# @FUNCTION: python_tkinter_exists
93# @DESCRIPTION: 506# @DESCRIPTION:
94# Run without arguments, checks if python was compiled with Tkinter 507# Run without arguments, checks if python was compiled with Tkinter
102 die "missing tkinter support with installed python" 515 die "missing tkinter support with installed python"
103 fi 516 fi
104} 517}
105 518
106# @FUNCTION: python_mod_exists 519# @FUNCTION: python_mod_exists
107# @USAGE: < module > 520# @USAGE: <module>
108# @DESCRIPTION: 521# @DESCRIPTION:
109# Run with the module name as an argument. it will check if a 522# Run with the module name as an argument. it will check if a
110# python module is installed and loadable. it will return 523# python module is installed and loadable. it will return
111# TRUE(0) if the module exists, and FALSE(1) if the module does 524# TRUE(0) if the module exists, and FALSE(1) if the module does
112# not exist. 525# not exist.
114# Example: 527# Example:
115# if python_mod_exists gtk; then 528# if python_mod_exists gtk; then
116# echo "gtk support enabled" 529# echo "gtk support enabled"
117# fi 530# fi
118python_mod_exists() { 531python_mod_exists() {
119 [ -z "$1" ] && die "${FUNCTION} requires an argument!" 532 [[ "$1" ]] || die "${FUNCNAME} requires an argument!"
120 if ! python -c "import $1" >/dev/null 2>&1; then 533 python -c "import $1" &>/dev/null
121 return 1
122 fi
123 return 0
124} 534}
125 535
126# @FUNCTION: python_mod_compile 536# @FUNCTION: python_mod_compile
127# @USAGE: < file > 537# @USAGE: <file> [more files ...]
128# @DESCRIPTION: 538# @DESCRIPTION:
129# Given a filename, it will pre-compile the module's .pyc and .pyo. 539# Given filenames, it will pre-compile the module's .pyc and .pyo.
130# should only be run in pkg_postinst() 540# This function should only be run in pkg_postinst()
131# 541#
132# Example: 542# Example:
133# python_mod_compile ${ROOT}usr/lib/python2.3/site-packages/pygoogle.py 543# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
134# 544#
135python_mod_compile() { 545python_mod_compile() {
546 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
547 die "${FUNCNAME}() cannot be used in this EAPI"
548 fi
549
550 local f myroot myfiles=()
551
552 # Check if phase is pkg_postinst()
553 [[ ${EBUILD_PHASE} != postinst ]] &&\
554 die "${FUNCNAME} should only be run in pkg_postinst()"
555
136 # allow compiling for older python versions 556 # allow compiling for older python versions
137 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then 557 if [[ "${PYTHON_OVERRIDE_PYVER}" ]]; then
138 PYVER=${PYTHON_OVERRIDE_PYVER} 558 PYVER=${PYTHON_OVERRIDE_PYVER}
139 else 559 else
140 python_version 560 python_version
141 fi 561 fi
142 562
143 if [ -f "$1" ]; then 563 # strip trailing slash
144 python${PYVER} -c "import py_compile; py_compile.compile('${1}')" || \ 564 myroot="${ROOT%/}"
565
566 # respect ROOT
567 for f in "$@"; do
568 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
569 done
570
571 if ((${#myfiles[@]})); then
572 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}"
573 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" &> /dev/null
574 else
145 ewarn "Failed to compile ${1}" 575 ewarn "No files to compile!"
146 python${PYVER} -O -c "import py_compile; py_compile.compile('${1}')" || \
147 ewarn "Failed to compile ${1}"
148 else
149 ewarn "Unable to find ${1}"
150 fi 576 fi
151} 577}
152 578
153# @FUNCTION: python_mod_optimize 579# @FUNCTION: python_mod_optimize
154# @USAGE: [ path ] 580# @USAGE: [options] [directory|file]
155# @DESCRIPTION: 581# @DESCRIPTION:
156# If no arguments supplied, it will recompile all modules under 582# If no arguments supplied, it will recompile not recursively all modules
157# sys.path (eg. /usr/lib/python2.3, /usr/lib/python2.3/site-packages/ ..) 583# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages).
158# no recursively
159# 584#
160# If supplied with arguments, it will recompile all modules recursively 585# If supplied with arguments, it will recompile all modules recursively
161# in the supplied directory 586# in the supplied directory.
587# This function should only be run in pkg_postinst().
588#
589# Options passed to this function are passed to compileall.py.
162# 590#
163# Example: 591# Example:
164# python_mod_optimize ${ROOT}usr/share/codegen 592# python_mod_optimize ctypesgencore
165python_mod_optimize() { 593python_mod_optimize() {
166 local myroot 594 # Check if phase is pkg_postinst().
595 [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME} should only be run in pkg_postinst()"
596
597 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
598 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=()
599
600 # Strip trailing slash from ROOT.
601 root="${ROOT%/}"
602
603 # Respect ROOT and options passed to compileall.py.
604 while (($#)); do
605 case "$1" in
606 -l|-f|-q)
607 options+=("$1")
608 ;;
609 -d|-x)
610 options+=("$1" "$2")
611 shift
612 ;;
613 -*)
614 ewarn "${FUNCNAME}: Ignoring compile option $1"
615 ;;
616 *)
617 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
618 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
619 elif [[ "$1" =~ ^/ ]]; then
620 if [[ -d "${root}/$1" ]]; then
621 other_dirs+=("${root}/$1")
622 elif [[ -f "${root}/$1" ]]; then
623 other_files+=("${root}/$1")
624 elif [[ -e "${root}/$1" ]]; then
625 ewarn "'${root}/$1' is not a file or a directory!"
626 else
627 ewarn "'${root}/$1' doesn't exist!"
628 fi
629 else
630 for PYTHON_ABI in ${PYTHON_ABIS}; do
631 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
632 site_packages_dirs+=("$1")
633 break
634 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
635 site_packages_files+=("$1")
636 break
637 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
638 ewarn "'$1' is not a file or a directory!"
639 else
640 ewarn "'$1' doesn't exist!"
641 fi
642 done
643 fi
644 ;;
645 esac
646 shift
647 done
648
649 # Set additional options.
650 options+=("-q")
651
652 for PYTHON_ABI in ${PYTHON_ABIS}; do
653 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
654 return_code="0"
655 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
656 if ((${#site_packages_dirs[@]})); then
657 for dir in "${site_packages_dirs[@]}"; do
658 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
659 done
660 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
661 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
662 fi
663 if ((${#site_packages_files[@]})); then
664 for file in "${site_packages_files[@]}"; do
665 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
666 done
667 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
668 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
669 fi
670 eend "${return_code}"
671 fi
672 unset site_packages_absolute_dirs site_packages_absolute_files
673 done
674
675 # Don't use PYTHON_ABI in next calls to python_get_libdir().
676 unset PYTHON_ABI
677
678 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
679 return_code="0"
680 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}..."
681 if ((${#other_dirs[@]})); then
682 python${PYVER} "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
683 python${PYVER} -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
684 fi
685 if ((${#other_files[@]})); then
686 python${PYVER} "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
687 python${PYVER} -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
688 fi
689 eend "${return_code}"
690 fi
691 else
692 local myroot mydirs=() myfiles=() myopts=() return_code="0"
693
167 # strip trailing slash 694 # strip trailing slash
168 myroot="${ROOT%/}" 695 myroot="${ROOT%/}"
169 696
697 # respect ROOT and options passed to compileall.py
698 while (($#)); do
699 case "$1" in
700 -l|-f|-q)
701 myopts+=("$1")
702 ;;
703 -d|-x)
704 myopts+=("$1" "$2")
705 shift
706 ;;
707 -*)
708 ewarn "${FUNCNAME}: Ignoring compile option $1"
709 ;;
710 *)
711 if [[ -d "${myroot}"/$1 ]]; then
712 mydirs+=("${myroot}/$1")
713 elif [[ -f "${myroot}"/$1 ]]; then
714 # Files are passed to python_mod_compile which is ROOT-aware
715 myfiles+=("$1")
716 elif [[ -e "${myroot}/$1" ]]; then
717 ewarn "${myroot}/$1 is not a file or directory!"
718 else
719 ewarn "${myroot}/$1 doesn't exist!"
720 fi
721 ;;
722 esac
723 shift
724 done
725
170 # allow compiling for older python versions 726 # allow compiling for older python versions
171 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then 727 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then
172 PYVER=${PYTHON_OVERRIDE_PYVER} 728 PYVER=${PYTHON_OVERRIDE_PYVER}
173 else 729 else
174 python_version 730 python_version
175 fi 731 fi
176 732
177 # set opts 733 # set additional opts
178 if [ "${PYVER}" = "2.2" ]; then 734 myopts+=(-q)
179 compileopts=""
180 else
181 compileopts="-q"
182 fi
183 735
184 ebegin "Byte compiling python modules for python-${PYVER} .." 736 ebegin "Byte compiling python modules for python-${PYVER} .."
737 if ((${#mydirs[@]})); then
738 python${PYVER} \
185 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/compileall.py ${compileopts} $@ 739 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
186 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/compileall.py ${compileopts} $@ 740 "${myopts[@]}" "${mydirs[@]}" || return_code="1"
187 eend $? 741 python${PYVER} -O \
742 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
743 "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
744 fi
745
746 if ((${#myfiles[@]})); then
747 python_mod_compile "${myfiles[@]}"
748 fi
749
750 eend "${return_code}"
751 fi
188} 752}
189 753
190# @FUNCTION: python_mod_cleanup 754# @FUNCTION: python_mod_cleanup
191# @USAGE: [ dir ] 755# @USAGE: [directory]
192# @DESCRIPTION: 756# @DESCRIPTION:
193# Run with optional arguments, where arguments are directories of 757# Run with optional arguments, where arguments are directories of
194# python modules. if none given, it will look in /usr/lib/python[0-9].[0-9] 758# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9].
195# 759#
196# It will recursively scan all compiled python modules in the directories 760# It will recursively scan all compiled Python modules in the directories and
197# and determine if they are orphaned (eg. their corresponding .py is missing.) 761# determine if they are orphaned (i.e. their corresponding .py files are missing.)
198# if they are, then it will remove their corresponding .pyc and .pyo 762# If they are, then it will remove their corresponding .pyc and .pyo files.
763#
764# This function should only be run in pkg_postrm().
199python_mod_cleanup() { 765python_mod_cleanup() {
200 local SEARCH_PATH myroot 766 local PYTHON_ABI SEARCH_PATH=() root src_py
201 767
768 # Check if phase is pkg_postrm().
769 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
770
202 # strip trailing slash 771 # Strip trailing slash from ROOT.
203 myroot="${ROOT%/}" 772 root="${ROOT%/}"
204 773
205 if [ $# -gt 0 ]; then 774 if (($#)); then
206 for path in $@; do 775 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
207 SEARCH_PATH="${SEARCH_PATH} ${myroot}/${path#/}" 776 while (($#)); do
777 if [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
778 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
779 elif [[ "$1" =~ ^/ ]]; then
780 SEARCH_PATH+=("${root}/${1#/}")
781 else
782 for PYTHON_ABI in ${PYTHON_ABIS}; do
783 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
784 done
785 fi
786 shift
208 done 787 done
209 else 788 else
210 for path in ${myroot}/usr/lib*/python*/site-packages; do 789 SEARCH_PATH=("${@#/}")
211 SEARCH_PATH="${SEARCH_PATH} ${path}" 790 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
212 done
213 fi 791 fi
792 else
793 SEARCH_PATH=("${root}"/usr/lib*/python*/site-packages)
794 fi
214 795
215 for path in ${SEARCH_PATH}; do 796 for path in "${SEARCH_PATH[@]}"; do
797 [[ ! -d "${path}" ]] && continue
216 einfo "Cleaning orphaned Python bytecode from ${path} .." 798 einfo "Cleaning orphaned Python bytecode from ${path} .."
217 for obj in $(find ${path} -name *.py[co]); do 799 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
218 src_py="${obj%[co]}" 800 src_py="${REPLY%[co]}"
219 if [ ! -f "${src_py}" ]; then 801 [[ -f "${src_py}" || (! -f "${src_py}c" && ! -f "${src_py}o") ]] && continue
220 einfo "Purging ${src_py}[co]" 802 einfo "Purging ${src_py}[co]"
221 rm -f ${src_py}[co] 803 rm -f "${src_py}"[co]
222 fi
223 done 804 done
805
224 # attempt to remove directories that maybe empty 806 # Attempt to remove directories that may be empty.
225 for dir in $(find ${path} -type d | sort -r); do 807 find "${path}" -type d | sort -r | while read -r dir; do
226 rmdir ${dir} 2>/dev/null 808 rmdir "${dir}" 2>/dev/null && einfo "Removing empty directory ${dir}"
227 done 809 done
228 done 810 done
229} 811}

Legend:
Removed from v.1.33  
changed lines
  Added in v.1.66

  ViewVC Help
Powered by ViewVC 1.1.20