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

Diff of /eclass/python.eclass

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.20