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

Diff of /eclass/python.eclass

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

Revision 1.60 Revision 1.82
1# Copyright 1999-2009 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.60 2009/08/05 18:31:30 arfrever Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.82 2009/12/23 23:43:42 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 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}" 15 PYTHON_ATOM=">=dev-lang/python-${NEED_PYTHON}"
18 DEPEND="${PYTHON_ATOM}" 16 DEPEND="${PYTHON_ATOM}"
19 RDEPEND="${DEPEND}" 17 RDEPEND="${DEPEND}"
20else 18else
21 PYTHON_ATOM="dev-lang/python" 19 PYTHON_ATOM="dev-lang/python"
22fi 20fi
23 21
24if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
25 DEPEND="${DEPEND} >=app-admin/eselect-python-20090804" 22DEPEND+=" >=app-admin/eselect-python-20090804
26fi 23 >=app-shells/bash-3.2"
27 24
28__python_eclass_test() { 25__python_eclass_test() {
29 __python_version_extract 2.3 26 __python_version_extract 2.3
30 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR" 27 echo -n "2.3 -> PYVER: $PYVER PYVER_MAJOR: $PYVER_MAJOR"
31 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO" 28 echo " PYVER_MINOR: $PYVER_MINOR PYVER_MICRO: $PYVER_MICRO"
59 56
60python_version() { 57python_version() {
61 [[ -n "${PYVER}" ]] && return 0 58 [[ -n "${PYVER}" ]] && return 0
62 local tmpstr 59 local tmpstr
63 python=${python:-/usr/bin/python} 60 python=${python:-/usr/bin/python}
64 tmpstr="$(${python} -V 2>&1 )" 61 tmpstr="$(EPYTHON= ${python} -V 2>&1 )"
65 export PYVER_ALL="${tmpstr#Python }" 62 export PYVER_ALL="${tmpstr#Python }"
66 __python_version_extract $PYVER_ALL 63 __python_version_extract $PYVER_ALL
67} 64}
68 65
69# @FUNCTION: PYTHON 66# @FUNCTION: PYTHON
70# @USAGE: [-a|--absolute-path] <Python_ABI="${PYTHON_ABI}"> 67# @USAGE: [-2] [-3] [-A|--only-ABI] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
71# @DESCRIPTION: 68# @DESCRIPTION:
72# Get Python interpreter filename for specified Python ABI. If Python_ABI argument 69# Get Python interpreter filename for specified Python ABI. If Python_ABI argument
73# is ommitted, then PYTHON_ABI environment variable must be set and is used. 70# is ommitted, then PYTHON_ABI environment variable must be set and is used.
71# If -2 option is specified, then active version of Python 2 is used.
72# If -3 option is specified, then active version of Python 3 is used.
73# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
74# -2, -3 and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
75# If --only-ABI option is specified, then only specified Python ABI is printed instead of
76# Python interpreter filename.
77# --only-ABI and --absolute-path options cannot be specified simultaneously.
74PYTHON() { 78PYTHON() {
75 local absolute_path="0" slot= 79 local absolute_path="0" final_ABI="0" only_ABI="0" python2="0" python3="0" slot=
76 80
77 while (($#)); do 81 while (($#)); do
78 case "$1" in 82 case "$1" in
83 -2)
84 python2="1"
85 ;;
86 -3)
87 python3="1"
88 ;;
89 -A|--only-ABI)
90 only_ABI="1"
91 ;;
79 -a|--absolute-path) 92 -a|--absolute-path)
80 absolute_path="1" 93 absolute_path="1"
81 ;; 94 ;;
95 -f|--final-ABI)
96 final_ABI="1"
97 ;;
98 --)
99 break
100 ;;
82 -*) 101 -*)
83 die "${FUNCNAME}(): Unrecognized option $1" 102 die "${FUNCNAME}(): Unrecognized option '$1'"
84 ;; 103 ;;
85 *) 104 *)
86 break 105 break
87 ;; 106 ;;
88 esac 107 esac
89 shift 108 shift
90 done 109 done
91 110
111 if [[ "${only_ABI}" == "1" && "${absolute_path}" == "1" ]]; then
112 die "${FUNCNAME}(): '--only-ABI and '--absolute-path' options cannot be specified simultaneously"
113 fi
114
115 if [[ "$((${python2} + ${python3} + ${final_ABI}))" -gt "1" ]]; then
116 die "${FUNCNAME}(): '-2', '-3' or '--final-ABI' options cannot be specified simultaneously"
117 fi
118
92 if [[ "$#" -eq "0" ]]; then 119 if [[ "$#" -eq "0" ]]; then
120 if [[ "${final_ABI}" == "1" ]]; then
121 validate_PYTHON_ABIS
122 slot="${PYTHON_ABIS##* }"
123 elif [[ "${python2}" == "1" ]]; then
124 slot="$(eselect python show --python2)"
125 if [[ -z "${slot}" ]]; then
126 die "${FUNCNAME}(): Active Python 2 interpreter not set"
127 elif [[ "${slot}" != "python2."* ]]; then
128 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
129 fi
130 slot="${slot#python}"
131 elif [[ "${python3}" == "1" ]]; then
132 slot="$(eselect python show --python3)"
133 if [[ -z "${slot}" ]]; then
134 die "${FUNCNAME}(): Active Python 3 interpreter not set"
135 elif [[ "${slot}" != "python3."* ]]; then
136 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
137 fi
138 slot="${slot#python}"
93 if [[ -n "${PYTHON_ABI}" ]]; then 139 elif [[ -n "${PYTHON_ABI}" ]]; then
94 slot="${PYTHON_ABI}" 140 slot="${PYTHON_ABI}"
95 else 141 else
96 die "${FUNCNAME}(): Invalid usage" 142 die "${FUNCNAME}(): Invalid usage"
97 fi 143 fi
98 elif [[ "$#" -eq "1" ]]; then 144 elif [[ "$#" -eq "1" ]]; then
145 if [[ "${final_ABI}" == "1" ]]; then
146 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
147 fi
148 if [[ "${python2}" == "1" ]]; then
149 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
150 fi
151 if [[ "${python3}" == "1" ]]; then
152 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
153 fi
99 slot="$1" 154 slot="$1"
100 else 155 else
101 die "${FUNCNAME}(): Invalid usage" 156 die "${FUNCNAME}(): Invalid usage"
102 fi 157 fi
103 158
159 if [[ "${only_ABI}" == "1" ]]; then
160 echo -n "${slot}"
161 return
104 if [[ "${absolute_path}" == "1" ]]; then 162 elif [[ "${absolute_path}" == "1" ]]; then
105 echo -n "/usr/bin/python${slot}" 163 echo -n "/usr/bin/python${slot}"
106 else 164 else
107 echo -n "python${slot}" 165 echo -n "python${slot}"
108 fi 166 fi
167
168 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
169 echo -n "-${ABI}"
170 fi
109} 171}
172
173# @FUNCTION: python_set_active_version
174# @USAGE: <Python_ABI|2|3>
175# @DESCRIPTION:
176# Set active version of Python.
177python_set_active_version() {
178 if [[ "$#" -ne "1" ]]; then
179 die "${FUNCNAME}() requires 1 argument"
180 fi
181
182 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
183 if ! has_version "dev-lang/python:$1"; then
184 die "${FUNCNAME}(): 'dev-lang/python:$1' isn't installed"
185 fi
186 export EPYTHON="$(PYTHON "$1")"
187 elif [[ "$1" == "2" ]]; then
188 if ! has_version "=dev-lang/python-2*"; then
189 die "${FUNCNAME}(): '=dev-lang/python-2*' isn't installed"
190 fi
191 export EPYTHON="$(PYTHON -2)"
192 elif [[ "$1" == "3" ]]; then
193 if ! has_version "=dev-lang/python-3*"; then
194 die "${FUNCNAME}(): '=dev-lang/python-3*' isn't installed"
195 fi
196 export EPYTHON="$(PYTHON -3)"
197 else
198 die "${FUNCNAME}(): Unrecognized argument '$1'"
199 fi
200
201 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
202 # so it doesn't need to be exported to subprocesses.
203 PYTHON_ABI="${EPYTHON#python}"
204 PYTHON_ABI="${PYTHON_ABI%%-*}"
205}
206
207unset PYTHON_ABIS
208unset PYTHON_ABIS_SANITY_CHECKS
110 209
111# @FUNCTION: validate_PYTHON_ABIS 210# @FUNCTION: validate_PYTHON_ABIS
112# @DESCRIPTION: 211# @DESCRIPTION:
113# Make sure PYTHON_ABIS variable has valid value. 212# Ensure that PYTHON_ABIS variable has valid value.
114validate_PYTHON_ABIS() { 213validate_PYTHON_ABIS() {
214 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 2 without setting SUPPORT_PYTHON_ABIS variable.
215 if has "${EAPI:-0}" 0 1 2 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
216 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
217 fi
218
115 # Ensure that /usr/bin/python and /usr/bin/python-config are valid. 219 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
116 if [[ "$(</usr/bin/python)" != *"Gentoo Python wrapper program"* ]]; then 220 if [[ "$(readlink /usr/bin/python)" != "python-wrapper" ]]; then
117 die "/usr/bin/python isn't valid program" 221 die "'/usr/bin/python' isn't valid symlink"
118 fi 222 fi
119 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then 223 if [[ "$(</usr/bin/python-config)" != *"Gentoo python-config wrapper script"* ]]; then
120 die "/usr/bin/python-config isn't valid script" 224 die "'/usr/bin/python-config' isn't valid script"
121 fi 225 fi
122 226
123 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 4. 227 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 5.
124 if [[ -z "${PYTHON_ABIS}" ]] && has "${EAPI:-0}" 0 1 2 3; then 228 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3 4; then
125 local ABI support_ABI supported_PYTHON_ABIS= restricted_ABI 229 local PYTHON_ABI python2_supported_versions python3_supported_versions restricted_ABI support_ABI supported_PYTHON_ABIS=
126 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2" 230 PYTHON_ABI_SUPPORTED_VALUES="2.4 2.5 2.6 2.7 3.0 3.1 3.2"
231 python2_supported_versions="2.4 2.5 2.6 2.7"
232 python3_supported_versions="3.0 3.1 3.2"
233
234 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
235 local python2_enabled="0" python3_enabled="0"
236
237 if [[ -z "${USE_PYTHON}" ]]; then
238 die "USE_PYTHON variable is empty"
239 fi
240
127 for ABI in ${USE_PYTHON}; do 241 for PYTHON_ABI in ${USE_PYTHON}; do
128 if ! has "${ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then 242 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
129 ewarn "Ignoring unsupported Python ABI '${ABI}'" 243 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
130 continue
131 fi 244 fi
245
246 if has "${PYTHON_ABI}" ${python2_supported_versions}; then
247 python2_enabled="1"
248 fi
249 if has "${PYTHON_ABI}" ${python3_supported_versions}; then
250 python3_enabled="1"
251 fi
252
132 support_ABI="1" 253 support_ABI="1"
133 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do 254 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
134 if python -c "from fnmatch import fnmatch; exit(not fnmatch('${ABI}', '${restricted_ABI}'))"; then 255 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
135 support_ABI="0" 256 support_ABI="0"
136 break 257 break
137 fi 258 fi
259 done
260 [[ "${support_ABI}" == "1" ]] && export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
138 done 261 done
139 [[ "${support_ABI}" == "1" ]] && supported_PYTHON_ABIS+=" ${ABI}" 262
263 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
264 die "USE_PYTHON variable doesn't enable any version of Python supported by ${CATEGORY}/${PF}"
265 fi
266
267 if [[ "${python2_enabled}" == "0" ]]; then
268 ewarn "USE_PYTHON variable doesn't enable any version of Python 2. This configuration is unsupported."
269 fi
270 if [[ "${python3_enabled}" == "0" ]]; then
271 ewarn "USE_PYTHON variable doesn't enable any version of Python 3. This configuration is unsupported."
272 fi
273 else
274 local python_version python2_version= python3_version= support_python_major_version
275
276 python_version="$(/usr/bin/python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
277
278 if has_version "=dev-lang/python-2*"; then
279 if [[ "$(readlink /usr/bin/python2)" != "python2."* ]]; then
280 die "'/usr/bin/python2' isn't valid symlink"
281 fi
282
283 python2_version="$(/usr/bin/python2 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
284
285 for PYTHON_ABI in ${python2_supported_versions}; do
286 support_python_major_version="1"
287 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
288 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
289 support_python_major_version="0"
290 fi
291 done
292 [[ "${support_python_major_version}" == "1" ]] && break
293 done
294 if [[ "${support_python_major_version}" == "1" ]]; then
295 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
296 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
297 die "Active version of Python 2 isn't supported by ${CATEGORY}/${PF}"
298 fi
299 done
300 else
301 python2_version=""
302 fi
303 fi
304
305 if has_version "=dev-lang/python-3*"; then
306 if [[ "$(readlink /usr/bin/python3)" != "python3."* ]]; then
307 die "'/usr/bin/python3' isn't valid symlink"
308 fi
309
310 python3_version="$(/usr/bin/python3 -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')"
311
312 for PYTHON_ABI in ${python3_supported_versions}; do
313 support_python_major_version="1"
314 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
315 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
316 support_python_major_version="0"
317 fi
318 done
319 [[ "${support_python_major_version}" == "1" ]] && break
320 done
321 if [[ "${support_python_major_version}" == "1" ]]; then
322 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
323 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
324 die "Active version of Python 3 isn't supported by ${CATEGORY}/${PF}"
325 fi
326 done
327 else
328 python3_version=""
329 fi
330 fi
331
332 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
333 eerror "Python wrapper is configured incorrectly or /usr/bin/python2 symlink"
334 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
335 die "Incorrect configuration of Python"
336 fi
337 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
338 eerror "Python wrapper is configured incorrectly or /usr/bin/python3 symlink"
339 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
340 die "Incorrect configuration of Python"
341 fi
342
343 PYTHON_ABIS="${python2_version} ${python3_version}"
344 PYTHON_ABIS="${PYTHON_ABIS# }"
345 export PYTHON_ABIS="${PYTHON_ABIS% }"
346 fi
347 fi
348
349 if [[ "$(declare -p PYTHON_ABIS_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_ABIS_SANITY_CHECKS="* ]]; then
350 local PYTHON_ABI
351 for PYTHON_ABI in ${PYTHON_ABIS}; do
352 # Ensure that appropriate version of Python is installed.
353 if ! has_version "dev-lang/python:${PYTHON_ABI}"; then
354 die "dev-lang/python:${PYTHON_ABI} isn't installed"
355 fi
356
357 # Ensure that EPYTHON variable is respected.
358 if [[ "$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')" != "${PYTHON_ABI}" ]]; then
359 eerror "python: '$(type -p python)'"
360 eerror "ABI: '${ABI}'"
361 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'"
362 eerror "EPYTHON: '$(PYTHON)'"
363 eerror "PYTHON_ABI: '${PYTHON_ABI}'"
364 eerror "Version of enabled Python: '$(EPYTHON="$(PYTHON)" python -c 'from sys import version_info; print(".".join([str(x) for x in version_info[:2]]))')'"
365 die "'python' doesn't respect EPYTHON variable"
366 fi
140 done 367 done
141 export PYTHON_ABIS="${supported_PYTHON_ABIS# }" 368 PYTHON_ABIS_SANITY_CHECKS="1"
142 fi
143
144 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
145 python_version
146 export PYTHON_ABIS="${PYVER}"
147 fi 369 fi
148} 370}
149 371
150# @FUNCTION: python_copy_sources 372# @FUNCTION: python_copy_sources
151# @USAGE: [directory] 373# @USAGE: [--no-link] [--] [directory]
152# @DESCRIPTION: 374# @DESCRIPTION:
153# Copy unpacked sources of given package for each Python ABI. 375# Copy unpacked sources of given package for each Python ABI.
154python_copy_sources() { 376python_copy_sources() {
155 local dir dirs=() PYTHON_ABI 377 local dir dirs=() no_link="0" PYTHON_ABI
378
379 while (($#)); do
380 case "$1" in
381 --no-link)
382 no_link="1"
383 ;;
384 --)
385 break
386 ;;
387 -*)
388 die "${FUNCNAME}(): Unrecognized option '$1'"
389 ;;
390 *)
391 break
392 ;;
393 esac
394 shift
395 done
156 396
157 if [[ "$#" -eq "0" ]]; then 397 if [[ "$#" -eq "0" ]]; then
158 if [[ "${WORKDIR}" == "${S}" ]]; then 398 if [[ "${WORKDIR}" == "${S}" ]]; then
159 die "${FUNCNAME}() cannot be used" 399 die "${FUNCNAME}() cannot be used"
160 fi 400 fi
164 fi 404 fi
165 405
166 validate_PYTHON_ABIS 406 validate_PYTHON_ABIS
167 for PYTHON_ABI in ${PYTHON_ABIS}; do 407 for PYTHON_ABI in ${PYTHON_ABIS}; do
168 for dir in "${dirs[@]}"; do 408 for dir in "${dirs[@]}"; do
409 if [[ "${no_link}" == "1" ]]; then
410 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
411 else
169 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed" 412 cp -lpr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
413 fi
170 done 414 done
171 done 415 done
172} 416}
173 417
174# @FUNCTION: python_set_build_dir_symlink 418# @FUNCTION: python_set_build_dir_symlink
176# @DESCRIPTION: 420# @DESCRIPTION:
177# Create build directory symlink. 421# Create build directory symlink.
178python_set_build_dir_symlink() { 422python_set_build_dir_symlink() {
179 local dir="$1" 423 local dir="$1"
180 424
181 [[ -z "${PYTHON_ABIS}" ]] && die "PYTHON_ABIS variable not set" 425 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
182 [[ -z "${dir}" ]] && dir="build" 426 [[ -z "${dir}" ]] && dir="build"
183 427
184 # Don't delete preexistent directories. 428 # Don't delete preexistent directories.
185 rm -f "${dir}" || die "Deletion of '${dir}' failed" 429 rm -f "${dir}" || die "Deletion of '${dir}' failed"
186 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed" 430 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
187} 431}
188 432
189# @FUNCTION: python_execute_function 433# @FUNCTION: python_execute_function
190# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] <function> [arguments] 434# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
191# @DESCRIPTION: 435# @DESCRIPTION:
192# Execute specified function for each value of PYTHON_ABIS, optionally passing additional 436# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
193# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables. 437# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
194python_execute_function() { 438python_execute_function() {
195 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" 439 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=
196 440
197 while (($#)); do 441 while (($#)); do
198 case "$1" in 442 case "$1" in
199 --action-message) 443 --action-message)
200 action_message_template="$2" 444 action_message_template="$2"
214 quiet="1" 458 quiet="1"
215 ;; 459 ;;
216 -s|--separate-build-dirs) 460 -s|--separate-build-dirs)
217 separate_build_dirs="1" 461 separate_build_dirs="1"
218 ;; 462 ;;
463 --source-dir)
464 source_dir="$2"
465 shift
466 ;;
467 --)
468 break
469 ;;
219 -*) 470 -*)
220 die "${FUNCNAME}(): Unrecognized option $1" 471 die "${FUNCNAME}(): Unrecognized option '$1'"
221 ;; 472 ;;
222 *) 473 *)
223 break 474 break
224 ;; 475 ;;
225 esac 476 esac
226 shift 477 shift
227 done 478 done
479
480 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
481 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
482 fi
228 483
229 if [[ "${default_function}" == "0" ]]; then 484 if [[ "${default_function}" == "0" ]]; then
230 if [[ "$#" -eq "0" ]]; then 485 if [[ "$#" -eq "0" ]]; then
231 die "${FUNCNAME}(): Missing function name" 486 die "${FUNCNAME}(): Missing function name"
232 fi 487 fi
233 function="$1" 488 function="$1"
234 shift 489 shift
490
491 if [[ -z "$(type -t "${function}")" ]]; then
492 die "${FUNCNAME}(): '${function}' function isn't defined"
493 fi
235 else 494 else
236 if [[ "$#" -ne "0" ]]; then 495 if [[ "$#" -ne "0" ]]; then
237 die "${FUNCNAME}(): --default-function option and function name cannot be specified simultaneously" 496 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
238 fi 497 fi
239 if has "${EAPI:-0}" 0 1; then 498 if has "${EAPI:-0}" 0 1; then
240 die "${FUNCNAME}(): --default-function option cannot be used in this EAPI" 499 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
241 fi 500 fi
242 501
243 if [[ "${EBUILD_PHASE}" == "configure" ]]; then 502 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
503 if has "${EAPI}" 2 3; then
244 python_default_function() { 504 python_default_function() {
245 econf 505 econf
246 } 506 }
507 else
508 python_default_function() {
509 nonfatal econf
510 }
511 fi
247 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then 512 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
248 python_default_function() { 513 python_default_function() {
249 emake 514 emake
250 } 515 }
251 elif [[ "${EBUILD_PHASE}" == "test" ]]; then 516 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
259 elif [[ "${EBUILD_PHASE}" == "install" ]]; then 524 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
260 python_default_function() { 525 python_default_function() {
261 emake DESTDIR="${D}" install 526 emake DESTDIR="${D}" install
262 } 527 }
263 else 528 else
264 die "${FUNCNAME}(): --default-function option cannot be used in this ebuild phase" 529 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
265 fi 530 fi
266 function="python_default_function" 531 function="python_default_function"
267 fi 532 fi
268 533
269 if [[ "${quiet}" == "0" ]]; then 534 if [[ "${quiet}" == "0" ]]; then
301 else 566 else
302 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..." 567 action_message="${action} of ${CATEGORY}/${PF} with Python ${PYTHON_ABI}..."
303 fi 568 fi
304 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}" 569 echo " ${GREEN}*${NORMAL} ${BLUE}${action_message}${NORMAL}"
305 fi 570 fi
571
306 if [[ "${separate_build_dirs}" == "1" ]]; then 572 if [[ "${separate_build_dirs}" == "1" ]]; then
573 if [[ -n "${source_dir}" ]]; then
574 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
575 else
307 export BUILDDIR="${S}-${PYTHON_ABI}" 576 export BUILDDIR="${S}-${PYTHON_ABI}"
577 fi
308 pushd "${BUILDDIR}" > /dev/null || die "pushd failed" 578 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
309 else 579 else
310 export BUILDDIR="${S}" 580 export BUILDDIR="${S}"
311 fi 581 fi
582
583 previous_directory="$(pwd)"
584 previous_directory_stack="$(dirs -p)"
585 previous_directory_stack_length="$(dirs -p | wc -l)"
586
587 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
588 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
589 else
312 if ! EPYTHON="$(PYTHON)" "${function}" "$@"; then 590 EPYTHON="$(PYTHON)" "${function}" "$@"
591 fi
592
593 if [[ "$?" != "0" ]]; then
313 if [[ -n "${failure_message_template}" ]]; then 594 if [[ -n "${failure_message_template}" ]]; then
314 failure_message="$(eval echo -n "${failure_message_template}")" 595 failure_message="$(eval echo -n "${failure_message_template}")"
315 else 596 else
316 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function" 597 failure_message="${action} failed with Python ${PYTHON_ABI} in ${function}() function"
317 fi 598 fi
318 if [[ "${nonfatal}" == "1" ]] || has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then 599
319 local ABI enabled_PYTHON_ABIS 600 if [[ "${nonfatal}" == "1" ]]; then
320 for ABI in ${PYTHON_ABIS}; do
321 [[ "${ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+=" ${ABI}"
322 done
323 export PYTHON_ABIS="${enabled_PYTHON_ABIS# }"
324 if [[ "${quiet}" == "0" ]]; then 601 if [[ "${quiet}" == "0" ]]; then
325 ewarn "${RED}${failure_message}${NORMAL}" 602 ewarn "${RED}${failure_message}${NORMAL}"
326 fi 603 fi
604 elif has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
605 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
606 local enabled_PYTHON_ABIS= other_PYTHON_ABI
607 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
608 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
609 done
610 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
611 fi
612 if [[ "${quiet}" == "0" ]]; then
613 ewarn "${RED}${failure_message}${NORMAL}"
614 fi
615 if [[ -z "${PYTHON_ABIS}" ]]; then
616 die "${function}() function failed with all enabled versions of Python"
617 fi
327 else 618 else
328 die "${failure_message}" 619 die "${failure_message}"
329 fi 620 fi
330 fi 621 fi
622
623 # Ensure that directory stack hasn't been decreased.
624 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
625 die "Directory stack decreased illegally"
626 fi
627
628 # Avoid side effects of earlier returning from the specified function.
629 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
630 popd > /dev/null || die "popd failed"
631 done
632
633 # Ensure that the bottom part of directory stack hasn't been changed. Restore
634 # previous directory (from before running of the specified function) before
635 # comparison of directory stacks to avoid mismatch of directory stacks after
636 # potential using of 'cd' to change current directory. Restoration of previous
637 # directory allows to safely use 'cd' to change current directory in the
638 # specified function without changing it back to original directory.
639 cd "${previous_directory}"
640 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
641 die "Directory stack changed illegally"
642 fi
643
331 if [[ "${separate_build_dirs}" == "1" ]]; then 644 if [[ "${separate_build_dirs}" == "1" ]]; then
332 popd > /dev/null || die "popd failed" 645 popd > /dev/null || die "popd failed"
333 fi 646 fi
334 unset BUILDDIR 647 unset BUILDDIR
335 done 648 done
337 if [[ "${default_function}" == "1" ]]; then 650 if [[ "${default_function}" == "1" ]]; then
338 unset -f python_default_function 651 unset -f python_default_function
339 fi 652 fi
340} 653}
341 654
655# @FUNCTION: python_convert_shebangs
656# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories]
657# @DESCRIPTION:
658# Convert shebangs in specified files. Directories can be specified only with --recursive option.
659python_convert_shebangs() {
660 local argument file files=() only_executables="0" python_version quiet="0" recursive="0"
661
662 while (($#)); do
663 case "$1" in
664 -r|--recursive)
665 recursive="1"
666 ;;
667 -q|--quiet)
668 quiet="1"
669 ;;
670 -x|--only-executables)
671 only_executables="1"
672 ;;
673 --)
674 break
675 ;;
676 -*)
677 die "${FUNCNAME}(): Unrecognized option '$1'"
678 ;;
679 *)
680 break
681 ;;
682 esac
683 shift
684 done
685
686 if [[ "$#" -eq 0 ]]; then
687 die "${FUNCNAME}(): Missing Python version and files or directories"
688 elif [[ "$#" -eq 1 ]]; then
689 die "${FUNCNAME}(): Missing files or directories"
690 fi
691
692 python_version="$1"
693 shift
694
695 for argument in "$@"; do
696 if [[ ! -e "${argument}" ]]; then
697 die "${FUNCNAME}(): '${argument}' doesn't exist"
698 elif [[ -f "${argument}" ]]; then
699 files+=("${argument}")
700 elif [[ -d "${argument}" ]]; then
701 if [[ "${recursive}" == "1" ]]; then
702 if [[ "${only_executables}" == "1" ]]; then
703 files+=($(find "${argument}" -perm /111 -type f))
704 else
705 files+=($(find "${argument}" -type f))
706 fi
707 else
708 die "${FUNCNAME}(): '${argument}' isn't a regular file"
709 fi
710 else
711 die "${FUNCNAME}(): '${argument}' isn't a regular file or a directory"
712 fi
713 done
714
715 for file in "${files[@]}"; do
716 file="${file#./}"
717 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
718
719 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then
720 if [[ "${quiet}" == "0" ]]; then
721 einfo "Converting shebang in '${file}'"
722 fi
723 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
724
725 # Delete potential whitespace after "#!".
726 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed"
727 fi
728 done
729}
730
731# @FUNCTION: python_generate_wrapper_scripts
732# @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
733# @DESCRIPTION:
734# Generate wrapper scripts. Existing files are overwritten only with --force option.
735# If --respect-EPYTHON option is specified, then generated wrapper scripts will
736# respect EPYTHON variable at run time.
737python_generate_wrapper_scripts() {
738 local eselect_python_option file force="0" quiet="0" PYTHON_ABI python2_enabled="0" python2_supported_versions python3_enabled="0" python3_supported_versions respect_EPYTHON="0"
739 python2_supported_versions="2.4 2.5 2.6 2.7"
740 python3_supported_versions="3.0 3.1 3.2"
741
742 while (($#)); do
743 case "$1" in
744 -E|--respect-EPYTHON)
745 respect_EPYTHON="1"
746 ;;
747 -f|--force)
748 force="1"
749 ;;
750 -q|--quiet)
751 quiet="1"
752 ;;
753 --)
754 break
755 ;;
756 -*)
757 die "${FUNCNAME}(): Unrecognized option '$1'"
758 ;;
759 *)
760 break
761 ;;
762 esac
763 shift
764 done
765
766 if [[ "$#" -eq 0 ]]; then
767 die "${FUNCNAME}(): Missing arguments"
768 fi
769
770 validate_PYTHON_ABIS
771 for PYTHON_ABI in ${python2_supported_versions}; do
772 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
773 python2_enabled="1"
774 fi
775 done
776 for PYTHON_ABI in ${python3_supported_versions}; do
777 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
778 python3_enabled="1"
779 fi
780 done
781
782 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
783 eselect_python_option=
784 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
785 eselect_python_option="--python2"
786 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
787 eselect_python_option="--python3"
788 else
789 die "${FUNCNAME}(): Unsupported environment"
790 fi
791
792 for file in "$@"; do
793 if [[ -f "${file}" && "${force}" == "0" ]]; then
794 die "${FUNCNAME}(): '$1' already exists"
795 fi
796
797 if [[ "${quiet}" == "0" ]]; then
798 einfo "Generating '${file#${D%/}}' wrapper script"
799 fi
800
801 cat << EOF > "${file}"
802#!/usr/bin/env python
803# Gentoo '${file##*/}' wrapper script
804
805import os
806import re
807import subprocess
808import sys
809
810EPYTHON_re = re.compile(r"^python(\d+\.\d+)$")
811
812EOF
813 if [[ "$?" != "0" ]]; then
814 die "${FUNCNAME}(): Generation of '$1' failed"
815 fi
816 if [[ "${respect_EPYTHON}" == "1" ]]; then
817 cat << EOF >> "${file}"
818EPYTHON = os.environ.get("EPYTHON")
819if EPYTHON:
820 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
821 if EPYTHON_matched:
822 PYTHON_ABI = EPYTHON_matched.group(1)
823 else:
824 sys.stderr.write("EPYTHON variable has unrecognized value '%s'\n" % EPYTHON)
825 sys.exit(1)
826else:
827 try:
828 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
829 if eselect_process.wait() != 0:
830 raise ValueError
831 except (OSError, ValueError):
832 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
833 sys.exit(1)
834
835 eselect_output = eselect_process.stdout.read()
836 if not isinstance(eselect_output, str):
837 # Python 3
838 eselect_output = eselect_output.decode()
839
840 EPYTHON_matched = EPYTHON_re.match(eselect_output)
841 if EPYTHON_matched:
842 PYTHON_ABI = EPYTHON_matched.group(1)
843 else:
844 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
845 sys.exit(1)
846EOF
847 if [[ "$?" != "0" ]]; then
848 die "${FUNCNAME}(): Generation of '$1' failed"
849 fi
850 else
851 cat << EOF >> "${file}"
852try:
853 eselect_process = subprocess.Popen(["/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
854 if eselect_process.wait() != 0:
855 raise ValueError
856except (OSError, ValueError):
857 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
858 sys.exit(1)
859
860eselect_output = eselect_process.stdout.read()
861if not isinstance(eselect_output, str):
862 # Python 3
863 eselect_output = eselect_output.decode()
864
865EPYTHON_matched = EPYTHON_re.match(eselect_output)
866if EPYTHON_matched:
867 PYTHON_ABI = EPYTHON_matched.group(1)
868else:
869 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
870 sys.exit(1)
871EOF
872 if [[ "$?" != "0" ]]; then
873 die "${FUNCNAME}(): Generation of '$1' failed"
874 fi
875 fi
876 cat << EOF >> "${file}"
877
878target_executable = "%s-%s" % (sys.argv[0], PYTHON_ABI)
879if not os.path.exists(target_executable):
880 sys.stderr.write("'%s' does not exist\n" % target_executable)
881 sys.exit(1)
882
883os.execv(target_executable, sys.argv)
884EOF
885 if [[ "$?" != "0" ]]; then
886 die "${FUNCNAME}(): Generation of '$1' failed"
887 fi
888 fperms +x "${file#${D%/}}" || die "fperms '${file}' failed"
889 done
890}
342 891
343# @ECLASS-VARIABLE: PYTHON_USE_WITH 892# @ECLASS-VARIABLE: PYTHON_USE_WITH
344# @DESCRIPTION: 893# @DESCRIPTION:
345# Set this to a space separated list of use flags 894# Set this to a space separated list of use flags
346# the python slot in use must be built with. 895# the python slot in use must be built with.
358 907
359# @FUNCTION: python_pkg_setup 908# @FUNCTION: python_pkg_setup
360# @DESCRIPTION: 909# @DESCRIPTION:
361# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags 910# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
362# are respected. Only exported if one of those variables is set. 911# are respected. Only exported if one of those variables is set.
363if ! has ${EAPI} 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then 912if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
913 python_pkg_setup() {
364 python_pkg_setup_fail() { 914 python_pkg_setup_fail() {
365 eerror "${1}" 915 eerror "${1}"
366 die "${1}" 916 die "${1}"
917 }
918
919 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
920
921 python_pkg_setup_check_USE_flags() {
922 local pyatom use
923 if [[ -n "${PYTHON_ABI}" ]]; then
924 pyatom="dev-lang/python:${PYTHON_ABI}"
925 else
926 python_version
927 pyatom="dev-lang/python:${PYVER}"
928 fi
929
930 for use in ${PYTHON_USE_WITH}; do
931 if ! has_version "${pyatom}[${use}]"; then
932 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
933 fi
934 done
935
936 for use in ${PYTHON_USE_WITH_OR}; do
937 if has_version "${pyatom}[${use}]"; then
938 return
939 fi
940 done
941
942 if [[ ${PYTHON_USE_WITH_OR} ]]; then
943 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
944 fi
945 }
946
947 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
948 python_execute_function -q python_pkg_setup_check_USE_flags
949 else
950 python_pkg_setup_check_USE_flags
951 fi
367 } 952 }
368 953
369 python_pkg_setup() {
370 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
371
372 python_version
373 local failed
374 local pyatom="dev-lang/python:${PYVER}"
375
376 for use in ${PYTHON_USE_WITH}; do
377 if ! has_version "${pyatom}[${use}]"; then
378 python_pkg_setup_fail \
379 "Please rebuild ${pyatom} with use flags: ${PYTHON_USE_WITH}"
380 fi
381 done
382
383 for use in ${PYTHON_USE_WITH_OR}; do
384 if has_version "${pyatom}[${use}]"; then
385 return
386 fi
387 done
388
389 if [[ ${PYTHON_USE_WITH_OR} ]]; then
390 python_pkg_setup_fail \
391 "Please rebuild ${pyatom} with one of: ${PYTHON_USE_WITH_OR}"
392 fi
393 }
394
395 EXPORT_FUNCTIONS pkg_setup 954 EXPORT_FUNCTIONS pkg_setup
396 955
397 if [[ ${PYTHON_USE_WITH} ]]; then 956 if [[ -n "${PYTHON_USE_WITH}" ]]; then
398 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]" 957 PYTHON_USE_WITH_ATOM="${PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]"
399 elif [[ ${PYTHON_USE_WITH_OR} ]]; then 958 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
400 PYTHON_USE_WITH_ATOM="|| ( " 959 PYTHON_USE_WITH_ATOM="|| ( "
401 for use in ${PYTHON_USE_WITH_OR}; do 960 for use in ${PYTHON_USE_WITH_OR}; do
402 PYTHON_USE_WITH_ATOM=" 961 PYTHON_USE_WITH_ATOM+=" ${PYTHON_ATOM}[${use}]"
403 ${PYTHON_USE_WITH_ATOM}
404 ${PYTHON_ATOM}[${use}]"
405 done 962 done
406 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_ATOM} )" 963 unset use
964 PYTHON_USE_WITH_ATOM+=" )"
407 fi 965 fi
408 if [[ ${PYTHON_USE_WITH_OPT} ]]; then 966 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
409 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )" 967 PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${PYTHON_USE_WITH_ATOM} )"
410 fi 968 fi
411 DEPEND="${PYTHON_USE_WITH_ATOM}" 969 DEPEND+=" ${PYTHON_USE_WITH_ATOM}"
412 RDEPEND="${PYTHON_USE_WITH_ATOM}" 970 RDEPEND+=" ${PYTHON_USE_WITH_ATOM}"
413fi 971fi
414 972
973# @ECLASS-VARIABLE: PYTHON_DEFINE_DEFAULT_FUNCTIONS
974# @DESCRIPTION:
975# Set this to define default functions for the following ebuild phases:
976# src_prepare, src_configure, src_compile, src_test, src_install.
977if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_DEFINE_DEFAULT_FUNCTIONS}" ]]; then
978 python_src_prepare() {
979 python_copy_sources
980 }
981
982 for python_default_function in src_configure src_compile src_test src_install; do
983 eval "python_${python_default_function}() { python_execute_function -d -s; }"
984 done
985 unset python_default_function
986
987 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
988fi
989
415# @FUNCTION: python_disable_pyc 990# @FUNCTION: python_disable_pyc
416# @DESCRIPTION: 991# @DESCRIPTION:
417# Tells python not to automatically recompile modules to .pyc/.pyo 992# Tell Python not to automatically recompile modules to .pyc/.pyo
418# even if the timestamps/version stamps don't match. This is done 993# even if the timestamps/version stamps don't match. This is done
419# to protect sandbox. 994# to protect sandbox.
420#
421# note: supported by >=dev-lang/python-2.2.3-r3 only.
422#
423python_disable_pyc() { 995python_disable_pyc() {
424 export PYTHONDONTWRITEBYTECODE=1 # For 2.6 and above 996 export PYTHONDONTWRITEBYTECODE="1"
425 export PYTHON_DONTCOMPILE=1 # For 2.5 and below
426} 997}
427 998
428# @FUNCTION: python_enable_pyc 999# @FUNCTION: python_enable_pyc
429# @DESCRIPTION: 1000# @DESCRIPTION:
430# Tells python to automatically recompile modules to .pyc/.pyo if the 1001# Tell Python to automatically recompile modules to .pyc/.pyo if the
431# timestamps/version stamps change 1002# timestamps/version stamps have changed.
432python_enable_pyc() { 1003python_enable_pyc() {
433 unset PYTHONDONTWRITEBYTECODE 1004 unset PYTHONDONTWRITEBYTECODE
434 unset PYTHON_DONTCOMPILE
435} 1005}
436
437python_disable_pyc
438 1006
439# @FUNCTION: python_need_rebuild 1007# @FUNCTION: python_need_rebuild
440# @DESCRIPTION: Run without arguments, specifies that the package should be 1008# @DESCRIPTION: Run without arguments, specifies that the package should be
441# rebuilt after a python upgrade. 1009# rebuilt after a python upgrade.
442python_need_rebuild() { 1010python_need_rebuild() {
471# @FUNCTION: python_get_sitedir 1039# @FUNCTION: python_get_sitedir
472# @DESCRIPTION: 1040# @DESCRIPTION:
473# Run without arguments, returns the Python site-packages directory. 1041# Run without arguments, returns the Python site-packages directory.
474python_get_sitedir() { 1042python_get_sitedir() {
475 echo "$(python_get_libdir)/site-packages" 1043 echo "$(python_get_libdir)/site-packages"
476}
477
478# @FUNCTION: python_makesym
479# @DESCRIPTION:
480# Run without arguments, it will create the /usr/bin/python symlinks
481# to the latest installed version
482python_makesym() {
483 alternatives_auto_makesym "/usr/bin/python" "python[0-9].[0-9]"
484 alternatives_auto_makesym "/usr/bin/python2" "python2.[0-9]"
485} 1044}
486 1045
487# @FUNCTION: python_tkinter_exists 1046# @FUNCTION: python_tkinter_exists
488# @DESCRIPTION: 1047# @DESCRIPTION:
489# Run without arguments, checks if python was compiled with Tkinter 1048# Run without arguments, checks if python was compiled with Tkinter
533 1092
534 # Check if phase is pkg_postinst() 1093 # Check if phase is pkg_postinst()
535 [[ ${EBUILD_PHASE} != postinst ]] &&\ 1094 [[ ${EBUILD_PHASE} != postinst ]] &&\
536 die "${FUNCNAME} should only be run in pkg_postinst()" 1095 die "${FUNCNAME} should only be run in pkg_postinst()"
537 1096
538 # allow compiling for older python versions
539 if [[ "${PYTHON_OVERRIDE_PYVER}" ]]; then 1097 if [[ -n "${PYTHON_ABI}" ]]; then
540 PYVER=${PYTHON_OVERRIDE_PYVER} 1098 PYVER="${PYTHON_ABI}"
541 else 1099 else
542 python_version 1100 python_version
543 fi 1101 fi
544 1102
545 # strip trailing slash 1103 # strip trailing slash
550 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}") 1108 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
551 done 1109 done
552 1110
553 if ((${#myfiles[@]})); then 1111 if ((${#myfiles[@]})); then
554 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1112 python${PYVER} ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}"
555 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" 1113 python${PYVER} -O ${myroot}/usr/$(get_libdir)/python${PYVER}/py_compile.py "${myfiles[@]}" &> /dev/null
556 else 1114 else
557 ewarn "No files to compile!" 1115 ewarn "No files to compile!"
558 fi 1116 fi
559} 1117}
560 1118
608 else 1166 else
609 ewarn "'${root}/$1' doesn't exist!" 1167 ewarn "'${root}/$1' doesn't exist!"
610 fi 1168 fi
611 else 1169 else
612 for PYTHON_ABI in ${PYTHON_ABIS}; do 1170 for PYTHON_ABI in ${PYTHON_ABIS}; do
613 if [[ -d "${root}/$(python_get_sitedir)/$1" ]]; then 1171 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
614 site_packages_dirs+=("$1") 1172 site_packages_dirs+=("$1")
615 break 1173 break
616 elif [[ -f "${root}/$(python_get_sitedir)/$1" ]]; then 1174 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
617 site_packages_files+=("$1") 1175 site_packages_files+=("$1")
618 break 1176 break
619 elif [[ -e "${root}/$(python_get_sitedir)/$1" ]]; then 1177 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
620 ewarn "'$1' is not a file or a directory!" 1178 ewarn "'$1' is not a file or a directory!"
621 else 1179 else
622 ewarn "'$1' doesn't exist!" 1180 ewarn "'$1' doesn't exist!"
623 fi 1181 fi
624 done 1182 done
635 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then 1193 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then
636 return_code="0" 1194 return_code="0"
637 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}" 1195 ebegin "Compilation and optimization of Python modules for Python ${PYTHON_ABI}"
638 if ((${#site_packages_dirs[@]})); then 1196 if ((${#site_packages_dirs[@]})); then
639 for dir in "${site_packages_dirs[@]}"; do 1197 for dir in "${site_packages_dirs[@]}"; do
640 site_packages_absolute_dirs+=("${root}/$(python_get_sitedir)/${dir}") 1198 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}")
641 done 1199 done
642 "$(PYTHON)" "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1" 1200 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1"
643 "$(PYTHON)" -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1" 1201 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1"
644 fi 1202 fi
645 if ((${#site_packages_files[@]})); then 1203 if ((${#site_packages_files[@]})); then
646 for file in "${site_packages_files[@]}"; do 1204 for file in "${site_packages_files[@]}"; do
647 site_packages_absolute_files+=("${root}/$(python_get_sitedir)/${file}") 1205 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}")
648 done 1206 done
649 "$(PYTHON)" "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1" 1207 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1"
650 "$(PYTHON)" -O "${root}/$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1" 1208 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1"
651 fi 1209 fi
652 eend "${return_code}" 1210 eend "${return_code}"
653 fi 1211 fi
654 unset site_packages_absolute_dirs site_packages_absolute_files 1212 unset site_packages_absolute_dirs site_packages_absolute_files
655 done 1213 done
657 # Don't use PYTHON_ABI in next calls to python_get_libdir(). 1215 # Don't use PYTHON_ABI in next calls to python_get_libdir().
658 unset PYTHON_ABI 1216 unset PYTHON_ABI
659 1217
660 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then 1218 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
661 return_code="0" 1219 return_code="0"
662 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}..." 1220 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for Python ${PYVER}"
663 if ((${#other_dirs[@]})); then 1221 if ((${#other_dirs[@]})); then
664 python${PYVER} "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1" 1222 python${PYVER} "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1"
665 python${PYVER} -O "${root}/$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1" 1223 python${PYVER} -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
666 fi 1224 fi
667 if ((${#other_files[@]})); then 1225 if ((${#other_files[@]})); then
668 python${PYVER} "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1" 1226 python${PYVER} "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1"
669 python${PYVER} -O "${root}/$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1" 1227 python${PYVER} -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1"
670 fi 1228 fi
671 eend "${return_code}" 1229 eend "${return_code}"
672 fi 1230 fi
673 else 1231 else
674 local myroot mydirs=() myfiles=() myopts=() 1232 local myroot mydirs=() myfiles=() myopts=() return_code="0"
675 1233
676 # strip trailing slash 1234 # strip trailing slash
677 myroot="${ROOT%/}" 1235 myroot="${ROOT%/}"
678 1236
679 # respect ROOT and options passed to compileall.py 1237 # respect ROOT and options passed to compileall.py
703 ;; 1261 ;;
704 esac 1262 esac
705 shift 1263 shift
706 done 1264 done
707 1265
708 # allow compiling for older python versions
709 if [ -n "${PYTHON_OVERRIDE_PYVER}" ]; then 1266 if [[ -n "${PYTHON_ABI}" ]]; then
710 PYVER=${PYTHON_OVERRIDE_PYVER} 1267 PYVER="${PYTHON_ABI}"
711 else 1268 else
712 python_version 1269 python_version
713 fi 1270 fi
714 1271
715 # set additional opts 1272 # set additional opts
716 myopts+=(-q) 1273 myopts+=(-q)
717 1274
718 ebegin "Byte compiling python modules for python-${PYVER} .." 1275 ebegin "Compilation and optimization of Python modules for Python ${PYVER}"
719 if ((${#mydirs[@]})); then 1276 if ((${#mydirs[@]})); then
720 python${PYVER} \ 1277 python${PYVER} \
721 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \ 1278 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
722 "${myopts[@]}" "${mydirs[@]}" 1279 "${myopts[@]}" "${mydirs[@]}" || return_code="1"
723 python${PYVER} -O \ 1280 python${PYVER} -O \
724 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \ 1281 "${myroot}"/usr/$(get_libdir)/python${PYVER}/compileall.py \
725 "${myopts[@]}" "${mydirs[@]}" 1282 "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
726 fi 1283 fi
727 1284
728 if ((${#myfiles[@]})); then 1285 if ((${#myfiles[@]})); then
729 python_mod_compile "${myfiles[@]}" 1286 python_mod_compile "${myfiles[@]}"
730 fi 1287 fi
731 1288
732 eend $? 1289 eend "${return_code}"
733 fi 1290 fi
734} 1291}
735 1292
736# @FUNCTION: python_mod_cleanup 1293# @FUNCTION: python_mod_cleanup
737# @USAGE: [directory] 1294# @USAGE: [directory|file]
738# @DESCRIPTION: 1295# @DESCRIPTION:
739# Run with optional arguments, where arguments are directories of 1296# Run with optional arguments, where arguments are Python modules. If none given,
740# python modules. If none given, it will look in /usr/lib/python[0-9].[0-9]. 1297# it will look in /usr/lib/python[0-9].[0-9].
741# 1298#
742# It will recursively scan all compiled Python modules in the directories and 1299# It will recursively scan all compiled Python modules in the directories and
743# determine if they are orphaned (i.e. their corresponding .py files are missing.) 1300# determine if they are orphaned (i.e. their corresponding .py files are missing.)
744# If they are, then it will remove their corresponding .pyc and .pyo files. 1301# If they are, then it will remove their corresponding .pyc and .pyo files.
745# 1302#
746# This function should only be run in pkg_postrm(). 1303# This function should only be run in pkg_postrm().
747python_mod_cleanup() { 1304python_mod_cleanup() {
748 local PYTHON_ABI SEARCH_PATH=() root src_py 1305 local path py_file PYTHON_ABI SEARCH_PATH=() root
749 1306
750 # Check if phase is pkg_postrm(). 1307 # Check if phase is pkg_postrm().
751 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()" 1308 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME} should only be run in pkg_postrm()"
752 1309
753 # Strip trailing slash from ROOT. 1310 # Strip trailing slash from ROOT.
760 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories" 1317 die "${FUNCNAME} doesn't support absolute paths of directories/files in site-packages directories"
761 elif [[ "$1" =~ ^/ ]]; then 1318 elif [[ "$1" =~ ^/ ]]; then
762 SEARCH_PATH+=("${root}/${1#/}") 1319 SEARCH_PATH+=("${root}/${1#/}")
763 else 1320 else
764 for PYTHON_ABI in ${PYTHON_ABIS}; do 1321 for PYTHON_ABI in ${PYTHON_ABIS}; do
765 SEARCH_PATH+=("${root}/$(python_get_sitedir)/$1") 1322 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1")
766 done 1323 done
767 fi 1324 fi
768 shift 1325 shift
769 done 1326 done
770 else 1327 else
771 SEARCH_PATH=("${@#/}") 1328 SEARCH_PATH=("${@#/}")
772 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}") 1329 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
773 fi 1330 fi
774 else 1331 else
775 SEARCH_PATH=("${root}"/usr/lib*/python*/site-packages) 1332 local dir sitedir
1333 for dir in "${root}"/usr/lib*; do
1334 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
1335 for sitedir in "${dir}"/python*/site-packages; do
1336 if [[ -d "${sitedir}" ]]; then
1337 SEARCH_PATH+=("${sitedir}")
1338 fi
1339 done
1340 fi
1341 done
1342 fi
1343
1344 local BLUE CYAN NORMAL
1345 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
1346 BLUE=$'\e[1;34m'
1347 CYAN=$'\e[1;36m'
1348 NORMAL=$'\e[0m'
1349 else
1350 BLUE=
1351 CYAN=
1352 NORMAL=
776 fi 1353 fi
777 1354
778 for path in "${SEARCH_PATH[@]}"; do 1355 for path in "${SEARCH_PATH[@]}"; do
779 einfo "Cleaning orphaned Python bytecode from ${path} .." 1356 if [[ -d "${path}" ]]; then
780 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do 1357 find "${path}" -name '*.py[co]' -print0 | while read -rd ''; do
781 src_py="${REPLY%[co]}" 1358 py_file="${REPLY%[co]}"
782 [[ -f "${src_py}" ]] && continue 1359 [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue
783 einfo "Purging ${src_py}[co]" 1360 einfo "${BLUE}<<< ${py_file}[co]${NORMAL}"
784 rm -f "${src_py}"[co] 1361 rm -f "${py_file}"[co]
785 done 1362 done
786 1363
787 # Attempt to remove directories that may be empty. 1364 # Attempt to delete directories, which may be empty.
788 find "${path}" -type d | sort -r | while read -r dir; do 1365 find "${path}" -type d | sort -r | while read -r dir; do
789 rmdir "${dir}" 2>/dev/null 1366 rmdir "${dir}" 2>/dev/null && einfo "${CYAN}<<< ${dir}${NORMAL}"
790 done 1367 done
1368 elif [[ "${path}" == *.py && ! -f "${path}" && (-f "${path}c" || -f "${path}o") ]]; then
1369 einfo "${BLUE}<<< ${path}[co]${NORMAL}"
1370 rm -f "${path}"[co]
1371 fi
791 done 1372 done
792} 1373}

Legend:
Removed from v.1.60  
changed lines
  Added in v.1.82

  ViewVC Help
Powered by ViewVC 1.1.20