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

Diff of /eclass/python.eclass

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

Revision 1.91 Revision 1.171
1# Copyright 1999-2010 Gentoo Foundation 1# Copyright 1999-2015 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.91 2010/02/28 15:49:33 arfrever Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/python.eclass,v 1.171 2015/03/31 18:43:33 ulm Exp $
4 4
5# @ECLASS: python.eclass 5# @ECLASS: python.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# Gentoo Python Project <python@gentoo.org> 7# Gentoo Python Project <python@gentoo.org>
8# @BLURB: Eclass for Python packages 8# @BLURB: Eclass for Python packages
9# @DESCRIPTION: 9# @DESCRIPTION:
10# The python eclass contains miscellaneous, useful functions for Python packages. 10# The python eclass contains miscellaneous, useful functions for Python packages.
11#
12# This eclass is DEPRECATED. Please use python-r1, python-single-r1
13# or python-any-r1 instead.
11 14
15if [[ ${_PYTHON_UTILS_R1} ]]; then
16 die 'python.eclass can not be used with python-r1 suite eclasses.'
17fi
18
19# Must call inherit before EXPORT_FUNCTIONS to avoid QA warning.
20if [[ -z "${_PYTHON_ECLASS_INHERITED}" ]]; then
12inherit multilib 21 inherit multilib
22fi
13 23
24# Export pkg_setup every time to avoid issues with eclass inheritance order.
25if ! has "${EAPI:-0}" 0 1 2 3 || { has "${EAPI:-0}" 2 3 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; }; then
26 EXPORT_FUNCTIONS pkg_setup
27fi
28
29# Avoid processing this eclass more than once.
30if [[ -z "${_PYTHON_ECLASS_INHERITED}" ]]; then
31_PYTHON_ECLASS_INHERITED="1"
32
14if ! has "${EAPI:-0}" 0 1 2 3; then 33if ! has "${EAPI:-0}" 0 1 2 3 4 5; then
15 die "API of python.eclass in EAPI=\"${EAPI}\" not established" 34 die "API of python.eclass in EAPI=\"${EAPI}\" not established"
16fi 35fi
17 36
37# Please do not add any new versions of Python here! Instead, please
38# focus on converting packages to use the new eclasses.
39
18_CPYTHON2_SUPPORTED_ABIS=(2.4 2.5 2.6 2.7) 40_CPYTHON2_GLOBALLY_SUPPORTED_ABIS=(2.4 2.5 2.6 2.7)
19_CPYTHON3_SUPPORTED_ABIS=(3.0 3.1 3.2) 41_CPYTHON3_GLOBALLY_SUPPORTED_ABIS=(3.1 3.2 3.3)
20_JYTHON_SUPPORTED_ABIS=(2.5-jython) 42_JYTHON_GLOBALLY_SUPPORTED_ABIS=(2.5-jython 2.7-jython)
43_PYPY_GLOBALLY_SUPPORTED_ABIS=(2.7-pypy-1.7 2.7-pypy-1.8 2.7-pypy-1.9 2.7-pypy-2.0)
44_PYTHON_GLOBALLY_SUPPORTED_ABIS=(${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]} ${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]} ${_JYTHON_GLOBALLY_SUPPORTED_ABIS[@]} ${_PYPY_GLOBALLY_SUPPORTED_ABIS[@]})
45
46# ================================================================================================
47# ===================================== HANDLING OF METADATA =====================================
48# ================================================================================================
49
50_PYTHON_ABI_PATTERN_REGEX="([[:alnum:]]|\.|-|\*|\[|\])+"
51
52_python_check_python_abi_matching() {
53 local pattern patterns patterns_list="0" PYTHON_ABI
54
55 while (($#)); do
56 case "$1" in
57 --patterns-list)
58 patterns_list="1"
59 ;;
60 --)
61 shift
62 break
63 ;;
64 -*)
65 die "${FUNCNAME}(): Unrecognized option '$1'"
66 ;;
67 *)
68 break
69 ;;
70 esac
71 shift
72 done
73
74 if [[ "$#" -ne 2 ]]; then
75 die "${FUNCNAME}() requires 2 arguments"
76 fi
77
78 PYTHON_ABI="$1"
79
80 if [[ "${patterns_list}" == "0" ]]; then
81 pattern="$2"
82
83 if [[ "${pattern}" == *"-cpython" ]]; then
84 [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+$ && "${PYTHON_ABI}" == ${pattern%-cpython} ]]
85 elif [[ "${pattern}" == *"-jython" ]]; then
86 [[ "${PYTHON_ABI}" == ${pattern} ]]
87 elif [[ "${pattern}" == *"-pypy-"* ]]; then
88 [[ "${PYTHON_ABI}" == ${pattern} ]]
89 else
90 if [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
91 [[ "${PYTHON_ABI}" == ${pattern} ]]
92 elif [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+-jython$ ]]; then
93 [[ "${PYTHON_ABI%-jython}" == ${pattern} ]]
94 elif [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+-pypy-[[:digit:]]+\.[[:digit:]]+$ ]]; then
95 [[ "${PYTHON_ABI%-pypy-*}" == ${pattern} ]]
96 else
97 die "${FUNCNAME}(): Unrecognized Python ABI '${PYTHON_ABI}'"
98 fi
99 fi
100 else
101 patterns="${2// /$'\n'}"
102
103 while read pattern; do
104 if _python_check_python_abi_matching "${PYTHON_ABI}" "${pattern}"; then
105 return 0
106 fi
107 done <<< "${patterns}"
108
109 return 1
110 fi
111}
112
113_python_implementation() {
114 if [[ "${CATEGORY}/${PN}" == "dev-lang/python" ]]; then
115 return 0
116 elif [[ "${CATEGORY}/${PN}" == "dev-java/jython" ]]; then
117 return 0
118 elif [[ "${CATEGORY}/${PN}" == "virtual/pypy" ]]; then
119 return 0
120 else
121 return 1
122 fi
123}
124
125_python_package_supporting_installation_for_multiple_python_abis() {
126 [[ -n "${SUPPORT_PYTHON_ABIS}" ]]
127}
21 128
22# @ECLASS-VARIABLE: PYTHON_DEPEND 129# @ECLASS-VARIABLE: PYTHON_DEPEND
23# @DESCRIPTION: 130# @DESCRIPTION:
24# Specification of dependency on dev-lang/python. 131# Specification of dependency on dev-lang/python.
25# Syntax: 132# Syntax:
27# version_components_group: <major_version[:[minimal_version][:maximal_version]]> 134# version_components_group: <major_version[:[minimal_version][:maximal_version]]>
28# major_version: <2|3|*> 135# major_version: <2|3|*>
29# minimal_version: <minimal_major_version.minimal_minor_version> 136# minimal_version: <minimal_major_version.minimal_minor_version>
30# maximal_version: <maximal_major_version.maximal_minor_version> 137# maximal_version: <maximal_major_version.maximal_minor_version>
31 138
32_parse_PYTHON_DEPEND() { 139_python_parse_PYTHON_DEPEND() {
33 local major_version maximal_version minimal_version python_all="0" python_maximal_version python_minimal_version python_versions=() python2="0" python2_maximal_version python2_minimal_version python3="0" python3_maximal_version python3_minimal_version USE_flag= version_components_group version_components_group_regex version_components_groups 140 local major_version maximal_version minimal_version python_all="0" python_maximal_version python_minimal_version python_versions=() python2="0" python2_maximal_version python2_minimal_version python3="0" python3_maximal_version python3_minimal_version USE_flag= version_components_group version_components_group_regex version_components_groups
34 141
35 version_components_group_regex="(2|3|\*)(:([[:digit:]]+\.[[:digit:]]+)?(:([[:digit:]]+\.[[:digit:]]+)?)?)?" 142 version_components_group_regex="(2|3|\*)(:([[:digit:]]+\.[[:digit:]]+)?(:([[:digit:]]+\.[[:digit:]]+)?)?)?"
36 version_components_groups="${PYTHON_DEPEND}" 143 version_components_groups="${PYTHON_DEPEND}"
37 144
60 fi 167 fi
61 fi 168 fi
62 169
63 if [[ "${major_version}" == "2" ]]; then 170 if [[ "${major_version}" == "2" ]]; then
64 python2="1" 171 python2="1"
65 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}") 172 python_versions=("${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}")
66 python2_minimal_version="${minimal_version}" 173 python2_minimal_version="${minimal_version}"
67 python2_maximal_version="${maximal_version}" 174 python2_maximal_version="${maximal_version}"
68 elif [[ "${major_version}" == "3" ]]; then 175 elif [[ "${major_version}" == "3" ]]; then
69 python3="1" 176 python3="1"
70 python_versions=("${_CPYTHON3_SUPPORTED_ABIS[@]}") 177 python_versions=("${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}")
71 python3_minimal_version="${minimal_version}" 178 python3_minimal_version="${minimal_version}"
72 python3_maximal_version="${maximal_version}" 179 python3_maximal_version="${maximal_version}"
73 else 180 else
74 python_all="1" 181 python_all="1"
75 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}") 182 python_versions=("${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}" "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}")
76 python_minimal_version="${minimal_version}" 183 python_minimal_version="${minimal_version}"
77 python_maximal_version="${maximal_version}" 184 python_maximal_version="${maximal_version}"
78 fi 185 fi
79 186
80 if [[ -n "${minimal_version}" ]] && ! has "${minimal_version}" "${python_versions[@]}"; then 187 if [[ -n "${minimal_version}" ]] && ! has "${minimal_version}" "${python_versions[@]}"; then
108 215
109 if [[ "${python_all}" == "1" ]]; then 216 if [[ "${python_all}" == "1" ]]; then
110 if [[ -z "${python_minimal_version}" && -z "${python_maximal_version}" ]]; then 217 if [[ -z "${python_minimal_version}" && -z "${python_maximal_version}" ]]; then
111 _PYTHON_ATOMS+=("dev-lang/python") 218 _PYTHON_ATOMS+=("dev-lang/python")
112 else 219 else
113 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}" "${_CPYTHON3_SUPPORTED_ABIS[@]}") 220 python_versions=("${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}" "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}")
114 python_minimal_version="${python_minimal_version:-${python_versions[0]}}" 221 python_minimal_version="${python_minimal_version:-${python_versions[0]}}"
115 python_maximal_version="${python_maximal_version:-${python_versions[${#python_versions[@]}-1]}}" 222 python_maximal_version="${python_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
116 _append_accepted_versions_range 223 _append_accepted_versions_range
117 fi 224 fi
118 else 225 else
119 if [[ "${python3}" == "1" ]]; then 226 if [[ "${python3}" == "1" ]]; then
120 if [[ -z "${python3_minimal_version}" && -z "${python3_maximal_version}" ]]; then 227 if [[ -z "${python3_minimal_version}" && -z "${python3_maximal_version}" ]]; then
121 _PYTHON_ATOMS+=("=dev-lang/python-3*") 228 _PYTHON_ATOMS+=("=dev-lang/python-3*")
122 else 229 else
123 python_versions=("${_CPYTHON3_SUPPORTED_ABIS[@]}") 230 python_versions=("${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}")
124 python_minimal_version="${python3_minimal_version:-${python_versions[0]}}" 231 python_minimal_version="${python3_minimal_version:-${python_versions[0]}}"
125 python_maximal_version="${python3_maximal_version:-${python_versions[${#python_versions[@]}-1]}}" 232 python_maximal_version="${python3_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
126 _append_accepted_versions_range 233 _append_accepted_versions_range
127 fi 234 fi
128 fi 235 fi
129 if [[ "${python2}" == "1" ]]; then 236 if [[ "${python2}" == "1" ]]; then
130 if [[ -z "${python2_minimal_version}" && -z "${python2_maximal_version}" ]]; then 237 if [[ -z "${python2_minimal_version}" && -z "${python2_maximal_version}" ]]; then
131 _PYTHON_ATOMS+=("=dev-lang/python-2*") 238 _PYTHON_ATOMS+=("=dev-lang/python-2*")
132 else 239 else
133 python_versions=("${_CPYTHON2_SUPPORTED_ABIS[@]}") 240 python_versions=("${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}")
134 python_minimal_version="${python2_minimal_version:-${python_versions[0]}}" 241 python_minimal_version="${python2_minimal_version:-${python_versions[0]}}"
135 python_maximal_version="${python2_maximal_version:-${python_versions[${#python_versions[@]}-1]}}" 242 python_maximal_version="${python2_maximal_version:-${python_versions[${#python_versions[@]}-1]}}"
136 _append_accepted_versions_range 243 _append_accepted_versions_range
137 fi 244 fi
138 fi 245 fi
150 else 257 else
151 die "Invalid syntax of PYTHON_DEPEND" 258 die "Invalid syntax of PYTHON_DEPEND"
152 fi 259 fi
153} 260}
154 261
262if _python_implementation; then
155DEPEND=">=app-admin/eselect-python-20091230" 263 DEPEND=">=app-eselect/eselect-python-20091230"
156RDEPEND="${DEPEND}" 264 RDEPEND="${DEPEND}"
265 PDEPEND="app-admin/python-updater"
266fi
157 267
158if [[ -n "${PYTHON_DEPEND}" && -n "${NEED_PYTHON}" ]]; then
159 die "PYTHON_DEPEND and NEED_PYTHON cannot be set simultaneously"
160elif [[ -n "${PYTHON_DEPEND}" ]]; then 268if [[ -n "${PYTHON_DEPEND}" ]]; then
161 _parse_PYTHON_DEPEND 269 _python_parse_PYTHON_DEPEND
162elif [[ -n "${NEED_PYTHON}" ]]; then
163 if ! has "${EAPI:-0}" 0 1 2; then
164 eerror "Use PYTHON_DEPEND instead of NEED_PYTHON."
165 die "NEED_PYTHON cannot be used in this EAPI"
166 fi
167 _PYTHON_ATOMS=(">=dev-lang/python-${NEED_PYTHON}")
168 DEPEND+="${DEPEND:+ }${_PYTHON_ATOMS[@]}"
169 RDEPEND+="${RDEPEND:+ }${_PYTHON_ATOMS[@]}"
170else 270else
171 _PYTHON_ATOMS=("dev-lang/python") 271 _PYTHON_ATOMS=("dev-lang/python")
172fi 272fi
273unset -f _python_parse_PYTHON_DEPEND
274
275if [[ -n "${NEED_PYTHON}" ]]; then
276 eerror "Use PYTHON_DEPEND variable instead of NEED_PYTHON variable."
277 die "NEED_PYTHON variable is banned"
278fi
173 279
174# @ECLASS-VARIABLE: PYTHON_USE_WITH 280# @ECLASS-VARIABLE: PYTHON_USE_WITH
175# @DESCRIPTION: 281# @DESCRIPTION:
176# Set this to a space separated list of USE flags the Python slot in use must be built with. 282# Set this to a space separated list of USE flags the Python slot in use must be built with.
177 283
182# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT 288# @ECLASS-VARIABLE: PYTHON_USE_WITH_OPT
183# @DESCRIPTION: 289# @DESCRIPTION:
184# Set this to a name of a USE flag if you need to make either PYTHON_USE_WITH or 290# Set this to a name of a USE flag if you need to make either PYTHON_USE_WITH or
185# PYTHON_USE_WITH_OR atoms conditional under a USE flag. 291# PYTHON_USE_WITH_OR atoms conditional under a USE flag.
186 292
187# @FUNCTION: python_pkg_setup
188# @DESCRIPTION:
189# Makes sure PYTHON_USE_WITH or PYTHON_USE_WITH_OR listed use flags
190# are respected. Only exported if one of those variables is set.
191if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then 293if ! has "${EAPI:-0}" 0 1 && [[ -n ${PYTHON_USE_WITH} || -n ${PYTHON_USE_WITH_OR} ]]; then
192 python_pkg_setup() {
193 python_pkg_setup_fail() {
194 eerror "${1}"
195 die "${1}"
196 }
197
198 [[ ${PYTHON_USE_WITH_OPT} ]] && use !${PYTHON_USE_WITH_OPT} && return
199
200 python_pkg_setup_check_USE_flags() {
201 local pyatom use
202 pyatom="$(python_get_implementational_package)"
203
204 for use in ${PYTHON_USE_WITH}; do
205 if ! has_version "${pyatom}[${use}]"; then
206 python_pkg_setup_fail "Please rebuild ${pyatom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
207 fi
208 done
209
210 for use in ${PYTHON_USE_WITH_OR}; do
211 if has_version "${pyatom}[${use}]"; then
212 return
213 fi
214 done
215
216 if [[ ${PYTHON_USE_WITH_OR} ]]; then
217 python_pkg_setup_fail "Please rebuild ${pyatom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
218 fi
219 }
220
221 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
222 python_execute_function -q python_pkg_setup_check_USE_flags
223 else
224 python_pkg_setup_check_USE_flags
225 fi
226
227 unset -f python_pkg_setup_check_USE_flags python_pkg_setup_fail
228 }
229
230 EXPORT_FUNCTIONS pkg_setup
231
232 _PYTHON_USE_WITH_ATOM="" 294 _PYTHON_USE_WITH_ATOMS_ARRAY=()
233 if [[ -n "${PYTHON_USE_WITH}" ]]; then 295 if [[ -n "${PYTHON_USE_WITH}" ]]; then
234 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do 296 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do
235 _PYTHON_USE_WITH_ATOM+="${_PYTHON_USE_WITH_ATOM:+ }${_PYTHON_ATOM}[${PYTHON_USE_WITH/ /,}]" 297 _PYTHON_USE_WITH_ATOMS_ARRAY+=("${_PYTHON_ATOM}[${PYTHON_USE_WITH// /,}]")
236 done 298 done
237 _PYTHON_USE_WITH_ATOM="|| ( ${_PYTHON_USE_WITH_ATOM} )"
238 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then 299 elif [[ -n "${PYTHON_USE_WITH_OR}" ]]; then
239 for _USE_flag in ${PYTHON_USE_WITH_OR}; do 300 for _USE_flag in ${PYTHON_USE_WITH_OR}; do
240 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do 301 for _PYTHON_ATOM in "${_PYTHON_ATOMS[@]}"; do
241 _PYTHON_USE_WITH_ATOM+="${_PYTHON_USE_WITH_ATOM:+ }${_PYTHON_ATOM}[${_USE_flag}]" 302 _PYTHON_USE_WITH_ATOMS_ARRAY+=("${_PYTHON_ATOM}[${_USE_flag}]")
242 done 303 done
243 done 304 done
244 unset _USE_flag 305 unset _USE_flag
306 fi
307 if [[ "${#_PYTHON_USE_WITH_ATOMS_ARRAY[@]}" -gt 1 ]]; then
245 _PYTHON_USE_WITH_ATOM="|| ( ${_PYTHON_USE_WITH_ATOM} )" 308 _PYTHON_USE_WITH_ATOMS="|| ( ${_PYTHON_USE_WITH_ATOMS_ARRAY[@]} )"
309 else
310 _PYTHON_USE_WITH_ATOMS="${_PYTHON_USE_WITH_ATOMS_ARRAY[@]}"
246 fi 311 fi
247 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then 312 if [[ -n "${PYTHON_USE_WITH_OPT}" ]]; then
248 _PYTHON_USE_WITH_ATOM="${PYTHON_USE_WITH_OPT}? ( ${_PYTHON_USE_WITH_ATOM} )" 313 _PYTHON_USE_WITH_ATOMS="${PYTHON_USE_WITH_OPT}? ( ${_PYTHON_USE_WITH_ATOMS} )"
249 fi 314 fi
250 DEPEND+=" ${_PYTHON_USE_WITH_ATOM}" 315 DEPEND+="${DEPEND:+ }${_PYTHON_USE_WITH_ATOMS}"
251 RDEPEND+=" ${_PYTHON_USE_WITH_ATOM}" 316 RDEPEND+="${RDEPEND:+ }${_PYTHON_USE_WITH_ATOMS}"
252 unset _PYTHON_ATOM _PYTHON_USE_WITH_ATOM 317 unset _PYTHON_ATOM _PYTHON_USE_WITH_ATOMS _PYTHON_USE_WITH_ATOMS_ARRAY
253fi 318fi
254 319
255unset _PYTHON_ATOMS 320unset _PYTHON_ATOMS
256
257# ================================================================================================
258# ======== FUNCTIONS FOR PACKAGES SUPPORTING INSTALLATION FOR MULTIPLE VERSIONS OF PYTHON ========
259# ================================================================================================
260
261# @ECLASS-VARIABLE: SUPPORT_PYTHON_ABIS
262# @DESCRIPTION:
263# Set this in EAPI <= 4 to indicate that current package supports installation for
264# multiple versions of Python.
265
266# @ECLASS-VARIABLE: PYTHON_EXPORT_PHASE_FUNCTIONS
267# @DESCRIPTION:
268# Set this to export phase functions for the following ebuild phases:
269# src_prepare, src_configure, src_compile, src_test, src_install.
270if ! has "${EAPI:-0}" 0 1 && [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
271 python_src_prepare() {
272 python_copy_sources
273 }
274
275 for python_default_function in src_configure src_compile src_test src_install; do
276 eval "python_${python_default_function}() { python_execute_function -d -s; }"
277 done
278 unset python_default_function
279
280 if [[ -n "${PYTHON_EXPORT_PHASE_FUNCTIONS}" ]]; then
281 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
282 fi
283fi
284
285unset PYTHON_ABIS
286
287# @FUNCTION: validate_PYTHON_ABIS
288# @DESCRIPTION:
289# Ensure that PYTHON_ABIS variable has valid value.
290# This function usually should not be directly called in ebuilds.
291validate_PYTHON_ABIS() {
292 # Ensure that some functions cannot be accidentally successfully used in EAPI <= 4 without setting SUPPORT_PYTHON_ABIS variable.
293 if has "${EAPI:-0}" 0 1 2 3 4 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
294 die "${FUNCNAME}() cannot be used in this EAPI without setting SUPPORT_PYTHON_ABIS variable"
295 fi
296
297 _python_initial_sanity_checks
298
299 # USE_${ABI_TYPE^^} and RESTRICT_${ABI_TYPE^^}_ABIS variables hopefully will be included in EAPI >= 5.
300 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]] && has "${EAPI:-0}" 0 1 2 3 4; then
301 local PYTHON_ABI restricted_ABI support_ABI supported_PYTHON_ABIS=
302 PYTHON_ABI_SUPPORTED_VALUES="${_CPYTHON2_SUPPORTED_ABIS[@]} ${_CPYTHON3_SUPPORTED_ABIS[@]} ${_JYTHON_SUPPORTED_ABIS[@]}"
303
304 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
305 local python2_enabled="0" python3_enabled="0"
306
307 if [[ -z "${USE_PYTHON}" ]]; then
308 die "USE_PYTHON variable is empty"
309 fi
310
311 for PYTHON_ABI in ${USE_PYTHON}; do
312 if ! has "${PYTHON_ABI}" ${PYTHON_ABI_SUPPORTED_VALUES}; then
313 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
314 fi
315
316 if has "${PYTHON_ABI}" "${_CPYTHON2_SUPPORTED_ABIS[@]}"; then
317 python2_enabled="1"
318 fi
319 if has "${PYTHON_ABI}" "${_CPYTHON3_SUPPORTED_ABIS[@]}"; then
320 python3_enabled="1"
321 fi
322
323 support_ABI="1"
324 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
325 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
326 support_ABI="0"
327 break
328 fi
329 done
330 [[ "${support_ABI}" == "1" ]] && export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
331 done
332
333 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
334 die "USE_PYTHON variable does not enable any version of Python supported by ${CATEGORY}/${PF}"
335 fi
336
337 if [[ "${python2_enabled}" == "0" ]]; then
338 ewarn "USE_PYTHON variable does not enable any version of Python 2. This configuration is unsupported."
339 fi
340 if [[ "${python3_enabled}" == "0" ]]; then
341 ewarn "USE_PYTHON variable does not enable any version of Python 3. This configuration is unsupported."
342 fi
343 if [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "0" ]]; then
344 die "USE_PYTHON variable does not enable any version of CPython"
345 fi
346 else
347 local python_version python2_version= python3_version= support_python_major_version
348
349 python_version="$("${EPREFIX}/usr/bin/python" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
350
351 if has_version "=dev-lang/python-2*"; then
352 if [[ "$(readlink "${EPREFIX}/usr/bin/python2")" != "python2."* ]]; then
353 die "'${EPREFIX}/usr/bin/python2' is not valid symlink"
354 fi
355
356 python2_version="$("${EPREFIX}/usr/bin/python2" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
357
358 for PYTHON_ABI in "${_CPYTHON2_SUPPORTED_ABIS[@]}"; do
359 support_python_major_version="1"
360 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
361 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
362 support_python_major_version="0"
363 fi
364 done
365 [[ "${support_python_major_version}" == "1" ]] && break
366 done
367 if [[ "${support_python_major_version}" == "1" ]]; then
368 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
369 if [[ "${python2_version}" == ${restricted_ABI} ]]; then
370 die "Active version of Python 2 is not supported by ${CATEGORY}/${PF}"
371 fi
372 done
373 else
374 python2_version=""
375 fi
376 fi
377
378 if has_version "=dev-lang/python-3*"; then
379 if [[ "$(readlink "${EPREFIX}/usr/bin/python3")" != "python3."* ]]; then
380 die "'${EPREFIX}/usr/bin/python3' is not valid symlink"
381 fi
382
383 python3_version="$("${EPREFIX}/usr/bin/python3" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
384
385 for PYTHON_ABI in "${_CPYTHON3_SUPPORTED_ABIS[@]}"; do
386 support_python_major_version="1"
387 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
388 if [[ "${PYTHON_ABI}" == ${restricted_ABI} ]]; then
389 support_python_major_version="0"
390 fi
391 done
392 [[ "${support_python_major_version}" == "1" ]] && break
393 done
394 if [[ "${support_python_major_version}" == "1" ]]; then
395 for restricted_ABI in ${RESTRICT_PYTHON_ABIS}; do
396 if [[ "${python3_version}" == ${restricted_ABI} ]]; then
397 die "Active version of Python 3 is not supported by ${CATEGORY}/${PF}"
398 fi
399 done
400 else
401 python3_version=""
402 fi
403 fi
404
405 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
406 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python2' symlink"
407 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
408 die "Incorrect configuration of Python"
409 fi
410 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
411 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python3' symlink"
412 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
413 die "Incorrect configuration of Python"
414 fi
415
416 PYTHON_ABIS="${python2_version} ${python3_version}"
417 PYTHON_ABIS="${PYTHON_ABIS# }"
418 export PYTHON_ABIS="${PYTHON_ABIS% }"
419 fi
420 fi
421
422 _python_final_sanity_checks
423}
424
425# @FUNCTION: python_execute_function
426# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [-f|--final-ABI] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
427# @DESCRIPTION:
428# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
429# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
430python_execute_function() {
431 _python_set_color_variables
432
433 local action action_message action_message_template= default_function="0" failure_message failure_message_template= final_ABI="0" function i iterated_PYTHON_ABIS nonfatal="0" previous_directory previous_directory_stack previous_directory_stack_length PYTHON_ABI quiet="0" separate_build_dirs="0" source_dir=
434
435 while (($#)); do
436 case "$1" in
437 --action-message)
438 action_message_template="$2"
439 shift
440 ;;
441 -d|--default-function)
442 default_function="1"
443 ;;
444 --failure-message)
445 failure_message_template="$2"
446 shift
447 ;;
448 -f|--final-ABI)
449 final_ABI="1"
450 ;;
451 --nonfatal)
452 nonfatal="1"
453 ;;
454 -q|--quiet)
455 quiet="1"
456 ;;
457 -s|--separate-build-dirs)
458 separate_build_dirs="1"
459 ;;
460 --source-dir)
461 source_dir="$2"
462 shift
463 ;;
464 --)
465 shift
466 break
467 ;;
468 -*)
469 die "${FUNCNAME}(): Unrecognized option '$1'"
470 ;;
471 *)
472 break
473 ;;
474 esac
475 shift
476 done
477
478 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
479 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
480 fi
481
482 if [[ "${default_function}" == "0" ]]; then
483 if [[ "$#" -eq 0 ]]; then
484 die "${FUNCNAME}(): Missing function name"
485 fi
486 function="$1"
487 shift
488
489 if [[ -z "$(type -t "${function}")" ]]; then
490 die "${FUNCNAME}(): '${function}' function is not defined"
491 fi
492 else
493 if [[ "$#" -ne 0 ]]; then
494 die "${FUNCNAME}(): '--default-function' option and function name cannot be specified simultaneously"
495 fi
496 if has "${EAPI:-0}" 0 1; then
497 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
498 fi
499
500 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
501 if has "${EAPI}" 2 3; then
502 python_default_function() {
503 econf
504 }
505 else
506 python_default_function() {
507 nonfatal econf
508 }
509 fi
510 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
511 python_default_function() {
512 emake
513 }
514 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
515 python_default_function() {
516 if emake -j1 -n check &> /dev/null; then
517 emake -j1 check
518 elif emake -j1 -n test &> /dev/null; then
519 emake -j1 test
520 fi
521 }
522 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
523 python_default_function() {
524 emake DESTDIR="${D}" install
525 }
526 else
527 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
528 fi
529 function="python_default_function"
530 fi
531
532 for ((i = 1; i < "${#FUNCNAME[@]}"; i++)); do
533 if [[ "${FUNCNAME[${i}]}" == "${FUNCNAME}" ]]; then
534 die "${FUNCNAME}(): Invalid call stack"
535 fi
536 done
537
538 if [[ "${quiet}" == "0" ]]; then
539 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
540 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
541 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
542 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
543 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
544 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
545 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
546 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
547 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
548 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
549 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
550 fi
551
552 validate_PYTHON_ABIS
553 if [[ "${final_ABI}" == "1" ]]; then
554 iterated_PYTHON_ABIS="$(PYTHON -f --ABI)"
555 else
556 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
557 fi
558 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
559 if [[ "${quiet}" == "0" ]]; then
560 if [[ -n "${action_message_template}" ]]; then
561 action_message="$(eval echo -n "${action_message_template}")"
562 else
563 action_message="${action} of ${CATEGORY}/${PF} with $(python_get_implementation) $(python_get_version)..."
564 fi
565 echo " ${_GREEN}*${_NORMAL} ${_BLUE}${action_message}${_NORMAL}"
566 fi
567
568 if [[ "${separate_build_dirs}" == "1" ]]; then
569 if [[ -n "${source_dir}" ]]; then
570 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
571 else
572 export BUILDDIR="${S}-${PYTHON_ABI}"
573 fi
574 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
575 else
576 export BUILDDIR="${S}"
577 fi
578
579 previous_directory="$(pwd)"
580 previous_directory_stack="$(dirs -p)"
581 previous_directory_stack_length="$(dirs -p | wc -l)"
582
583 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
584 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
585 else
586 EPYTHON="$(PYTHON)" "${function}" "$@"
587 fi
588
589 if [[ "$?" != "0" ]]; then
590 if [[ -n "${failure_message_template}" ]]; then
591 failure_message="$(eval echo -n "${failure_message_template}")"
592 else
593 failure_message="${action} failed with $(python_get_implementation) $(python_get_version) in ${function}() function"
594 fi
595
596 if [[ "${nonfatal}" == "1" ]]; then
597 if [[ "${quiet}" == "0" ]]; then
598 ewarn "${_RED}${failure_message}${_NORMAL}"
599 fi
600 elif [[ "${final_ABI}" == "0" ]] && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
601 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
602 local enabled_PYTHON_ABIS= other_PYTHON_ABI
603 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
604 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
605 done
606 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
607 fi
608 if [[ "${quiet}" == "0" ]]; then
609 ewarn "${_RED}${failure_message}${_NORMAL}"
610 fi
611 if [[ -z "${PYTHON_ABIS}" ]]; then
612 die "${function}() function failed with all enabled versions of Python"
613 fi
614 else
615 die "${failure_message}"
616 fi
617 fi
618
619 # Ensure that directory stack has not been decreased.
620 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
621 die "Directory stack decreased illegally"
622 fi
623
624 # Avoid side effects of earlier returning from the specified function.
625 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
626 popd > /dev/null || die "popd failed"
627 done
628
629 # Ensure that the bottom part of directory stack has not been changed. Restore
630 # previous directory (from before running of the specified function) before
631 # comparison of directory stacks to avoid mismatch of directory stacks after
632 # potential using of 'cd' to change current directory. Restoration of previous
633 # directory allows to safely use 'cd' to change current directory in the
634 # specified function without changing it back to original directory.
635 cd "${previous_directory}"
636 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
637 die "Directory stack changed illegally"
638 fi
639
640 if [[ "${separate_build_dirs}" == "1" ]]; then
641 popd > /dev/null || die "popd failed"
642 fi
643 unset BUILDDIR
644 done
645
646 if [[ "${default_function}" == "1" ]]; then
647 unset -f python_default_function
648 fi
649}
650
651# @FUNCTION: python_copy_sources
652# @USAGE: <directory="${S}"> [directory]
653# @DESCRIPTION:
654# Copy unpacked sources of current package to separate build directory for each Python ABI.
655python_copy_sources() {
656 local dir dirs=() PYTHON_ABI
657
658 if [[ "$#" -eq 0 ]]; then
659 if [[ "${WORKDIR}" == "${S}" ]]; then
660 die "${FUNCNAME}() cannot be used"
661 fi
662 dirs=("${S}")
663 else
664 dirs=("$@")
665 fi
666
667 validate_PYTHON_ABIS
668 for PYTHON_ABI in ${PYTHON_ABIS}; do
669 for dir in "${dirs[@]}"; do
670 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
671 done
672 done
673}
674
675# @FUNCTION: python_set_build_dir_symlink
676# @USAGE: <directory="build">
677# @DESCRIPTION:
678# Create build directory symlink.
679python_set_build_dir_symlink() {
680 local dir="$1"
681
682 [[ -z "${PYTHON_ABI}" ]] && die "PYTHON_ABI variable not set"
683 [[ -z "${dir}" ]] && dir="build"
684
685 # Do not delete preexistent directories.
686 rm -f "${dir}" || die "Deletion of '${dir}' failed"
687 ln -s "${dir}-${PYTHON_ABI}" "${dir}" || die "Creation of '${dir}' directory symlink failed"
688}
689
690# @FUNCTION: python_generate_wrapper_scripts
691# @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
692# @DESCRIPTION:
693# Generate wrapper scripts. Existing files are overwritten only with --force option.
694# If --respect-EPYTHON option is specified, then generated wrapper scripts will
695# respect EPYTHON variable at run time.
696python_generate_wrapper_scripts() {
697 _python_initialize_prefix_variables
698
699 local eselect_python_option file force="0" quiet="0" PYTHON_ABI python2_enabled="0" python3_enabled="0" respect_EPYTHON="0"
700
701 while (($#)); do
702 case "$1" in
703 -E|--respect-EPYTHON)
704 respect_EPYTHON="1"
705 ;;
706 -f|--force)
707 force="1"
708 ;;
709 -q|--quiet)
710 quiet="1"
711 ;;
712 --)
713 shift
714 break
715 ;;
716 -*)
717 die "${FUNCNAME}(): Unrecognized option '$1'"
718 ;;
719 *)
720 break
721 ;;
722 esac
723 shift
724 done
725
726 if [[ "$#" -eq 0 ]]; then
727 die "${FUNCNAME}(): Missing arguments"
728 fi
729
730 validate_PYTHON_ABIS
731 for PYTHON_ABI in "${_CPYTHON2_SUPPORTED_ABIS[@]}"; do
732 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
733 python2_enabled="1"
734 fi
735 done
736 for PYTHON_ABI in "${_CPYTHON3_SUPPORTED_ABIS[@]}"; do
737 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
738 python3_enabled="1"
739 fi
740 done
741
742 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
743 eselect_python_option=
744 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
745 eselect_python_option="--python2"
746 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
747 eselect_python_option="--python3"
748 else
749 die "${FUNCNAME}(): Unsupported environment"
750 fi
751
752 for file in "$@"; do
753 if [[ -f "${file}" && "${force}" == "0" ]]; then
754 die "${FUNCNAME}(): '$1' already exists"
755 fi
756
757 if [[ "${quiet}" == "0" ]]; then
758 einfo "Generating '${file#${D%/}}' wrapper script"
759 fi
760
761 cat << EOF > "${file}"
762#!/usr/bin/env python
763# Gentoo '${file##*/}' wrapper script
764
765import os
766import re
767import subprocess
768import sys
769
770EPYTHON_re = re.compile(r"^python(\d+\.\d+)$")
771
772EOF
773 if [[ "$?" != "0" ]]; then
774 die "${FUNCNAME}(): Generation of '$1' failed"
775 fi
776 if [[ "${respect_EPYTHON}" == "1" ]]; then
777 cat << EOF >> "${file}"
778EPYTHON = os.environ.get("EPYTHON")
779if EPYTHON:
780 EPYTHON_matched = EPYTHON_re.match(EPYTHON)
781 if EPYTHON_matched:
782 PYTHON_ABI = EPYTHON_matched.group(1)
783 else:
784 sys.stderr.write("EPYTHON variable has unrecognized value '%s'\n" % EPYTHON)
785 sys.exit(1)
786else:
787 try:
788 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
789 if eselect_process.wait() != 0:
790 raise ValueError
791 except (OSError, ValueError):
792 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
793 sys.exit(1)
794
795 eselect_output = eselect_process.stdout.read()
796 if not isinstance(eselect_output, str):
797 # Python 3
798 eselect_output = eselect_output.decode()
799
800 EPYTHON_matched = EPYTHON_re.match(eselect_output)
801 if EPYTHON_matched:
802 PYTHON_ABI = EPYTHON_matched.group(1)
803 else:
804 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
805 sys.exit(1)
806EOF
807 if [[ "$?" != "0" ]]; then
808 die "${FUNCNAME}(): Generation of '$1' failed"
809 fi
810 else
811 cat << EOF >> "${file}"
812try:
813 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], stdout=subprocess.PIPE)
814 if eselect_process.wait() != 0:
815 raise ValueError
816except (OSError, ValueError):
817 sys.stderr.write("Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n")
818 sys.exit(1)
819
820eselect_output = eselect_process.stdout.read()
821if not isinstance(eselect_output, str):
822 # Python 3
823 eselect_output = eselect_output.decode()
824
825EPYTHON_matched = EPYTHON_re.match(eselect_output)
826if EPYTHON_matched:
827 PYTHON_ABI = EPYTHON_matched.group(1)
828else:
829 sys.stderr.write("'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s" % eselect_output)
830 sys.exit(1)
831EOF
832 if [[ "$?" != "0" ]]; then
833 die "${FUNCNAME}(): Generation of '$1' failed"
834 fi
835 fi
836 cat << EOF >> "${file}"
837
838os.environ["PYTHON_SCRIPT_NAME"] = sys.argv[0]
839target_executable = "%s-%s" % (os.path.realpath(sys.argv[0]), PYTHON_ABI)
840if not os.path.exists(target_executable):
841 sys.stderr.write("'%s' does not exist\n" % target_executable)
842 sys.exit(1)
843
844os.execv(target_executable, sys.argv)
845EOF
846 if [[ "$?" != "0" ]]; then
847 die "${FUNCNAME}(): Generation of '$1' failed"
848 fi
849 fperms +x "${file#${ED%/}}" || die "fperms '${file}' failed"
850 done
851}
852
853# ================================================================================================
854# ====== FUNCTIONS FOR PACKAGES NOT SUPPORTING INSTALLATION FOR MULTIPLE VERSIONS OF PYTHON ======
855# ================================================================================================
856
857# @FUNCTION: python_set_active_version
858# @USAGE: <CPython_ABI|2|3>
859# @DESCRIPTION:
860# Set specified version of CPython as active version of Python.
861python_set_active_version() {
862 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
863 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple versions of Python"
864 fi
865
866 if [[ "$#" -ne 1 ]]; then
867 die "${FUNCNAME}() requires 1 argument"
868 fi
869
870 _python_initial_sanity_checks
871
872 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
873 if ! _python_implementation && ! has_version "dev-lang/python:$1"; then
874 die "${FUNCNAME}(): 'dev-lang/python:$1' is not installed"
875 fi
876 export EPYTHON="$(PYTHON "$1")"
877 elif [[ "$1" == "2" ]]; then
878 if ! _python_implementation && ! has_version "=dev-lang/python-2*"; then
879 die "${FUNCNAME}(): '=dev-lang/python-2*' is not installed"
880 fi
881 export EPYTHON="$(PYTHON -2)"
882 elif [[ "$1" == "3" ]]; then
883 if ! _python_implementation && ! has_version "=dev-lang/python-3*"; then
884 die "${FUNCNAME}(): '=dev-lang/python-3*' is not installed"
885 fi
886 export EPYTHON="$(PYTHON -3)"
887 else
888 die "${FUNCNAME}(): Unrecognized argument '$1'"
889 fi
890
891 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
892 # so it does not need to be exported to subprocesses.
893 PYTHON_ABI="${EPYTHON#python}"
894 PYTHON_ABI="${PYTHON_ABI%%-*}"
895
896 _python_final_sanity_checks
897
898 # python-updater checks PYTHON_REQUESTED_ACTIVE_VERSION variable.
899 PYTHON_REQUESTED_ACTIVE_VERSION="$1"
900}
901
902# @FUNCTION: python_need_rebuild
903# @DESCRIPTION: Mark current package for rebuilding by python-updater after
904# switching of active version of Python.
905python_need_rebuild() {
906 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
907 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple versions of Python"
908 fi
909
910 export PYTHON_NEED_REBUILD="$(PYTHON --ABI)"
911}
912
913# ================================================================================================
914# ======================================= GETTER FUNCTIONS =======================================
915# ================================================================================================
916
917_PYTHON_ABI_EXTRACTION_COMMAND='import platform
918import sys
919sys.stdout.write(".".join(str(x) for x in sys.version_info[:2]))
920if platform.system()[:4] == "Java":
921 sys.stdout.write("-jython")'
922
923_python_get_implementation() {
924 if [[ "$#" -ne 1 ]]; then
925 die "${FUNCNAME}() requires 1 argument"
926 fi
927
928 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
929 echo "CPython"
930 elif [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+-jython$ ]]; then
931 echo "Jython"
932 else
933 die "${FUNCNAME}(): Unrecognized Python ABI '$1'"
934 fi
935}
936
937# @FUNCTION: PYTHON
938# @USAGE: [-2] [-3] [--ABI] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
939# @DESCRIPTION:
940# Print filename of Python interpreter for specified Python ABI. If Python_ABI argument
941# is ommitted, then PYTHON_ABI environment variable must be set and is used.
942# If -2 option is specified, then active version of Python 2 is used.
943# If -3 option is specified, then active version of Python 3 is used.
944# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
945# -2, -3 and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
946# If --ABI option is specified, then only specified Python ABI is printed instead of
947# filename of Python interpreter.
948# If --absolute-path option is specified, then absolute path to Python interpreter is printed.
949# --ABI and --absolute-path options cannot be specified simultaneously.
950PYTHON() {
951 local ABI_output="0" absolute_path_output="0" final_ABI="0" PYTHON_ABI="${PYTHON_ABI}" python_interpreter python2="0" python3="0"
952
953 while (($#)); do
954 case "$1" in
955 -2)
956 python2="1"
957 ;;
958 -3)
959 python3="1"
960 ;;
961 --ABI)
962 ABI_output="1"
963 ;;
964 -a|--absolute-path)
965 absolute_path_output="1"
966 ;;
967 -f|--final-ABI)
968 final_ABI="1"
969 ;;
970 --)
971 shift
972 break
973 ;;
974 -*)
975 die "${FUNCNAME}(): Unrecognized option '$1'"
976 ;;
977 *)
978 break
979 ;;
980 esac
981 shift
982 done
983
984 if [[ "${ABI_output}" == "1" && "${absolute_path_output}" == "1" ]]; then
985 die "${FUNCNAME}(): '--ABI and '--absolute-path' options cannot be specified simultaneously"
986 fi
987
988 if [[ "$((${python2} + ${python3} + ${final_ABI}))" -gt 1 ]]; then
989 die "${FUNCNAME}(): '-2', '-3' or '--final-ABI' options cannot be specified simultaneously"
990 fi
991
992 if [[ "$#" -eq 0 ]]; then
993 if [[ "${final_ABI}" == "1" ]]; then
994 if has "${EAPI:-0}" 0 1 2 3 4 && [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
995 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple versions of Python"
996 fi
997 validate_PYTHON_ABIS
998 PYTHON_ABI="${PYTHON_ABIS##* }"
999 elif [[ "${python2}" == "1" ]]; then
1000 PYTHON_ABI="$(eselect python show --python2 --ABI)"
1001 if [[ -z "${PYTHON_ABI}" ]]; then
1002 die "${FUNCNAME}(): Active Python 2 interpreter not set"
1003 elif [[ "${PYTHON_ABI}" != "2."* ]]; then
1004 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
1005 fi
1006 elif [[ "${python3}" == "1" ]]; then
1007 PYTHON_ABI="$(eselect python show --python3 --ABI)"
1008 if [[ -z "${PYTHON_ABI}" ]]; then
1009 die "${FUNCNAME}(): Active Python 3 interpreter not set"
1010 elif [[ "${PYTHON_ABI}" != "3."* ]]; then
1011 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
1012 fi
1013 elif [[ -z "${SUPPORT_PYTHON_ABIS}" ]]; then
1014 PYTHON_ABI="$("${EPREFIX}/usr/bin/python" -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")"
1015 elif [[ -z "${PYTHON_ABI}" ]]; then
1016 die "${FUNCNAME}(): Invalid usage: Python ABI not specified"
1017 fi
1018 elif [[ "$#" -eq 1 ]]; then
1019 if [[ "${final_ABI}" == "1" ]]; then
1020 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
1021 fi
1022 if [[ "${python2}" == "1" ]]; then
1023 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
1024 fi
1025 if [[ "${python3}" == "1" ]]; then
1026 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
1027 fi
1028 PYTHON_ABI="$1"
1029 else
1030 die "${FUNCNAME}(): Invalid usage"
1031 fi
1032
1033 if [[ "${ABI_output}" == "1" ]]; then
1034 echo -n "${PYTHON_ABI}"
1035 return
1036 else
1037 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1038 python_interpreter="python${PYTHON_ABI}"
1039 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1040 python_interpreter="jython-${PYTHON_ABI%-jython}"
1041 fi
1042
1043 if [[ "${absolute_path_output}" == "1" ]]; then
1044 echo -n "${EPREFIX}/usr/bin/${python_interpreter}"
1045 else
1046 echo -n "${python_interpreter}"
1047 fi
1048 fi
1049
1050 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
1051 echo -n "-${ABI}"
1052 fi
1053}
1054
1055# @FUNCTION: python_get_implementation
1056# @USAGE: [-f|--final-ABI]
1057# @DESCRIPTION:
1058# Print name of Python implementation.
1059# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1060python_get_implementation() {
1061 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1062
1063 while (($#)); do
1064 case "$1" in
1065 -f|--final-ABI)
1066 final_ABI="1"
1067 ;;
1068 -*)
1069 die "${FUNCNAME}(): Unrecognized option '$1'"
1070 ;;
1071 *)
1072 die "${FUNCNAME}(): Invalid usage"
1073 ;;
1074 esac
1075 shift
1076 done
1077
1078 if [[ "${final_ABI}" == "1" ]]; then
1079 PYTHON_ABI="$(PYTHON -f --ABI)"
1080 elif [[ -z "${PYTHON_ABI}" ]]; then
1081 PYTHON_ABI="$(PYTHON --ABI)"
1082 fi
1083
1084 echo "$(_python_get_implementation "${PYTHON_ABI}")"
1085}
1086
1087# @FUNCTION: python_get_implementational_package
1088# @USAGE: [-f|--final-ABI]
1089# @DESCRIPTION:
1090# Print category, name and slot of package providing Python implementation.
1091# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1092python_get_implementational_package() {
1093 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1094
1095 while (($#)); do
1096 case "$1" in
1097 -f|--final-ABI)
1098 final_ABI="1"
1099 ;;
1100 -*)
1101 die "${FUNCNAME}(): Unrecognized option '$1'"
1102 ;;
1103 *)
1104 die "${FUNCNAME}(): Invalid usage"
1105 ;;
1106 esac
1107 shift
1108 done
1109
1110 if [[ "${final_ABI}" == "1" ]]; then
1111 PYTHON_ABI="$(PYTHON -f --ABI)"
1112 elif [[ -z "${PYTHON_ABI}" ]]; then
1113 PYTHON_ABI="$(PYTHON --ABI)"
1114 fi
1115
1116 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1117 echo "dev-lang/python:${PYTHON_ABI}"
1118 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1119 echo "dev-java/jython:${PYTHON_ABI%-jython}"
1120 fi
1121}
1122
1123# @FUNCTION: python_get_includedir
1124# @USAGE: [-f|--final-ABI]
1125# @DESCRIPTION:
1126# Print path to Python include directory.
1127# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1128python_get_includedir() {
1129 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1130
1131 while (($#)); do
1132 case "$1" in
1133 -f|--final-ABI)
1134 final_ABI="1"
1135 ;;
1136 -*)
1137 die "${FUNCNAME}(): Unrecognized option '$1'"
1138 ;;
1139 *)
1140 die "${FUNCNAME}(): Invalid usage"
1141 ;;
1142 esac
1143 shift
1144 done
1145
1146 if [[ "${final_ABI}" == "1" ]]; then
1147 PYTHON_ABI="$(PYTHON -f --ABI)"
1148 elif [[ -z "${PYTHON_ABI}" ]]; then
1149 PYTHON_ABI="$(PYTHON --ABI)"
1150 fi
1151
1152 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1153 echo "/usr/include/python${PYTHON_ABI}"
1154 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1155 echo "/usr/share/jython-${PYTHON_ABI%-jython}/Include"
1156 fi
1157}
1158
1159# @FUNCTION: python_get_libdir
1160# @USAGE: [-f|--final-ABI]
1161# @DESCRIPTION:
1162# Print path to Python library directory.
1163# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1164python_get_libdir() {
1165 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1166
1167 while (($#)); do
1168 case "$1" in
1169 -f|--final-ABI)
1170 final_ABI="1"
1171 ;;
1172 -*)
1173 die "${FUNCNAME}(): Unrecognized option '$1'"
1174 ;;
1175 *)
1176 die "${FUNCNAME}(): Invalid usage"
1177 ;;
1178 esac
1179 shift
1180 done
1181
1182 if [[ "${final_ABI}" == "1" ]]; then
1183 PYTHON_ABI="$(PYTHON -f --ABI)"
1184 elif [[ -z "${PYTHON_ABI}" ]]; then
1185 PYTHON_ABI="$(PYTHON --ABI)"
1186 fi
1187
1188 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1189 echo "/usr/$(get_libdir)/python${PYTHON_ABI}"
1190 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1191 echo "/usr/share/jython-${PYTHON_ABI%-jython}/Lib"
1192 fi
1193}
1194
1195# @FUNCTION: python_get_sitedir
1196# @USAGE: [-f|--final-ABI]
1197# @DESCRIPTION:
1198# Print path to Python site-packages directory.
1199# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1200python_get_sitedir() {
1201 local options=()
1202
1203 while (($#)); do
1204 case "$1" in
1205 -f|--final-ABI)
1206 options+=("$1")
1207 ;;
1208 -*)
1209 die "${FUNCNAME}(): Unrecognized option '$1'"
1210 ;;
1211 *)
1212 die "${FUNCNAME}(): Invalid usage"
1213 ;;
1214 esac
1215 shift
1216 done
1217
1218 echo "$(python_get_libdir "${options[@]}")/site-packages"
1219}
1220
1221# @FUNCTION: python_get_library
1222# @USAGE: [-f|--final-ABI] [-l|--linker-option]
1223# @DESCRIPTION:
1224# Print path to Python library.
1225# If --linker-option is specified, then "-l${library}" linker option is printed.
1226# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1227python_get_library() {
1228 local final_ABI="0" linker_option="0" PYTHON_ABI="${PYTHON_ABI}"
1229
1230 while (($#)); do
1231 case "$1" in
1232 -f|--final-ABI)
1233 final_ABI="1"
1234 ;;
1235 -l|--linker-option)
1236 linker_option="1"
1237 ;;
1238 -*)
1239 die "${FUNCNAME}(): Unrecognized option '$1'"
1240 ;;
1241 *)
1242 die "${FUNCNAME}(): Invalid usage"
1243 ;;
1244 esac
1245 shift
1246 done
1247
1248 if [[ "${final_ABI}" == "1" ]]; then
1249 PYTHON_ABI="$(PYTHON -f --ABI)"
1250 elif [[ -z "${PYTHON_ABI}" ]]; then
1251 PYTHON_ABI="$(PYTHON --ABI)"
1252 fi
1253
1254 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1255 if [[ "${linker_option}" == "1" ]]; then
1256 echo "-lpython${PYTHON_ABI}"
1257 else
1258 echo "/usr/$(get_libdir)/libpython${PYTHON_ABI}$(get_libname)"
1259 fi
1260 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1261 die "${FUNCNAME}(): Jython does not have shared library"
1262 fi
1263}
1264
1265# @FUNCTION: python_get_version
1266# @USAGE: [-f|--final-ABI] [--major] [--minor] [--micro]
1267# @DESCRIPTION:
1268# Print Python version.
1269# --major, --minor and --micro options cannot be specified simultaneously.
1270# If --major, --minor and --micro options are not specified, then "${major_version}.${minor_version}" is printed.
1271# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1272python_get_version() {
1273 local final_ABI="0" major="0" minor="0" micro="0" python_command
1274
1275 while (($#)); do
1276 case "$1" in
1277 -f|--final-ABI)
1278 final_ABI="1"
1279 ;;
1280 --major)
1281 major="1"
1282 ;;
1283 --minor)
1284 minor="1"
1285 ;;
1286 --micro)
1287 micro="1"
1288 ;;
1289 -*)
1290 die "${FUNCNAME}(): Unrecognized option '$1'"
1291 ;;
1292 *)
1293 die "${FUNCNAME}(): Invalid usage"
1294 ;;
1295 esac
1296 shift
1297 done
1298
1299 if [[ "$((${major} + ${minor} + ${micro}))" -gt 1 ]]; then
1300 die "${FUNCNAME}(): '--major', '--minor' or '--micro' options cannot be specified simultaneously"
1301 fi
1302
1303 if [[ "${major}" == "1" ]]; then
1304 python_command="from sys import version_info; print(version_info[0])"
1305 elif [[ "${minor}" == "1" ]]; then
1306 python_command="from sys import version_info; print(version_info[1])"
1307 elif [[ "${micro}" == "1" ]]; then
1308 python_command="from sys import version_info; print(version_info[2])"
1309 else
1310 python_command="from sys import version_info; print('.'.join(str(x) for x in version_info[:2]))"
1311 fi
1312
1313 if [[ "${final_ABI}" == "1" ]]; then
1314 "$(PYTHON -f)" -c "${python_command}"
1315 else
1316 "$(PYTHON ${PYTHON_ABI})" -c "${python_command}"
1317 fi
1318}
1319 321
1320# ================================================================================================ 322# ================================================================================================
1321# =================================== MISCELLANEOUS FUNCTIONS ==================================== 323# =================================== MISCELLANEOUS FUNCTIONS ====================================
1322# ================================================================================================ 324# ================================================================================================
1323 325
1324_python_implementation() { 326_python_abi-specific_local_scope() {
1325 if [[ "${CATEGORY}/${PN}" == "dev-lang/python" ]]; then 327 [[ " ${FUNCNAME[@]:2} " =~ " "(_python_final_sanity_checks|python_execute_function|python_mod_optimize|python_mod_cleanup)" " ]]
1326 return 0
1327 elif [[ "${CATEGORY}/${PN}" == "dev-java/jython" ]]; then
1328 return 0
1329 else
1330 return 1
1331 fi
1332} 328}
1333 329
1334_python_initialize_prefix_variables() { 330_python_initialize_prefix_variables() {
1335 if has "${EAPI:-0}" 0 1 2; then 331 if has "${EAPI:-0}" 0 1 2; then
1336 if [[ -n "${ROOT}" && -z "${EROOT}" ]]; then 332 if [[ -n "${ROOT}" && -z "${EROOT}" ]]; then
1340 ED="${D%/}${EPREFIX}/" 336 ED="${D%/}${EPREFIX}/"
1341 fi 337 fi
1342 fi 338 fi
1343} 339}
1344 340
1345unset PYTHON_SANITY_CHECKS 341unset PYTHON_SANITY_CHECKS_EXECUTED PYTHON_SKIP_SANITY_CHECKS
1346 342
1347_python_initial_sanity_checks() { 343_python_initial_sanity_checks() {
1348 if [[ "$(declare -p PYTHON_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS="* ]]; then 344 if [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then
1349 # Ensure that /usr/bin/python and /usr/bin/python-config are valid. 345 # Ensure that /usr/bin/python and /usr/bin/python-config are valid.
1350 if [[ "$(readlink "${EPREFIX}/usr/bin/python")" != "python-wrapper" ]]; then 346 if [[ "$(readlink "${EPREFIX}/usr/bin/python")" != "python-wrapper" ]]; then
1351 eerror "'${EPREFIX}/usr/bin/python' is not valid symlink." 347 eerror "'${EPREFIX}/usr/bin/python' is not a valid symlink."
1352 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem." 348 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
1353 die "'${EPREFIX}/usr/bin/python' is not valid symlink" 349 die "'${EPREFIX}/usr/bin/python' is not a valid symlink"
1354 fi 350 fi
1355 if [[ "$(<"${EPREFIX}/usr/bin/python-config")" != *"Gentoo python-config wrapper script"* ]]; then 351 if [[ "$(<"${EPREFIX}/usr/bin/python-config")" != *"Gentoo python-config wrapper script"* ]]; then
1356 eerror "'${EPREFIX}/usr/bin/python-config' is not valid script" 352 eerror "'${EPREFIX}/usr/bin/python-config' is not a valid script"
1357 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem." 353 eerror "Use \`eselect python set \${python_interpreter}\` to fix this problem."
1358 die "'${EPREFIX}/usr/bin/python-config' is not valid script" 354 die "'${EPREFIX}/usr/bin/python-config' is not a valid script"
1359 fi 355 fi
1360 fi 356 fi
1361} 357}
1362 358
1363_python_final_sanity_checks() { 359_python_final_sanity_checks() {
1364 if ! _python_implementation && [[ "$(declare -p PYTHON_SANITY_CHECKS 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS="* ]]; then 360 if ! _python_implementation && [[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED 2> /dev/null)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]; then
1365 local PYTHON_ABI="${PYTHON_ABI}" 361 local PYTHON_ABI="${PYTHON_ABI}"
1366 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI}}; do 362 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI}}; do
1367 # Ensure that appropriate version of Python is installed. 363 # Ensure that appropriate version of Python is installed.
1368 if ! has_version "$(python_get_implementational_package)"; then 364 if ! has_version "$(python_get_implementational_package)"; then
1369 die "$(python_get_implementational_package) is not installed" 365 die "$(python_get_implementational_package) is not installed"
1370 fi 366 fi
1371 367
1372 # Ensure that EPYTHON variable is respected. 368 # Ensure that EPYTHON variable is respected.
1373 if [[ "$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")" != "${PYTHON_ABI}" ]]; then 369 if [[ "$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")" != "${PYTHON_ABI}" ]]; then
1374 eerror "python: '$(type -p python)'" 370 eerror "Path to 'python': '$(type -p python)'"
1375 eerror "ABI: '${ABI}'" 371 eerror "ABI: '${ABI}'"
1376 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'" 372 eerror "DEFAULT_ABI: '${DEFAULT_ABI}'"
1377 eerror "EPYTHON: '$(PYTHON)'" 373 eerror "EPYTHON: '$(PYTHON)'"
1378 eerror "PYTHON_ABI: '${PYTHON_ABI}'" 374 eerror "PYTHON_ABI: '${PYTHON_ABI}'"
1379 eerror "Version of enabled Python: '$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")'" 375 eerror "Locally active version of Python: '$(EPYTHON="$(PYTHON)" python -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")'"
1380 die "'python' does not respect EPYTHON variable" 376 die "'python' does not respect EPYTHON variable"
1381 fi 377 fi
1382 done 378 done
1383 fi 379 fi
1384 PYTHON_SANITY_CHECKS="1" 380 PYTHON_SANITY_CHECKS_EXECUTED="1"
1385} 381}
382
383# @ECLASS-VARIABLE: PYTHON_COLORS
384# @DESCRIPTION:
385# User-configurable colored output.
386PYTHON_COLORS="${PYTHON_COLORS:-0}"
1386 387
1387_python_set_color_variables() { 388_python_set_color_variables() {
1388 if [[ "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then 389 if [[ "${PYTHON_COLORS}" != "0" && "${NOCOLOR:-false}" =~ ^(false|no)$ ]]; then
1389 _BOLD=$'\e[1m' 390 _BOLD=$'\e[1m'
1390 _RED=$'\e[1;31m' 391 _RED=$'\e[1;31m'
1391 _GREEN=$'\e[1;32m' 392 _GREEN=$'\e[1;32m'
1392 _BLUE=$'\e[1;34m' 393 _BLUE=$'\e[1;34m'
1393 _CYAN=$'\e[1;36m' 394 _CYAN=$'\e[1;36m'
1400 _CYAN= 401 _CYAN=
1401 _NORMAL= 402 _NORMAL=
1402 fi 403 fi
1403} 404}
1404 405
406_python_check_python_pkg_setup_execution() {
407 [[ " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " ]] && return
408
409 if ! has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_PKG_SETUP_EXECUTED}" ]]; then
410 die "python_pkg_setup() not called"
411 fi
412}
413
414# @FUNCTION: python_pkg_setup
415# @DESCRIPTION:
416# Perform sanity checks and initialize environment.
417#
418# This function is exported in EAPI 2 and 3 when PYTHON_USE_WITH or PYTHON_USE_WITH_OR variable
419# is set and always in EAPI >=4. Calling of this function is mandatory in EAPI >=4.
420python_pkg_setup() {
421 if [[ "${EBUILD_PHASE}" != "setup" ]]; then
422 die "${FUNCNAME}() can be used only in pkg_setup() phase"
423 fi
424
425 if [[ "$#" -ne 0 ]]; then
426 die "${FUNCNAME}() does not accept arguments"
427 fi
428
429 export JYTHON_SYSTEM_CACHEDIR="1"
430 addwrite "${EPREFIX}/var/cache/jython"
431
432 if _python_package_supporting_installation_for_multiple_python_abis; then
433 _python_calculate_PYTHON_ABIS
434 export EPYTHON="$(PYTHON -f)"
435 else
436 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
437 fi
438
439 if ! has "${EAPI:-0}" 0 1 && [[ -n "${PYTHON_USE_WITH}" || -n "${PYTHON_USE_WITH_OR}" ]]; then
440 if [[ "${PYTHON_USE_WITH_OPT}" ]]; then
441 if [[ "${PYTHON_USE_WITH_OPT}" == !* ]]; then
442 use ${PYTHON_USE_WITH_OPT#!} && return
443 else
444 use !${PYTHON_USE_WITH_OPT} && return
445 fi
446 fi
447
448 python_pkg_setup_check_USE_flags() {
449 local python_atom USE_flag
450 python_atom="$(python_get_implementational_package)"
451
452 for USE_flag in ${PYTHON_USE_WITH}; do
453 if ! has_version "${python_atom}[${USE_flag}]"; then
454 eerror "Please rebuild ${python_atom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
455 die "Please rebuild ${python_atom} with the following USE flags enabled: ${PYTHON_USE_WITH}"
456 fi
457 done
458
459 for USE_flag in ${PYTHON_USE_WITH_OR}; do
460 if has_version "${python_atom}[${USE_flag}]"; then
461 return
462 fi
463 done
464
465 if [[ ${PYTHON_USE_WITH_OR} ]]; then
466 eerror "Please rebuild ${python_atom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
467 die "Please rebuild ${python_atom} with at least one of the following USE flags enabled: ${PYTHON_USE_WITH_OR}"
468 fi
469 }
470
471 if _python_package_supporting_installation_for_multiple_python_abis; then
472 PYTHON_SKIP_SANITY_CHECKS="1" python_execute_function -q python_pkg_setup_check_USE_flags
473 else
474 python_pkg_setup_check_USE_flags
475 fi
476
477 unset -f python_pkg_setup_check_USE_flags
478 fi
479
480 PYTHON_PKG_SETUP_EXECUTED="1"
481}
482
483_PYTHON_SHEBANG_BASE_PART_REGEX='^#![[:space:]]*([^[:space:]]*/usr/bin/env[[:space:]]+)?([^[:space:]]*/)?(jython|pypy-c|python)'
484
1405# @FUNCTION: python_convert_shebangs 485# @FUNCTION: python_convert_shebangs
1406# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_version> <file|directory> [files|directories] 486# @USAGE: [-q|--quiet] [-r|--recursive] [-x|--only-executables] [--] <Python_ABI|Python_version> <file|directory> [files|directories]
1407# @DESCRIPTION: 487# @DESCRIPTION:
1408# Convert shebangs in specified files. Directories can be specified only with --recursive option. 488# Convert shebangs in specified files. Directories can be specified only with --recursive option.
1409python_convert_shebangs() { 489python_convert_shebangs() {
490 _python_check_python_pkg_setup_execution
491
1410 local argument file files=() only_executables="0" python_version quiet="0" recursive="0" 492 local argument file files=() only_executables="0" python_interpreter quiet="0" recursive="0" shebangs_converted="0"
1411 493
1412 while (($#)); do 494 while (($#)); do
1413 case "$1" in 495 case "$1" in
1414 -r|--recursive) 496 -r|--recursive)
1415 recursive="1" 497 recursive="1"
1438 die "${FUNCNAME}(): Missing Python version and files or directories" 520 die "${FUNCNAME}(): Missing Python version and files or directories"
1439 elif [[ "$#" -eq 1 ]]; then 521 elif [[ "$#" -eq 1 ]]; then
1440 die "${FUNCNAME}(): Missing files or directories" 522 die "${FUNCNAME}(): Missing files or directories"
1441 fi 523 fi
1442 524
1443 python_version="$1" 525 if [[ -n "$(_python_get_implementation --ignore-invalid "$1")" ]]; then
526 python_interpreter="$(PYTHON "$1")"
527 else
528 python_interpreter="python$1"
529 fi
1444 shift 530 shift
1445 531
1446 for argument in "$@"; do 532 for argument in "$@"; do
1447 if [[ ! -e "${argument}" ]]; then 533 if [[ ! -e "${argument}" ]]; then
1448 die "${FUNCNAME}(): '${argument}' does not exist" 534 die "${FUNCNAME}(): '${argument}' does not exist"
1449 elif [[ -f "${argument}" ]]; then 535 elif [[ -f "${argument}" ]]; then
1450 files+=("${argument}") 536 files+=("${argument}")
1451 elif [[ -d "${argument}" ]]; then 537 elif [[ -d "${argument}" ]]; then
1452 if [[ "${recursive}" == "1" ]]; then 538 if [[ "${recursive}" == "1" ]]; then
1453 if [[ "${only_executables}" == "1" ]]; then 539 while read -d $'\0' -r file; do
1454 files+=($(find "${argument}" -perm /111 -type f)) 540 files+=("${file}")
1455 else 541 done < <(find "${argument}" $([[ "${only_executables}" == "1" ]] && echo -perm /111) -type f -print0)
1456 files+=($(find "${argument}" -type f))
1457 fi
1458 else 542 else
1459 die "${FUNCNAME}(): '${argument}' is not a regular file" 543 die "${FUNCNAME}(): '${argument}' is not a regular file"
1460 fi 544 fi
1461 else 545 else
1462 die "${FUNCNAME}(): '${argument}' is not a regular file or a directory" 546 die "${FUNCNAME}(): '${argument}' is not a regular file or a directory"
1465 549
1466 for file in "${files[@]}"; do 550 for file in "${files[@]}"; do
1467 file="${file#./}" 551 file="${file#./}"
1468 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue 552 [[ "${only_executables}" == "1" && ! -x "${file}" ]] && continue
1469 553
1470 if [[ "$(head -n1 "${file}")" =~ ^'#!'.*python ]]; then 554 if [[ "$(head -n1 "${file}")" =~ ${_PYTHON_SHEBANG_BASE_PART_REGEX} ]]; then
555 [[ "$(sed -ne "2p" "${file}")" =~ ^"# Gentoo '".*"' wrapper script generated by python_generate_wrapper_scripts()"$ ]] && continue
556
557 shebangs_converted="1"
558
1471 if [[ "${quiet}" == "0" ]]; then 559 if [[ "${quiet}" == "0" ]]; then
1472 einfo "Converting shebang in '${file}'" 560 einfo "Converting shebang in '${file}'"
1473 fi 561 fi
1474 sed -e "1s/python\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?/python${python_version}/" -i "${file}" || die "Conversion of shebang in '${file}' failed"
1475 562
1476 # Delete potential whitespace after "#!". 563 sed -e "1s:^#![[:space:]]*\([^[:space:]]*/usr/bin/env[[:space:]]\)\?[[:space:]]*\([^[:space:]]*/\)\?\(jython\|pypy-c\|python\)\([[:digit:]]\+\(\.[[:digit:]]\+\)\?\)\?\(\$\|[[:space:]].*\):#!\1\2${python_interpreter}\6:" -i "${file}" || die "Conversion of shebang in '${file}' failed"
1477 sed -e '1s/\(^#!\)[[:space:]]*/\1/' -i "${file}" || die "sed '${file}' failed" 564 fi
565 done
566
567 if [[ "${shebangs_converted}" == "0" ]]; then
568 ewarn "${FUNCNAME}(): Python scripts not found"
569 fi
570}
571
572# @FUNCTION: python_clean_py-compile_files
573# @USAGE: [-q|--quiet]
574# @DESCRIPTION:
575# Clean py-compile files to disable byte-compilation.
576python_clean_py-compile_files() {
577 _python_check_python_pkg_setup_execution
578
579 local file files=() quiet="0"
580
581 while (($#)); do
582 case "$1" in
583 -q|--quiet)
584 quiet="1"
585 ;;
586 -*)
587 die "${FUNCNAME}(): Unrecognized option '$1'"
588 ;;
589 *)
590 die "${FUNCNAME}(): Invalid usage"
591 ;;
592 esac
593 shift
594 done
595
596 while read -d $'\0' -r file; do
597 files+=("${file#./}")
598 done < <(find -name py-compile -type f -print0)
599
600 for file in "${files[@]}"; do
601 if [[ "${quiet}" == "0" ]]; then
602 einfo "Cleaning '${file}' file"
603 fi
604 echo "#!/bin/sh" > "${file}"
605 done
606}
607
608# @FUNCTION: python_clean_installation_image
609# @USAGE: [-q|--quiet]
610# @DESCRIPTION:
611# Delete needless files in installation image.
612#
613# This function can be used only in src_install() phase.
614python_clean_installation_image() {
615 if [[ "${EBUILD_PHASE}" != "install" ]]; then
616 die "${FUNCNAME}() can be used only in src_install() phase"
617 fi
618
619 _python_check_python_pkg_setup_execution
620 _python_initialize_prefix_variables
621
622 local file files=() quiet="0"
623
624 while (($#)); do
625 case "$1" in
626 -q|--quiet)
627 quiet="1"
628 ;;
629 -*)
630 die "${FUNCNAME}(): Unrecognized option '$1'"
631 ;;
632 *)
633 die "${FUNCNAME}(): Invalid usage"
634 ;;
635 esac
636 shift
637 done
638
639 while read -d $'\0' -r file; do
640 files+=("${file}")
641 done < <(find "${ED}" "(" -name "*.py[co]" -o -name "*\$py.class" ")" -type f -print0)
642
643 if [[ "${#files[@]}" -gt 0 ]]; then
644 if [[ "${quiet}" == "0" ]]; then
645 ewarn "Deleting byte-compiled Python modules needlessly generated by build system:"
646 fi
647 for file in "${files[@]}"; do
648 if [[ "${quiet}" == "0" ]]; then
649 ewarn " ${file}"
1478 fi 650 fi
651 rm -f "${file}"
652
653 # Delete empty __pycache__ directories.
654 if [[ "${file%/*}" == *"/__pycache__" ]]; then
655 rmdir "${file%/*}" 2> /dev/null
656 fi
1479 done 657 done
658 fi
659
660 python_clean_sitedirs() {
661 if [[ -d "${ED}$(python_get_sitedir)" ]]; then
662 find "${ED}$(python_get_sitedir)" "(" -name "*.c" -o -name "*.h" -o -name "*.la" ")" -type f -print0 | xargs -0 rm -f
663 fi
664 }
665 if _python_package_supporting_installation_for_multiple_python_abis; then
666 python_execute_function -q python_clean_sitedirs
667 else
668 python_clean_sitedirs
669 fi
670
671 unset -f python_clean_sitedirs
672}
673
674# ================================================================================================
675# =========== FUNCTIONS FOR PACKAGES SUPPORTING INSTALLATION FOR MULTIPLE PYTHON ABIS ============
676# ================================================================================================
677
678# @ECLASS-VARIABLE: SUPPORT_PYTHON_ABIS
679# @DESCRIPTION:
680# Set this in EAPI <= 4 to indicate that current package supports installation for
681# multiple Python ABIs.
682
683# @ECLASS-VARIABLE: PYTHON_TESTS_RESTRICTED_ABIS
684# @DESCRIPTION:
685# Space-separated list of Python ABI patterns. Testing in Python ABIs matching any Python ABI
686# patterns specified in this list is skipped.
687
688# @ECLASS-VARIABLE: PYTHON_EXPORT_PHASE_FUNCTIONS
689# @DESCRIPTION:
690# Set this to export phase functions for the following ebuild phases:
691# src_prepare(), src_configure(), src_compile(), src_test(), src_install().
692if ! has "${EAPI:-0}" 0 1; then
693 python_src_prepare() {
694 if [[ "${EBUILD_PHASE}" != "prepare" ]]; then
695 die "${FUNCNAME}() can be used only in src_prepare() phase"
696 fi
697
698 if ! _python_package_supporting_installation_for_multiple_python_abis; then
699 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
700 fi
701
702 _python_check_python_pkg_setup_execution
703
704 if [[ "$#" -ne 0 ]]; then
705 die "${FUNCNAME}() does not accept arguments"
706 fi
707
708 python_copy_sources
709 }
710
711 for python_default_function in src_configure src_compile src_test; do
712 eval "python_${python_default_function}() {
713 if [[ \"\${EBUILD_PHASE}\" != \"${python_default_function#src_}\" ]]; then
714 die \"\${FUNCNAME}() can be used only in ${python_default_function}() phase\"
715 fi
716
717 if ! _python_package_supporting_installation_for_multiple_python_abis; then
718 die \"\${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs\"
719 fi
720
721 _python_check_python_pkg_setup_execution
722
723 python_execute_function -d -s -- \"\$@\"
724 }"
725 done
726 unset python_default_function
727
728 python_src_install() {
729 if [[ "${EBUILD_PHASE}" != "install" ]]; then
730 die "${FUNCNAME}() can be used only in src_install() phase"
731 fi
732
733 if ! _python_package_supporting_installation_for_multiple_python_abis; then
734 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
735 fi
736
737 _python_check_python_pkg_setup_execution
738
739 if has "${EAPI:-0}" 0 1 2 3; then
740 python_execute_function -d -s -- "$@"
741 else
742 python_installation() {
743 emake DESTDIR="${T}/images/${PYTHON_ABI}" install "$@"
744 }
745 python_execute_function -s python_installation "$@"
746 unset python_installation
747
748 python_merge_intermediate_installation_images "${T}/images"
749 fi
750 }
751
752 if [[ -n "${PYTHON_EXPORT_PHASE_FUNCTIONS}" ]]; then
753 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
754 fi
755fi
756
757unset PYTHON_ABIS
758
759_python_calculate_PYTHON_ABIS() {
760 if ! _python_package_supporting_installation_for_multiple_python_abis; then
761 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
762 fi
763
764 _python_initial_sanity_checks
765
766 if [[ "$(declare -p PYTHON_ABIS 2> /dev/null)" != "declare -x PYTHON_ABIS="* ]]; then
767 local PYTHON_ABI
768
769 if [[ "$(declare -p USE_PYTHON 2> /dev/null)" == "declare -x USE_PYTHON="* ]]; then
770 local cpython_enabled="0"
771
772 if [[ -z "${USE_PYTHON}" ]]; then
773 die "USE_PYTHON variable is empty"
774 fi
775
776 for PYTHON_ABI in ${USE_PYTHON}; do
777 if ! has "${PYTHON_ABI}" "${_PYTHON_GLOBALLY_SUPPORTED_ABIS[@]}"; then
778 die "USE_PYTHON variable contains invalid value '${PYTHON_ABI}'"
779 fi
780
781 if has "${PYTHON_ABI}" "${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}" "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}"; then
782 cpython_enabled="1"
783 fi
784
785 if ! _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${RESTRICT_PYTHON_ABIS}"; then
786 export PYTHON_ABIS+="${PYTHON_ABIS:+ }${PYTHON_ABI}"
787 fi
788 done
789
790 if [[ -z "${PYTHON_ABIS//[${IFS}]/}" ]]; then
791 die "USE_PYTHON variable does not enable any Python ABI supported by ${CATEGORY}/${PF}"
792 fi
793
794 if [[ "${cpython_enabled}" == "0" ]]; then
795 die "USE_PYTHON variable does not enable any CPython ABI"
796 fi
797 else
798 local python_version python2_version python3_version support_python_major_version
799
800 if ! has_version "dev-lang/python"; then
801 die "${FUNCNAME}(): 'dev-lang/python' is not installed"
802 fi
803
804 python_version="$("${EPREFIX}/usr/bin/python" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
805
806 if has_version "=dev-lang/python-2*"; then
807 if [[ "$(readlink "${EPREFIX}/usr/bin/python2")" != "python2."* ]]; then
808 die "'${EPREFIX}/usr/bin/python2' is not a valid symlink"
809 fi
810
811 python2_version="$("${EPREFIX}/usr/bin/python2" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
812
813 support_python_major_version="0"
814 for PYTHON_ABI in "${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}"; do
815 if ! _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${RESTRICT_PYTHON_ABIS}"; then
816 support_python_major_version="1"
817 break
818 fi
819 done
820 if [[ "${support_python_major_version}" == "1" ]]; then
821 if _python_check_python_abi_matching --patterns-list "${python2_version}" "${RESTRICT_PYTHON_ABIS}"; then
822 die "Active version of CPython 2 is not supported by ${CATEGORY}/${PF}"
823 fi
824 else
825 python2_version=""
826 fi
827 fi
828
829 if has_version "=dev-lang/python-3*"; then
830 if [[ "$(readlink "${EPREFIX}/usr/bin/python3")" != "python3."* ]]; then
831 die "'${EPREFIX}/usr/bin/python3' is not a valid symlink"
832 fi
833
834 python3_version="$("${EPREFIX}/usr/bin/python3" -c 'from sys import version_info; print(".".join(str(x) for x in version_info[:2]))')"
835
836 support_python_major_version="0"
837 for PYTHON_ABI in "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}"; do
838 if ! _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${RESTRICT_PYTHON_ABIS}"; then
839 support_python_major_version="1"
840 break
841 fi
842 done
843 if [[ "${support_python_major_version}" == "1" ]]; then
844 if _python_check_python_abi_matching --patterns-list "${python3_version}" "${RESTRICT_PYTHON_ABIS}"; then
845 die "Active version of CPython 3 is not supported by ${CATEGORY}/${PF}"
846 fi
847 else
848 python3_version=""
849 fi
850 fi
851
852 if [[ -z "${python2_version}" && -z "${python3_version}" ]]; then
853 eerror "${CATEGORY}/${PF} requires at least one of the following packages:"
854 for PYTHON_ABI in "${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}" "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}"; do
855 if ! _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${RESTRICT_PYTHON_ABIS}"; then
856 eerror " dev-lang/python:${PYTHON_ABI}"
857 fi
858 done
859 die "No supported version of CPython installed"
860 fi
861
862 if [[ -n "${python2_version}" && "${python_version}" == "2."* && "${python_version}" != "${python2_version}" ]]; then
863 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python2' symlink"
864 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
865 die "Incorrect configuration of Python"
866 fi
867 if [[ -n "${python3_version}" && "${python_version}" == "3."* && "${python_version}" != "${python3_version}" ]]; then
868 eerror "Python wrapper is configured incorrectly or '${EPREFIX}/usr/bin/python3' symlink"
869 eerror "is set incorrectly. Use \`eselect python\` to fix configuration."
870 die "Incorrect configuration of Python"
871 fi
872
873 PYTHON_ABIS="${python2_version} ${python3_version}"
874 PYTHON_ABIS="${PYTHON_ABIS# }"
875 export PYTHON_ABIS="${PYTHON_ABIS% }"
876 fi
877 fi
878
879 _python_final_sanity_checks
880}
881
882_python_prepare_flags() {
883 local array=() deleted_flag element flags new_value old_flag old_value operator pattern prefix variable
884
885 for variable in CPPFLAGS CFLAGS CXXFLAGS LDFLAGS; do
886 eval "_PYTHON_SAVED_${variable}=\"\${!variable}\""
887 for prefix in PYTHON_USER_ PYTHON_; do
888 if [[ "$(declare -p ${prefix}${variable} 2> /dev/null)" == "declare -a ${prefix}${variable}="* ]]; then
889 eval "array=(\"\${${prefix}${variable}[@]}\")"
890 for element in "${array[@]}"; do
891 if [[ "${element}" =~ ^${_PYTHON_ABI_PATTERN_REGEX}\ (\+|-)\ .+ ]]; then
892 pattern="${element%% *}"
893 element="${element#* }"
894 operator="${element%% *}"
895 flags="${element#* }"
896 if _python_check_python_abi_matching "${PYTHON_ABI}" "${pattern}"; then
897 if [[ "${operator}" == "+" ]]; then
898 eval "export ${variable}+=\"\${variable:+ }${flags}\""
899 elif [[ "${operator}" == "-" ]]; then
900 flags="${flags// /$'\n'}"
901 old_value="${!variable// /$'\n'}"
902 new_value=""
903 while read old_flag; do
904 while read deleted_flag; do
905 if [[ "${old_flag}" == ${deleted_flag} ]]; then
906 continue 2
907 fi
908 done <<< "${flags}"
909 new_value+="${new_value:+ }${old_flag}"
910 done <<< "${old_value}"
911 eval "export ${variable}=\"\${new_value}\""
912 fi
913 fi
914 else
915 die "Element '${element}' of ${prefix}${variable} array has invalid syntax"
916 fi
917 done
918 elif [[ -n "$(declare -p ${prefix}${variable} 2> /dev/null)" ]]; then
919 die "${prefix}${variable} should be indexed array"
920 fi
921 done
922 done
923}
924
925_python_restore_flags() {
926 local variable
927
928 for variable in CPPFLAGS CFLAGS CXXFLAGS LDFLAGS; do
929 eval "${variable}=\"\${_PYTHON_SAVED_${variable}}\""
930 unset _PYTHON_SAVED_${variable}
931 done
932}
933
934# @FUNCTION: python_execute_function
935# @USAGE: [--action-message message] [-d|--default-function] [--failure-message message] [-f|--final-ABI] [--nonfatal] [-q|--quiet] [-s|--separate-build-dirs] [--source-dir source_directory] [--] <function> [arguments]
936# @DESCRIPTION:
937# Execute specified function for each value of PYTHON_ABIS, optionally passing additional
938# arguments. The specified function can use PYTHON_ABI and BUILDDIR variables.
939python_execute_function() {
940 if ! _python_package_supporting_installation_for_multiple_python_abis; then
941 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
942 fi
943
944 _python_check_python_pkg_setup_execution
945 _python_set_color_variables
946
947 local action action_message action_message_template default_function="0" failure_message failure_message_template final_ABI="0" function iterated_PYTHON_ABIS nonfatal="0" previous_directory previous_directory_stack previous_directory_stack_length PYTHON_ABI quiet="0" return_code separate_build_dirs="0" source_dir
948
949 while (($#)); do
950 case "$1" in
951 --action-message)
952 action_message_template="$2"
953 shift
954 ;;
955 -d|--default-function)
956 default_function="1"
957 ;;
958 --failure-message)
959 failure_message_template="$2"
960 shift
961 ;;
962 -f|--final-ABI)
963 final_ABI="1"
964 ;;
965 --nonfatal)
966 nonfatal="1"
967 ;;
968 -q|--quiet)
969 quiet="1"
970 ;;
971 -s|--separate-build-dirs)
972 separate_build_dirs="1"
973 ;;
974 --source-dir)
975 source_dir="$2"
976 shift
977 ;;
978 --)
979 shift
980 break
981 ;;
982 -*)
983 die "${FUNCNAME}(): Unrecognized option '$1'"
984 ;;
985 *)
986 break
987 ;;
988 esac
989 shift
990 done
991
992 if [[ -n "${source_dir}" && "${separate_build_dirs}" == 0 ]]; then
993 die "${FUNCNAME}(): '--source-dir' option can be specified only with '--separate-build-dirs' option"
994 fi
995
996 if [[ "${default_function}" == "0" ]]; then
997 if [[ "$#" -eq 0 ]]; then
998 die "${FUNCNAME}(): Missing function name"
999 fi
1000 function="$1"
1001 shift
1002
1003 if [[ -z "$(type -t "${function}")" ]]; then
1004 die "${FUNCNAME}(): '${function}' function is not defined"
1005 fi
1006 else
1007 if has "${EAPI:-0}" 0 1; then
1008 die "${FUNCNAME}(): '--default-function' option cannot be used in this EAPI"
1009 fi
1010
1011 if [[ "${EBUILD_PHASE}" == "configure" ]]; then
1012 if has "${EAPI}" 2 3; then
1013 python_default_function() {
1014 econf "$@"
1015 }
1016 else
1017 python_default_function() {
1018 nonfatal econf "$@"
1019 }
1020 fi
1021 elif [[ "${EBUILD_PHASE}" == "compile" ]]; then
1022 python_default_function() {
1023 emake "$@"
1024 }
1025 elif [[ "${EBUILD_PHASE}" == "test" ]]; then
1026 python_default_function() {
1027 # Stolen from portage's _eapi0_src_test()
1028 local emake_cmd="${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE}"
1029 if ${emake_cmd} -j1 -n check &> /dev/null; then
1030 ${emake_cmd} -j1 check "$@"
1031 elif ${emake_cmd} -j1 -n test &> /dev/null; then
1032 ${emake_cmd} -j1 test "$@"
1033 fi
1034 }
1035 elif [[ "${EBUILD_PHASE}" == "install" ]]; then
1036 python_default_function() {
1037 emake DESTDIR="${D}" install "$@"
1038 }
1039 else
1040 die "${FUNCNAME}(): '--default-function' option cannot be used in this ebuild phase"
1041 fi
1042 function="python_default_function"
1043 fi
1044
1045 # Ensure that python_execute_function() cannot be directly or indirectly called by python_execute_function().
1046 if _python_abi-specific_local_scope; then
1047 die "${FUNCNAME}(): Invalid call stack"
1048 fi
1049
1050 if [[ "${quiet}" == "0" ]]; then
1051 [[ "${EBUILD_PHASE}" == "setup" ]] && action="Setting up"
1052 [[ "${EBUILD_PHASE}" == "unpack" ]] && action="Unpacking"
1053 [[ "${EBUILD_PHASE}" == "prepare" ]] && action="Preparation"
1054 [[ "${EBUILD_PHASE}" == "configure" ]] && action="Configuration"
1055 [[ "${EBUILD_PHASE}" == "compile" ]] && action="Building"
1056 [[ "${EBUILD_PHASE}" == "test" ]] && action="Testing"
1057 [[ "${EBUILD_PHASE}" == "install" ]] && action="Installation"
1058 [[ "${EBUILD_PHASE}" == "preinst" ]] && action="Preinstallation"
1059 [[ "${EBUILD_PHASE}" == "postinst" ]] && action="Postinstallation"
1060 [[ "${EBUILD_PHASE}" == "prerm" ]] && action="Preuninstallation"
1061 [[ "${EBUILD_PHASE}" == "postrm" ]] && action="Postuninstallation"
1062 fi
1063
1064 _python_calculate_PYTHON_ABIS
1065 if [[ "${final_ABI}" == "1" ]]; then
1066 iterated_PYTHON_ABIS="$(PYTHON -f --ABI)"
1067 else
1068 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
1069 fi
1070 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
1071 if [[ "${EBUILD_PHASE}" == "test" ]] && _python_check_python_abi_matching --patterns-list "${PYTHON_ABI}" "${PYTHON_TESTS_RESTRICTED_ABIS}"; then
1072 if [[ "${quiet}" == "0" ]]; then
1073 echo " ${_GREEN}*${_NORMAL} ${_BLUE}Testing of ${CATEGORY}/${PF} with $(python_get_implementation_and_version) skipped${_NORMAL}"
1074 fi
1075 continue
1076 fi
1077
1078 _python_prepare_flags
1079
1080 if [[ "${quiet}" == "0" ]]; then
1081 if [[ -n "${action_message_template}" ]]; then
1082 eval "action_message=\"${action_message_template}\""
1083 else
1084 action_message="${action} of ${CATEGORY}/${PF} with $(python_get_implementation_and_version)..."
1085 fi
1086 echo " ${_GREEN}*${_NORMAL} ${_BLUE}${action_message}${_NORMAL}"
1087 fi
1088
1089 if [[ "${separate_build_dirs}" == "1" ]]; then
1090 if [[ -n "${source_dir}" ]]; then
1091 export BUILDDIR="${S}/${source_dir}-${PYTHON_ABI}"
1092 else
1093 export BUILDDIR="${S}-${PYTHON_ABI}"
1094 fi
1095 pushd "${BUILDDIR}" > /dev/null || die "pushd failed"
1096 else
1097 export BUILDDIR="${S}"
1098 fi
1099
1100 previous_directory="$(pwd)"
1101 previous_directory_stack="$(dirs -p)"
1102 previous_directory_stack_length="$(dirs -p | wc -l)"
1103
1104 if ! has "${EAPI}" 0 1 2 3 && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
1105 EPYTHON="$(PYTHON)" nonfatal "${function}" "$@"
1106 else
1107 EPYTHON="$(PYTHON)" "${function}" "$@"
1108 fi
1109
1110 return_code="$?"
1111
1112 _python_restore_flags
1113
1114 if [[ "${return_code}" -ne 0 ]]; then
1115 if [[ -n "${failure_message_template}" ]]; then
1116 eval "failure_message=\"${failure_message_template}\""
1117 else
1118 failure_message="${action} failed with $(python_get_implementation_and_version) in ${function}() function"
1119 fi
1120
1121 if [[ "${nonfatal}" == "1" ]]; then
1122 if [[ "${quiet}" == "0" ]]; then
1123 ewarn "${failure_message}"
1124 fi
1125 elif [[ "${final_ABI}" == "0" ]] && has "${PYTHON_ABI}" ${FAILURE_TOLERANT_PYTHON_ABIS}; then
1126 if [[ "${EBUILD_PHASE}" != "test" ]] || ! has test-fail-continue ${FEATURES}; then
1127 local enabled_PYTHON_ABIS= other_PYTHON_ABI
1128 for other_PYTHON_ABI in ${PYTHON_ABIS}; do
1129 [[ "${other_PYTHON_ABI}" != "${PYTHON_ABI}" ]] && enabled_PYTHON_ABIS+="${enabled_PYTHON_ABIS:+ }${other_PYTHON_ABI}"
1130 done
1131 export PYTHON_ABIS="${enabled_PYTHON_ABIS}"
1132 fi
1133 if [[ "${quiet}" == "0" ]]; then
1134 ewarn "${failure_message}"
1135 fi
1136 if [[ -z "${PYTHON_ABIS}" ]]; then
1137 die "${function}() function failed with all enabled Python ABIs"
1138 fi
1139 else
1140 die "${failure_message}"
1141 fi
1142 fi
1143
1144 # Ensure that directory stack has not been decreased.
1145 if [[ "$(dirs -p | wc -l)" -lt "${previous_directory_stack_length}" ]]; then
1146 die "Directory stack decreased illegally"
1147 fi
1148
1149 # Avoid side effects of earlier returning from the specified function.
1150 while [[ "$(dirs -p | wc -l)" -gt "${previous_directory_stack_length}" ]]; do
1151 popd > /dev/null || die "popd failed"
1152 done
1153
1154 # Ensure that the bottom part of directory stack has not been changed. Restore
1155 # previous directory (from before running of the specified function) before
1156 # comparison of directory stacks to avoid mismatch of directory stacks after
1157 # potential using of 'cd' to change current directory. Restoration of previous
1158 # directory allows to safely use 'cd' to change current directory in the
1159 # specified function without changing it back to original directory.
1160 cd "${previous_directory}"
1161 if [[ "$(dirs -p)" != "${previous_directory_stack}" ]]; then
1162 die "Directory stack changed illegally"
1163 fi
1164
1165 if [[ "${separate_build_dirs}" == "1" ]]; then
1166 popd > /dev/null || die "popd failed"
1167 fi
1168 unset BUILDDIR
1169 done
1170
1171 if [[ "${default_function}" == "1" ]]; then
1172 unset -f python_default_function
1173 fi
1174}
1175
1176# @FUNCTION: python_copy_sources
1177# @USAGE: <directory="${S}"> [directory]
1178# @DESCRIPTION:
1179# Copy unpacked sources of current package to separate build directory for each Python ABI.
1180python_copy_sources() {
1181 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1182 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1183 fi
1184
1185 _python_check_python_pkg_setup_execution
1186
1187 local dir dirs=() PYTHON_ABI
1188
1189 if [[ "$#" -eq 0 ]]; then
1190 if [[ "${WORKDIR}" == "${S}" ]]; then
1191 die "${FUNCNAME}() cannot be used with current value of S variable"
1192 fi
1193 dirs=("${S%/}")
1194 else
1195 dirs=("$@")
1196 fi
1197
1198 _python_calculate_PYTHON_ABIS
1199 for PYTHON_ABI in ${PYTHON_ABIS}; do
1200 for dir in "${dirs[@]}"; do
1201 cp -pr "${dir}" "${dir}-${PYTHON_ABI}" > /dev/null || die "Copying of sources failed"
1202 done
1203 done
1204}
1205
1206# @FUNCTION: python_generate_wrapper_scripts
1207# @USAGE: [-E|--respect-EPYTHON] [-f|--force] [-q|--quiet] [--] <file> [files]
1208# @DESCRIPTION:
1209# Generate wrapper scripts. Existing files are overwritten only with --force option.
1210# If --respect-EPYTHON option is specified, then generated wrapper scripts will
1211# respect EPYTHON variable at run time.
1212#
1213# This function can be used only in src_install() phase.
1214python_generate_wrapper_scripts() {
1215 if [[ "${EBUILD_PHASE}" != "install" ]]; then
1216 die "${FUNCNAME}() can be used only in src_install() phase"
1217 fi
1218
1219 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1220 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1221 fi
1222
1223 _python_check_python_pkg_setup_execution
1224 _python_initialize_prefix_variables
1225
1226 local eselect_python_option file force="0" quiet="0" PYTHON_ABI PYTHON_ABIS_list python2_enabled="0" python3_enabled="0" respect_EPYTHON="0"
1227
1228 while (($#)); do
1229 case "$1" in
1230 -E|--respect-EPYTHON)
1231 respect_EPYTHON="1"
1232 ;;
1233 -f|--force)
1234 force="1"
1235 ;;
1236 -q|--quiet)
1237 quiet="1"
1238 ;;
1239 --)
1240 shift
1241 break
1242 ;;
1243 -*)
1244 die "${FUNCNAME}(): Unrecognized option '$1'"
1245 ;;
1246 *)
1247 break
1248 ;;
1249 esac
1250 shift
1251 done
1252
1253 if [[ "$#" -eq 0 ]]; then
1254 die "${FUNCNAME}(): Missing arguments"
1255 fi
1256
1257 _python_calculate_PYTHON_ABIS
1258 for PYTHON_ABI in "${_CPYTHON2_GLOBALLY_SUPPORTED_ABIS[@]}"; do
1259 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
1260 python2_enabled="1"
1261 fi
1262 done
1263 for PYTHON_ABI in "${_CPYTHON3_GLOBALLY_SUPPORTED_ABIS[@]}"; do
1264 if has "${PYTHON_ABI}" ${PYTHON_ABIS}; then
1265 python3_enabled="1"
1266 fi
1267 done
1268
1269 if [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "1" ]]; then
1270 eselect_python_option=
1271 elif [[ "${python2_enabled}" == "1" && "${python3_enabled}" == "0" ]]; then
1272 eselect_python_option="--python2"
1273 elif [[ "${python2_enabled}" == "0" && "${python3_enabled}" == "1" ]]; then
1274 eselect_python_option="--python3"
1275 else
1276 die "${FUNCNAME}(): Unsupported environment"
1277 fi
1278
1279 PYTHON_ABIS_list="$("$(PYTHON -f)" -c "print(', '.join('\"%s\"' % x for x in reversed('${PYTHON_ABIS}'.split())))")"
1280
1281 for file in "$@"; do
1282 if [[ -f "${file}" && "${force}" == "0" ]]; then
1283 die "${FUNCNAME}(): '${file}' already exists"
1284 fi
1285
1286 if [[ "${quiet}" == "0" ]]; then
1287 einfo "Generating '${file#${ED%/}}' wrapper script"
1288 fi
1289
1290 cat << EOF > "${file}"
1291#!/usr/bin/env python
1292# Gentoo '${file##*/}' wrapper script generated by python_generate_wrapper_scripts()
1293
1294import os
1295import re
1296import subprocess
1297import sys
1298
1299cpython_ABI_re = re.compile(r"^(\d+\.\d+)$")
1300jython_ABI_re = re.compile(r"^(\d+\.\d+)-jython$")
1301pypy_ABI_re = re.compile(r"^\d+\.\d+-pypy-(\d+\.\d+)$")
1302cpython_interpreter_re = re.compile(r"^python(\d+\.\d+)$")
1303jython_interpreter_re = re.compile(r"^jython(\d+\.\d+)$")
1304pypy_interpreter_re = re.compile(r"^pypy-c(\d+\.\d+)$")
1305cpython_shebang_re = re.compile(r"^#![ \t]*(?:${EPREFIX}/usr/bin/python|(?:${EPREFIX})?/usr/bin/env[ \t]+(?:${EPREFIX}/usr/bin/)?python)")
1306python_shebang_options_re = re.compile(r"^#![ \t]*${EPREFIX}/usr/bin/(?:jython|pypy-c|python)(?:\d+(?:\.\d+)?)?[ \t]+(-\S)")
1307python_verification_output_re = re.compile("^GENTOO_PYTHON_TARGET_SCRIPT_PATH supported\n$")
1308
1309#pypy_versions_mapping = {
1310# "1.5": "2.7",
1311# "1.6": "2.7",
1312# "1.7": "2.7",
1313# "1.8": "2.7",
1314# "1.9": "2.7",
1315# "2.0": "2.7",
1316#}
1317
1318def get_PYTHON_ABI(python_interpreter):
1319 cpython_matched = cpython_interpreter_re.match(python_interpreter)
1320 jython_matched = jython_interpreter_re.match(python_interpreter)
1321 pypy_matched = pypy_interpreter_re.match(python_interpreter)
1322 if cpython_matched is not None:
1323 PYTHON_ABI = cpython_matched.group(1)
1324 elif jython_matched is not None:
1325 PYTHON_ABI = jython_matched.group(1) + "-jython"
1326 elif pypy_matched is not None:
1327 #PYTHON_ABI = pypy_versions_mapping[pypy_matched.group(1)] + "-pypy-" + pypy_matched.group(1)
1328 PYTHON_ABI = "2.7-pypy-" + pypy_matched.group(1)
1329 else:
1330 PYTHON_ABI = None
1331 return PYTHON_ABI
1332
1333def get_python_interpreter(PYTHON_ABI):
1334 cpython_matched = cpython_ABI_re.match(PYTHON_ABI)
1335 jython_matched = jython_ABI_re.match(PYTHON_ABI)
1336 pypy_matched = pypy_ABI_re.match(PYTHON_ABI)
1337 if cpython_matched is not None:
1338 python_interpreter = "python" + cpython_matched.group(1)
1339 elif jython_matched is not None:
1340 python_interpreter = "jython" + jython_matched.group(1)
1341 elif pypy_matched is not None:
1342 python_interpreter = "pypy-c" + pypy_matched.group(1)
1343 else:
1344 python_interpreter = None
1345 return python_interpreter
1346
1347EOF
1348 if [[ "$?" != "0" ]]; then
1349 die "${FUNCNAME}(): Generation of '$1' failed"
1350 fi
1351 if [[ "${respect_EPYTHON}" == "1" ]]; then
1352 cat << EOF >> "${file}"
1353python_interpreter = os.environ.get("EPYTHON")
1354if python_interpreter:
1355 PYTHON_ABI = get_PYTHON_ABI(python_interpreter)
1356 if PYTHON_ABI is None:
1357 sys.stderr.write("%s: EPYTHON variable has unrecognized value '%s'\n" % (sys.argv[0], python_interpreter))
1358 sys.exit(1)
1359else:
1360 try:
1361 environment = os.environ.copy()
1362 environment["ROOT"] = "/"
1363 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], env=environment, stdout=subprocess.PIPE)
1364 if eselect_process.wait() != 0:
1365 raise ValueError
1366 except (OSError, ValueError):
1367 sys.stderr.write("%s: Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n" % sys.argv[0])
1368 sys.exit(1)
1369
1370 python_interpreter = eselect_process.stdout.read()
1371 if not isinstance(python_interpreter, str):
1372 # Python 3
1373 python_interpreter = python_interpreter.decode()
1374 python_interpreter = python_interpreter.rstrip("\n")
1375
1376 PYTHON_ABI = get_PYTHON_ABI(python_interpreter)
1377 if PYTHON_ABI is None:
1378 sys.stderr.write("%s: 'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s'\n" % (sys.argv[0], python_interpreter))
1379 sys.exit(1)
1380
1381wrapper_script_path = os.path.realpath(sys.argv[0])
1382target_executable_path = "%s-%s" % (wrapper_script_path, PYTHON_ABI)
1383if not os.path.exists(target_executable_path):
1384 sys.stderr.write("%s: '%s' does not exist\n" % (sys.argv[0], target_executable_path))
1385 sys.exit(1)
1386EOF
1387 if [[ "$?" != "0" ]]; then
1388 die "${FUNCNAME}(): Generation of '$1' failed"
1389 fi
1390 else
1391 cat << EOF >> "${file}"
1392try:
1393 environment = os.environ.copy()
1394 environment["ROOT"] = "/"
1395 eselect_process = subprocess.Popen(["${EPREFIX}/usr/bin/eselect", "python", "show"${eselect_python_option:+, $(echo "\"")}${eselect_python_option}${eselect_python_option:+$(echo "\"")}], env=environment, stdout=subprocess.PIPE)
1396 if eselect_process.wait() != 0:
1397 raise ValueError
1398except (OSError, ValueError):
1399 sys.stderr.write("%s: Execution of 'eselect python show${eselect_python_option:+ }${eselect_python_option}' failed\n" % sys.argv[0])
1400 sys.exit(1)
1401
1402python_interpreter = eselect_process.stdout.read()
1403if not isinstance(python_interpreter, str):
1404 # Python 3
1405 python_interpreter = python_interpreter.decode()
1406python_interpreter = python_interpreter.rstrip("\n")
1407
1408PYTHON_ABI = get_PYTHON_ABI(python_interpreter)
1409if PYTHON_ABI is None:
1410 sys.stderr.write("%s: 'eselect python show${eselect_python_option:+ }${eselect_python_option}' printed unrecognized value '%s'\n" % (sys.argv[0], python_interpreter))
1411 sys.exit(1)
1412
1413wrapper_script_path = os.path.realpath(sys.argv[0])
1414for PYTHON_ABI in [PYTHON_ABI, ${PYTHON_ABIS_list}]:
1415 target_executable_path = "%s-%s" % (wrapper_script_path, PYTHON_ABI)
1416 if os.path.exists(target_executable_path):
1417 break
1418else:
1419 sys.stderr.write("%s: No target script exists for '%s'\n" % (sys.argv[0], wrapper_script_path))
1420 sys.exit(1)
1421
1422python_interpreter = get_python_interpreter(PYTHON_ABI)
1423if python_interpreter is None:
1424 sys.stderr.write("%s: Unrecognized Python ABI '%s'\n" % (sys.argv[0], PYTHON_ABI))
1425 sys.exit(1)
1426EOF
1427 if [[ "$?" != "0" ]]; then
1428 die "${FUNCNAME}(): Generation of '$1' failed"
1429 fi
1430 fi
1431 cat << EOF >> "${file}"
1432
1433target_executable = open(target_executable_path, "rb")
1434target_executable_first_line = target_executable.readline()
1435target_executable.close()
1436if not isinstance(target_executable_first_line, str):
1437 # Python 3
1438 target_executable_first_line = target_executable_first_line.decode("utf_8", "replace")
1439
1440options = []
1441python_shebang_options_matched = python_shebang_options_re.match(target_executable_first_line)
1442if python_shebang_options_matched is not None:
1443 options = [python_shebang_options_matched.group(1)]
1444
1445cpython_shebang_matched = cpython_shebang_re.match(target_executable_first_line)
1446
1447if cpython_shebang_matched is not None:
1448 try:
1449 python_interpreter_path = "${EPREFIX}/usr/bin/%s" % python_interpreter
1450 os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"] = "1"
1451 python_verification_process = subprocess.Popen([python_interpreter_path, "-c", "pass"], stdout=subprocess.PIPE)
1452 del os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"]
1453 if python_verification_process.wait() != 0:
1454 raise ValueError
1455
1456 python_verification_output = python_verification_process.stdout.read()
1457 if not isinstance(python_verification_output, str):
1458 # Python 3
1459 python_verification_output = python_verification_output.decode()
1460
1461 if not python_verification_output_re.match(python_verification_output):
1462 raise ValueError
1463
1464 if cpython_interpreter_re.match(python_interpreter) is not None:
1465 os.environ["GENTOO_PYTHON_PROCESS_NAME"] = os.path.basename(sys.argv[0])
1466 os.environ["GENTOO_PYTHON_WRAPPER_SCRIPT_PATH"] = sys.argv[0]
1467 os.environ["GENTOO_PYTHON_TARGET_SCRIPT_PATH"] = target_executable_path
1468
1469 if hasattr(os, "execv"):
1470 os.execv(python_interpreter_path, [python_interpreter_path] + options + sys.argv)
1471 else:
1472 sys.exit(subprocess.Popen([python_interpreter_path] + options + sys.argv).wait())
1473 except (KeyboardInterrupt, SystemExit):
1474 raise
1475 except:
1476 pass
1477 for variable in ("GENTOO_PYTHON_PROCESS_NAME", "GENTOO_PYTHON_WRAPPER_SCRIPT_PATH", "GENTOO_PYTHON_TARGET_SCRIPT_PATH", "GENTOO_PYTHON_TARGET_SCRIPT_PATH_VERIFICATION"):
1478 if variable in os.environ:
1479 del os.environ[variable]
1480
1481if hasattr(os, "execv"):
1482 os.execv(target_executable_path, sys.argv)
1483else:
1484 sys.exit(subprocess.Popen([target_executable_path] + sys.argv[1:]).wait())
1485EOF
1486 if [[ "$?" != "0" ]]; then
1487 die "${FUNCNAME}(): Generation of '$1' failed"
1488 fi
1489 fperms +x "${file#${ED%/}}" || die "fperms '${file}' failed"
1490 done
1491}
1492
1493# @ECLASS-VARIABLE: PYTHON_VERSIONED_SCRIPTS
1494# @DESCRIPTION:
1495# Array of regular expressions of paths to versioned Python scripts.
1496# Python scripts in /usr/bin and /usr/sbin are versioned by default.
1497
1498# @ECLASS-VARIABLE: PYTHON_VERSIONED_EXECUTABLES
1499# @DESCRIPTION:
1500# Array of regular expressions of paths to versioned executables (including Python scripts).
1501
1502# @ECLASS-VARIABLE: PYTHON_NONVERSIONED_EXECUTABLES
1503# @DESCRIPTION:
1504# Array of regular expressions of paths to nonversioned executables (including Python scripts).
1505
1506# @FUNCTION: python_merge_intermediate_installation_images
1507# @USAGE: [-q|--quiet] [--] <intermediate_installation_images_directory>
1508# @DESCRIPTION:
1509# Merge intermediate installation images into installation image.
1510#
1511# This function can be used only in src_install() phase.
1512python_merge_intermediate_installation_images() {
1513 if [[ "${EBUILD_PHASE}" != "install" ]]; then
1514 die "${FUNCNAME}() can be used only in src_install() phase"
1515 fi
1516
1517 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1518 die "${FUNCNAME}() cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1519 fi
1520
1521 _python_check_python_pkg_setup_execution
1522 _python_initialize_prefix_variables
1523
1524 local absolute_file b file files=() intermediate_installation_images_directory PYTHON_ABI quiet="0" regex shebang version_executable wrapper_scripts=() wrapper_scripts_set=()
1525
1526 while (($#)); do
1527 case "$1" in
1528 -q|--quiet)
1529 quiet="1"
1530 ;;
1531 --)
1532 shift
1533 break
1534 ;;
1535 -*)
1536 die "${FUNCNAME}(): Unrecognized option '$1'"
1537 ;;
1538 *)
1539 break
1540 ;;
1541 esac
1542 shift
1543 done
1544
1545 if [[ "$#" -ne 1 ]]; then
1546 die "${FUNCNAME}() requires 1 argument"
1547 fi
1548
1549 intermediate_installation_images_directory="$1"
1550
1551 if [[ ! -d "${intermediate_installation_images_directory}" ]]; then
1552 die "${FUNCNAME}(): Intermediate installation images directory '${intermediate_installation_images_directory}' does not exist"
1553 fi
1554
1555 _python_calculate_PYTHON_ABIS
1556 if [[ "$(PYTHON -f --ABI)" == 3.* ]]; then
1557 b="b"
1558 fi
1559
1560 while read -d $'\0' -r file; do
1561 files+=("${file}")
1562 done < <("$(PYTHON -f)" -c \
1563"import os
1564import sys
1565
1566if hasattr(sys.stdout, 'buffer'):
1567 # Python 3
1568 stdout = sys.stdout.buffer
1569else:
1570 # Python 2
1571 stdout = sys.stdout
1572
1573files_set = set()
1574
1575os.chdir(${b}'${intermediate_installation_images_directory}')
1576
1577for PYTHON_ABI in ${b}'${PYTHON_ABIS}'.split():
1578 for root, dirs, files in os.walk(PYTHON_ABI + ${b}'${EPREFIX}'):
1579 root = root[len(PYTHON_ABI + ${b}'${EPREFIX}')+1:]
1580 files_set.update(root + ${b}'/' + file for file in files)
1581
1582for file in sorted(files_set):
1583 stdout.write(file)
1584 stdout.write(${b}'\x00')" || die "${FUNCNAME}(): Failure of extraction of files in intermediate installation images")
1585
1586 for PYTHON_ABI in ${PYTHON_ABIS}; do
1587 if [[ ! -d "${intermediate_installation_images_directory}/${PYTHON_ABI}" ]]; then
1588 die "${FUNCNAME}(): Intermediate installation image for Python ABI '${PYTHON_ABI}' does not exist"
1589 fi
1590
1591 pushd "${intermediate_installation_images_directory}/${PYTHON_ABI}${EPREFIX}" > /dev/null || die "pushd failed"
1592
1593 for file in "${files[@]}"; do
1594 version_executable="0"
1595 for regex in "/usr/bin/.*" "/usr/sbin/.*" "${PYTHON_VERSIONED_SCRIPTS[@]}"; do
1596 if [[ "/${file}" =~ ^${regex}$ ]]; then
1597 version_executable="1"
1598 break
1599 fi
1600 done
1601 for regex in "${PYTHON_VERSIONED_EXECUTABLES[@]}"; do
1602 if [[ "/${file}" =~ ^${regex}$ ]]; then
1603 version_executable="2"
1604 break
1605 fi
1606 done
1607 if [[ "${version_executable}" != "0" ]]; then
1608 for regex in "${PYTHON_NONVERSIONED_EXECUTABLES[@]}"; do
1609 if [[ "/${file}" =~ ^${regex}$ ]]; then
1610 version_executable="0"
1611 break
1612 fi
1613 done
1614 fi
1615
1616 [[ "${version_executable}" == "0" ]] && continue
1617
1618 if [[ -L "${file}" ]]; then
1619 absolute_file="$(readlink "${file}")"
1620 if [[ "${absolute_file}" == /* ]]; then
1621 absolute_file="${intermediate_installation_images_directory}/${PYTHON_ABI}${EPREFIX}/${absolute_file##/}"
1622 else
1623 if [[ "${file}" == */* ]]; then
1624 absolute_file="${intermediate_installation_images_directory}/${PYTHON_ABI}${EPREFIX}/${file%/*}/${absolute_file}"
1625 else
1626 absolute_file="${intermediate_installation_images_directory}/${PYTHON_ABI}${EPREFIX}/${absolute_file}"
1627 fi
1628 fi
1629 else
1630 absolute_file="${intermediate_installation_images_directory}/${PYTHON_ABI}${EPREFIX}/${file}"
1631 fi
1632
1633 [[ ! -x "${absolute_file}" ]] && continue
1634
1635 shebang="$(head -n1 "${absolute_file}")" || die "Extraction of shebang from '${absolute_file}' failed"
1636
1637 if [[ "${version_executable}" == "2" ]]; then
1638 wrapper_scripts+=("${ED}${file}")
1639 elif [[ "${version_executable}" == "1" ]]; then
1640 if [[ "${shebang}" =~ ${_PYTHON_SHEBANG_BASE_PART_REGEX}([[:digit:]]+(\.[[:digit:]]+)?)?($|[[:space:]]+) ]]; then
1641 wrapper_scripts+=("${ED}${file}")
1642 else
1643 version_executable="0"
1644 fi
1645 fi
1646
1647 [[ "${version_executable}" == "0" ]] && continue
1648
1649 if [[ -e "${file}-${PYTHON_ABI}" ]]; then
1650 die "${FUNCNAME}(): '${EPREFIX}/${file}-${PYTHON_ABI}' already exists"
1651 fi
1652
1653 mv "${file}" "${file}-${PYTHON_ABI}" || die "Renaming of '${file}' failed"
1654
1655 if [[ "${shebang}" =~ ${_PYTHON_SHEBANG_BASE_PART_REGEX}[[:digit:]]*($|[[:space:]]+) ]]; then
1656 if [[ -L "${file}-${PYTHON_ABI}" ]]; then
1657 python_convert_shebangs $([[ "${quiet}" == "1" ]] && echo --quiet) "${PYTHON_ABI}" "${absolute_file}"
1658 else
1659 python_convert_shebangs $([[ "${quiet}" == "1" ]] && echo --quiet) "${PYTHON_ABI}" "${file}-${PYTHON_ABI}"
1660 fi
1661 fi
1662 done
1663
1664 popd > /dev/null || die "popd failed"
1665
1666 # This is per bug #390691, without the duplication refactor, and with
1667 # the 3-way structure per comment #6. This enable users with old
1668 # coreutils to upgrade a lot easier (you need to upgrade python+portage
1669 # before coreutils can be upgraded).
1670 if ROOT="/" has_version '>=sys-apps/coreutils-6.9.90'; then
1671 cp -fr --preserve=all --no-preserve=context "${intermediate_installation_images_directory}/${PYTHON_ABI}/"* "${D}" || die "Merging of intermediate installation image for Python ABI '${PYTHON_ABI} into installation image failed"
1672 elif ROOT="/" has_version sys-apps/coreutils; then
1673 cp -fr --preserve=all "${intermediate_installation_images_directory}/${PYTHON_ABI}/"* "${D}" || die "Merging of intermediate installation image for Python ABI '${PYTHON_ABI} into installation image failed"
1674 else
1675 cp -fpr "${intermediate_installation_images_directory}/${PYTHON_ABI}/"* "${D}" || die "Merging of intermediate installation image for Python ABI '${PYTHON_ABI} into installation image failed"
1676 fi
1677 done
1678
1679 rm -fr "${intermediate_installation_images_directory}"
1680
1681 if [[ "${#wrapper_scripts[@]}" -ge 1 ]]; then
1682 rm -f "${T}/python_wrapper_scripts"
1683
1684 for file in "${wrapper_scripts[@]}"; do
1685 echo -n "${file}" >> "${T}/python_wrapper_scripts"
1686 echo -en "\x00" >> "${T}/python_wrapper_scripts"
1687 done
1688
1689 while read -d $'\0' -r file; do
1690 wrapper_scripts_set+=("${file}")
1691 done < <("$(PYTHON -f)" -c \
1692"import sys
1693
1694if hasattr(sys.stdout, 'buffer'):
1695 # Python 3
1696 stdout = sys.stdout.buffer
1697else:
1698 # Python 2
1699 stdout = sys.stdout
1700
1701python_wrapper_scripts_file = open('${T}/python_wrapper_scripts', 'rb')
1702files = set(python_wrapper_scripts_file.read().rstrip(${b}'\x00').split(${b}'\x00'))
1703python_wrapper_scripts_file.close()
1704
1705for file in sorted(files):
1706 stdout.write(file)
1707 stdout.write(${b}'\x00')" || die "${FUNCNAME}(): Failure of extraction of set of wrapper scripts")
1708
1709 python_generate_wrapper_scripts $([[ "${quiet}" == "1" ]] && echo --quiet) "${wrapper_scripts_set[@]}"
1710 fi
1711}
1712
1713# ================================================================================================
1714# ========= FUNCTIONS FOR PACKAGES NOT SUPPORTING INSTALLATION FOR MULTIPLE PYTHON ABIS ==========
1715# ================================================================================================
1716
1717unset EPYTHON PYTHON_ABI
1718
1719# @FUNCTION: python_set_active_version
1720# @USAGE: <Python_ABI|2|3>
1721# @DESCRIPTION:
1722# Set locally active version of Python.
1723# If Python_ABI argument is specified, then version of Python corresponding to Python_ABI is used.
1724# If 2 argument is specified, then active version of CPython 2 is used.
1725# If 3 argument is specified, then active version of CPython 3 is used.
1726#
1727# This function can be used only in pkg_setup() phase.
1728python_set_active_version() {
1729 if [[ "${EBUILD_PHASE}" != "setup" ]]; then
1730 die "${FUNCNAME}() can be used only in pkg_setup() phase"
1731 fi
1732
1733 if _python_package_supporting_installation_for_multiple_python_abis; then
1734 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
1735 fi
1736
1737 if [[ "$#" -ne 1 ]]; then
1738 die "${FUNCNAME}() requires 1 argument"
1739 fi
1740
1741 _python_initial_sanity_checks
1742
1743 if [[ -z "${PYTHON_ABI}" ]]; then
1744 if [[ -n "$(_python_get_implementation --ignore-invalid "$1")" ]]; then
1745 # PYTHON_ABI variable is intended to be used only in ebuilds/eclasses,
1746 # so it does not need to be exported to subprocesses.
1747 PYTHON_ABI="$1"
1748 if ! _python_implementation && ! has_version "$(python_get_implementational_package)"; then
1749 die "${FUNCNAME}(): '$(python_get_implementational_package)' is not installed"
1750 fi
1751 export EPYTHON="$(PYTHON "$1")"
1752 elif [[ "$1" == "2" ]]; then
1753 if ! _python_implementation && ! has_version "=dev-lang/python-2*"; then
1754 die "${FUNCNAME}(): '=dev-lang/python-2*' is not installed"
1755 fi
1756 export EPYTHON="$(PYTHON -2)"
1757 PYTHON_ABI="${EPYTHON#python}"
1758 PYTHON_ABI="${PYTHON_ABI%%-*}"
1759 elif [[ "$1" == "3" ]]; then
1760 if ! _python_implementation && ! has_version "=dev-lang/python-3*"; then
1761 die "${FUNCNAME}(): '=dev-lang/python-3*' is not installed"
1762 fi
1763 export EPYTHON="$(PYTHON -3)"
1764 PYTHON_ABI="${EPYTHON#python}"
1765 PYTHON_ABI="${PYTHON_ABI%%-*}"
1766 else
1767 die "${FUNCNAME}(): Unrecognized argument '$1'"
1768 fi
1769 fi
1770
1771 _python_final_sanity_checks
1772
1773 # python-updater checks PYTHON_REQUESTED_ACTIVE_VERSION variable.
1774 PYTHON_REQUESTED_ACTIVE_VERSION="$1"
1775}
1776
1777# @FUNCTION: python_need_rebuild
1778# @DESCRIPTION:
1779# Mark current package for rebuilding by python-updater after
1780# switching of active version of Python.
1781python_need_rebuild() {
1782 if _python_package_supporting_installation_for_multiple_python_abis; then
1783 die "${FUNCNAME}() cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
1784 fi
1785
1786 _python_check_python_pkg_setup_execution
1787
1788 if [[ "$#" -ne 0 ]]; then
1789 die "${FUNCNAME}() does not accept arguments"
1790 fi
1791
1792 export PYTHON_NEED_REBUILD="$(PYTHON --ABI)"
1793}
1794
1795# ================================================================================================
1796# ======================================= GETTER FUNCTIONS =======================================
1797# ================================================================================================
1798
1799_PYTHON_ABI_EXTRACTION_COMMAND=\
1800'import platform
1801import sys
1802sys.stdout.write(".".join(str(x) for x in sys.version_info[:2]))
1803if platform.system()[:4] == "Java":
1804 sys.stdout.write("-jython")
1805elif hasattr(platform, "python_implementation") and platform.python_implementation() == "PyPy":
1806 sys.stdout.write("-pypy-" + ".".join(str(x) for x in sys.pypy_version_info[:2]))'
1807
1808_python_get_implementation() {
1809 local ignore_invalid="0"
1810
1811 while (($#)); do
1812 case "$1" in
1813 --ignore-invalid)
1814 ignore_invalid="1"
1815 ;;
1816 --)
1817 shift
1818 break
1819 ;;
1820 -*)
1821 die "${FUNCNAME}(): Unrecognized option '$1'"
1822 ;;
1823 *)
1824 break
1825 ;;
1826 esac
1827 shift
1828 done
1829
1830 if [[ "$#" -ne 1 ]]; then
1831 die "${FUNCNAME}() requires 1 argument"
1832 fi
1833
1834 if [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+$ ]]; then
1835 echo "CPython"
1836 elif [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+-jython$ ]]; then
1837 echo "Jython"
1838 elif [[ "$1" =~ ^[[:digit:]]+\.[[:digit:]]+-pypy-[[:digit:]]+\.[[:digit:]]+$ ]]; then
1839 echo "PyPy"
1840 else
1841 if [[ "${ignore_invalid}" == "0" ]]; then
1842 die "${FUNCNAME}(): Unrecognized Python ABI '$1'"
1843 fi
1844 fi
1845}
1846
1847# @FUNCTION: PYTHON
1848# @USAGE: [-2] [-3] [--ABI] [-a|--absolute-path] [-f|--final-ABI] [--] <Python_ABI="${PYTHON_ABI}">
1849# @DESCRIPTION:
1850# Print filename of Python interpreter for specified Python ABI. If Python_ABI argument
1851# is ommitted, then PYTHON_ABI environment variable must be set and is used.
1852# If -2 option is specified, then active version of CPython 2 is used.
1853# If -3 option is specified, then active version of CPython 3 is used.
1854# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1855# -2, -3 and --final-ABI options and Python_ABI argument cannot be specified simultaneously.
1856# If --ABI option is specified, then only specified Python ABI is printed instead of
1857# filename of Python interpreter.
1858# If --absolute-path option is specified, then absolute path to Python interpreter is printed.
1859# --ABI and --absolute-path options cannot be specified simultaneously.
1860PYTHON() {
1861 _python_check_python_pkg_setup_execution
1862
1863 local ABI_output="0" absolute_path_output="0" final_ABI="0" PYTHON_ABI="${PYTHON_ABI}" python_interpreter python2="0" python3="0"
1864
1865 while (($#)); do
1866 case "$1" in
1867 -2)
1868 python2="1"
1869 ;;
1870 -3)
1871 python3="1"
1872 ;;
1873 --ABI)
1874 ABI_output="1"
1875 ;;
1876 -a|--absolute-path)
1877 absolute_path_output="1"
1878 ;;
1879 -f|--final-ABI)
1880 final_ABI="1"
1881 ;;
1882 --)
1883 shift
1884 break
1885 ;;
1886 -*)
1887 die "${FUNCNAME}(): Unrecognized option '$1'"
1888 ;;
1889 *)
1890 break
1891 ;;
1892 esac
1893 shift
1894 done
1895
1896 if [[ "${ABI_output}" == "1" && "${absolute_path_output}" == "1" ]]; then
1897 die "${FUNCNAME}(): '--ABI' and '--absolute-path' options cannot be specified simultaneously"
1898 fi
1899
1900 if [[ "$((${python2} + ${python3} + ${final_ABI}))" -gt 1 ]]; then
1901 die "${FUNCNAME}(): '-2', '-3' or '--final-ABI' options cannot be specified simultaneously"
1902 fi
1903
1904 if [[ "$#" -eq 0 ]]; then
1905 if [[ "${final_ABI}" == "1" ]]; then
1906 if ! _python_package_supporting_installation_for_multiple_python_abis; then
1907 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
1908 fi
1909 _python_calculate_PYTHON_ABIS
1910 PYTHON_ABI="${PYTHON_ABIS##* }"
1911 elif [[ "${python2}" == "1" ]]; then
1912 PYTHON_ABI="$(ROOT="/" eselect python show --python2 --ABI)"
1913 if [[ -z "${PYTHON_ABI}" ]]; then
1914 die "${FUNCNAME}(): Active version of CPython 2 not set"
1915 elif [[ "${PYTHON_ABI}" != "2."* ]]; then
1916 die "${FUNCNAME}(): Internal error in \`eselect python show --python2\`"
1917 fi
1918 elif [[ "${python3}" == "1" ]]; then
1919 PYTHON_ABI="$(ROOT="/" eselect python show --python3 --ABI)"
1920 if [[ -z "${PYTHON_ABI}" ]]; then
1921 die "${FUNCNAME}(): Active version of CPython 3 not set"
1922 elif [[ "${PYTHON_ABI}" != "3."* ]]; then
1923 die "${FUNCNAME}(): Internal error in \`eselect python show --python3\`"
1924 fi
1925 elif _python_package_supporting_installation_for_multiple_python_abis; then
1926 if ! _python_abi-specific_local_scope; then
1927 die "${FUNCNAME}() should be used in ABI-specific local scope"
1928 fi
1929 else
1930 PYTHON_ABI="$("${EPREFIX}/usr/bin/python" -c "${_PYTHON_ABI_EXTRACTION_COMMAND}")"
1931 if [[ -z "${PYTHON_ABI}" ]]; then
1932 die "${FUNCNAME}(): Failure of extraction of locally active version of Python"
1933 fi
1934 fi
1935 elif [[ "$#" -eq 1 ]]; then
1936 if [[ "${final_ABI}" == "1" ]]; then
1937 die "${FUNCNAME}(): '--final-ABI' option and Python ABI cannot be specified simultaneously"
1938 fi
1939 if [[ "${python2}" == "1" ]]; then
1940 die "${FUNCNAME}(): '-2' option and Python ABI cannot be specified simultaneously"
1941 fi
1942 if [[ "${python3}" == "1" ]]; then
1943 die "${FUNCNAME}(): '-3' option and Python ABI cannot be specified simultaneously"
1944 fi
1945 PYTHON_ABI="$1"
1946 else
1947 die "${FUNCNAME}(): Invalid usage"
1948 fi
1949
1950 if [[ "${ABI_output}" == "1" ]]; then
1951 echo -n "${PYTHON_ABI}"
1952 return
1953 else
1954 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
1955 python_interpreter="python${PYTHON_ABI}"
1956 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
1957 python_interpreter="jython${PYTHON_ABI%-jython}"
1958 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
1959 python_interpreter="pypy-c${PYTHON_ABI#*-pypy-}"
1960 fi
1961
1962 if [[ "${absolute_path_output}" == "1" ]]; then
1963 echo -n "${EPREFIX}/usr/bin/${python_interpreter}"
1964 else
1965 echo -n "${python_interpreter}"
1966 fi
1967 fi
1968
1969 if [[ -n "${ABI}" && "${ABI}" != "${DEFAULT_ABI}" && "${DEFAULT_ABI}" != "default" ]]; then
1970 echo -n "-${ABI}"
1971 fi
1972}
1973
1974# @FUNCTION: python_get_implementation
1975# @USAGE: [-f|--final-ABI]
1976# @DESCRIPTION:
1977# Print name of Python implementation.
1978# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
1979python_get_implementation() {
1980 _python_check_python_pkg_setup_execution
1981
1982 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
1983
1984 while (($#)); do
1985 case "$1" in
1986 -f|--final-ABI)
1987 final_ABI="1"
1988 ;;
1989 -*)
1990 die "${FUNCNAME}(): Unrecognized option '$1'"
1991 ;;
1992 *)
1993 die "${FUNCNAME}(): Invalid usage"
1994 ;;
1995 esac
1996 shift
1997 done
1998
1999 if [[ "${final_ABI}" == "1" ]]; then
2000 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2001 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2002 fi
2003 PYTHON_ABI="$(PYTHON -f --ABI)"
2004 else
2005 if _python_package_supporting_installation_for_multiple_python_abis; then
2006 if ! _python_abi-specific_local_scope; then
2007 die "${FUNCNAME}() should be used in ABI-specific local scope"
2008 fi
2009 else
2010 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2011 fi
2012 fi
2013
2014 echo "$(_python_get_implementation "${PYTHON_ABI}")"
2015}
2016
2017# @FUNCTION: python_get_implementational_package
2018# @USAGE: [-f|--final-ABI]
2019# @DESCRIPTION:
2020# Print category, name and slot of package providing Python implementation.
2021# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2022python_get_implementational_package() {
2023 _python_check_python_pkg_setup_execution
2024
2025 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
2026
2027 while (($#)); do
2028 case "$1" in
2029 -f|--final-ABI)
2030 final_ABI="1"
2031 ;;
2032 -*)
2033 die "${FUNCNAME}(): Unrecognized option '$1'"
2034 ;;
2035 *)
2036 die "${FUNCNAME}(): Invalid usage"
2037 ;;
2038 esac
2039 shift
2040 done
2041
2042 if [[ "${final_ABI}" == "1" ]]; then
2043 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2044 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2045 fi
2046 PYTHON_ABI="$(PYTHON -f --ABI)"
2047 else
2048 if _python_package_supporting_installation_for_multiple_python_abis; then
2049 if ! _python_abi-specific_local_scope; then
2050 die "${FUNCNAME}() should be used in ABI-specific local scope"
2051 fi
2052 else
2053 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2054 fi
2055 fi
2056
2057 if [[ "${EAPI:-0}" == "0" ]]; then
2058 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2059 echo "=dev-lang/python-${PYTHON_ABI}*"
2060 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2061 echo "=dev-java/jython-${PYTHON_ABI%-jython}*"
2062 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2063 echo "=virtual/pypy-${PYTHON_ABI#*-pypy-}*"
2064 fi
2065 else
2066 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2067 echo "dev-lang/python:${PYTHON_ABI}"
2068 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2069 echo "dev-java/jython:${PYTHON_ABI%-jython}"
2070 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2071 echo "virtual/pypy:${PYTHON_ABI#*-pypy-}"
2072 fi
2073 fi
2074}
2075
2076# @FUNCTION: python_get_includedir
2077# @USAGE: [-b|--base-path] [-f|--final-ABI]
2078# @DESCRIPTION:
2079# Print path to Python include directory.
2080# If --base-path option is specified, then path not prefixed with "/" is printed.
2081# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2082python_get_includedir() {
2083 _python_check_python_pkg_setup_execution
2084
2085 local base_path="0" final_ABI="0" prefix PYTHON_ABI="${PYTHON_ABI}"
2086
2087 while (($#)); do
2088 case "$1" in
2089 -b|--base-path)
2090 base_path="1"
2091 ;;
2092 -f|--final-ABI)
2093 final_ABI="1"
2094 ;;
2095 -*)
2096 die "${FUNCNAME}(): Unrecognized option '$1'"
2097 ;;
2098 *)
2099 die "${FUNCNAME}(): Invalid usage"
2100 ;;
2101 esac
2102 shift
2103 done
2104
2105 if [[ "${base_path}" == "0" ]]; then
2106 prefix="/"
2107 fi
2108
2109 if [[ "${final_ABI}" == "1" ]]; then
2110 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2111 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2112 fi
2113 PYTHON_ABI="$(PYTHON -f --ABI)"
2114 else
2115 if _python_package_supporting_installation_for_multiple_python_abis; then
2116 if ! _python_abi-specific_local_scope; then
2117 die "${FUNCNAME}() should be used in ABI-specific local scope"
2118 fi
2119 else
2120 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2121 fi
2122 fi
2123
2124 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2125 echo "${prefix}usr/include/python${PYTHON_ABI}"
2126 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2127 echo "${prefix}usr/share/jython-${PYTHON_ABI%-jython}/Include"
2128 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2129 echo "${prefix}usr/$(get_libdir)/pypy${PYTHON_ABI#*-pypy-}/include"
2130 fi
2131}
2132
2133# @FUNCTION: python_get_libdir
2134# @USAGE: [-b|--base-path] [-f|--final-ABI]
2135# @DESCRIPTION:
2136# Print path to Python standard library directory.
2137# If --base-path option is specified, then path not prefixed with "/" is printed.
2138# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2139python_get_libdir() {
2140 _python_check_python_pkg_setup_execution
2141
2142 local base_path="0" final_ABI="0" prefix PYTHON_ABI="${PYTHON_ABI}"
2143
2144 while (($#)); do
2145 case "$1" in
2146 -b|--base-path)
2147 base_path="1"
2148 ;;
2149 -f|--final-ABI)
2150 final_ABI="1"
2151 ;;
2152 -*)
2153 die "${FUNCNAME}(): Unrecognized option '$1'"
2154 ;;
2155 *)
2156 die "${FUNCNAME}(): Invalid usage"
2157 ;;
2158 esac
2159 shift
2160 done
2161
2162 if [[ "${base_path}" == "0" ]]; then
2163 prefix="/"
2164 fi
2165
2166 if [[ "${final_ABI}" == "1" ]]; then
2167 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2168 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2169 fi
2170 PYTHON_ABI="$(PYTHON -f --ABI)"
2171 else
2172 if _python_package_supporting_installation_for_multiple_python_abis; then
2173 if ! _python_abi-specific_local_scope; then
2174 die "${FUNCNAME}() should be used in ABI-specific local scope"
2175 fi
2176 else
2177 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2178 fi
2179 fi
2180
2181 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2182 echo "${prefix}usr/$(get_libdir)/python${PYTHON_ABI}"
2183 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2184 echo "${prefix}usr/share/jython-${PYTHON_ABI%-jython}/Lib"
2185 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2186 die "${FUNCNAME}(): PyPy has multiple standard library directories"
2187 fi
2188}
2189
2190# @FUNCTION: python_get_sitedir
2191# @USAGE: [-b|--base-path] [-f|--final-ABI]
2192# @DESCRIPTION:
2193# Print path to Python site-packages directory.
2194# If --base-path option is specified, then path not prefixed with "/" is printed.
2195# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2196python_get_sitedir() {
2197 _python_check_python_pkg_setup_execution
2198
2199 local base_path="0" final_ABI="0" prefix PYTHON_ABI="${PYTHON_ABI}"
2200
2201 while (($#)); do
2202 case "$1" in
2203 -b|--base-path)
2204 base_path="1"
2205 ;;
2206 -f|--final-ABI)
2207 final_ABI="1"
2208 ;;
2209 -*)
2210 die "${FUNCNAME}(): Unrecognized option '$1'"
2211 ;;
2212 *)
2213 die "${FUNCNAME}(): Invalid usage"
2214 ;;
2215 esac
2216 shift
2217 done
2218
2219 if [[ "${base_path}" == "0" ]]; then
2220 prefix="/"
2221 fi
2222
2223 if [[ "${final_ABI}" == "1" ]]; then
2224 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2225 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2226 fi
2227 PYTHON_ABI="$(PYTHON -f --ABI)"
2228 else
2229 if _python_package_supporting_installation_for_multiple_python_abis; then
2230 if ! _python_abi-specific_local_scope; then
2231 die "${FUNCNAME}() should be used in ABI-specific local scope"
2232 fi
2233 else
2234 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2235 fi
2236 fi
2237
2238 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2239 echo "${prefix}usr/$(get_libdir)/python${PYTHON_ABI}/site-packages"
2240 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2241 echo "${prefix}usr/share/jython-${PYTHON_ABI%-jython}/Lib/site-packages"
2242 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2243 echo "${prefix}usr/$(get_libdir)/pypy${PYTHON_ABI#*-pypy-}/site-packages"
2244 fi
2245}
2246
2247# @FUNCTION: python_get_library
2248# @USAGE: [-b|--base-path] [-f|--final-ABI] [-l|--linker-option]
2249# @DESCRIPTION:
2250# Print path to Python library.
2251# If --base-path option is specified, then path not prefixed with "/" is printed.
2252# If --linker-option is specified, then "-l${library}" linker option is printed.
2253# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2254python_get_library() {
2255 _python_check_python_pkg_setup_execution
2256
2257 local base_path="0" final_ABI="0" linker_option="0" prefix PYTHON_ABI="${PYTHON_ABI}"
2258
2259 while (($#)); do
2260 case "$1" in
2261 -b|--base-path)
2262 base_path="1"
2263 ;;
2264 -f|--final-ABI)
2265 final_ABI="1"
2266 ;;
2267 -l|--linker-option)
2268 linker_option="1"
2269 ;;
2270 -*)
2271 die "${FUNCNAME}(): Unrecognized option '$1'"
2272 ;;
2273 *)
2274 die "${FUNCNAME}(): Invalid usage"
2275 ;;
2276 esac
2277 shift
2278 done
2279
2280 if [[ "${base_path}" == "0" ]]; then
2281 prefix="/"
2282 fi
2283
2284 if [[ "${base_path}" == "1" && "${linker_option}" == "1" ]]; then
2285 die "${FUNCNAME}(): '--base-path' and '--linker-option' options cannot be specified simultaneously"
2286 fi
2287
2288 if [[ "${final_ABI}" == "1" ]]; then
2289 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2290 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2291 fi
2292 PYTHON_ABI="$(PYTHON -f --ABI)"
2293 else
2294 if _python_package_supporting_installation_for_multiple_python_abis; then
2295 if ! _python_abi-specific_local_scope; then
2296 die "${FUNCNAME}() should be used in ABI-specific local scope"
2297 fi
2298 else
2299 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2300 fi
2301 fi
2302
2303 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2304 if [[ "${linker_option}" == "1" ]]; then
2305 echo "-lpython${PYTHON_ABI}"
2306 else
2307 echo "${prefix}usr/$(get_libdir)/libpython${PYTHON_ABI}$(get_libname)"
2308 fi
2309 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2310 die "${FUNCNAME}(): Jython does not have shared library"
2311 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2312 die "${FUNCNAME}(): PyPy does not have shared library"
2313 fi
2314}
2315
2316# @FUNCTION: python_get_version
2317# @USAGE: [-f|--final-ABI] [-l|--language] [--full] [--major] [--minor] [--micro]
2318# @DESCRIPTION:
2319# Print version of Python implementation.
2320# --full, --major, --minor and --micro options cannot be specified simultaneously.
2321# If --full, --major, --minor and --micro options are not specified, then "${major_version}.${minor_version}" is printed.
2322# If --language option is specified, then version of Python language is printed.
2323# --language and --full options cannot be specified simultaneously.
2324# --language and --micro options cannot be specified simultaneously.
2325# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2326python_get_version() {
2327 _python_check_python_pkg_setup_execution
2328
2329 local final_ABI="0" language="0" language_version full="0" major="0" minor="0" micro="0" PYTHON_ABI="${PYTHON_ABI}" python_command
2330
2331 while (($#)); do
2332 case "$1" in
2333 -f|--final-ABI)
2334 final_ABI="1"
2335 ;;
2336 -l|--language)
2337 language="1"
2338 ;;
2339 --full)
2340 full="1"
2341 ;;
2342 --major)
2343 major="1"
2344 ;;
2345 --minor)
2346 minor="1"
2347 ;;
2348 --micro)
2349 micro="1"
2350 ;;
2351 -*)
2352 die "${FUNCNAME}(): Unrecognized option '$1'"
2353 ;;
2354 *)
2355 die "${FUNCNAME}(): Invalid usage"
2356 ;;
2357 esac
2358 shift
2359 done
2360
2361 if [[ "${final_ABI}" == "1" ]]; then
2362 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2363 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2364 fi
2365 else
2366 if _python_package_supporting_installation_for_multiple_python_abis && ! _python_abi-specific_local_scope; then
2367 die "${FUNCNAME}() should be used in ABI-specific local scope"
2368 fi
2369 fi
2370
2371 if [[ "$((${full} + ${major} + ${minor} + ${micro}))" -gt 1 ]]; then
2372 die "${FUNCNAME}(): '--full', '--major', '--minor' or '--micro' options cannot be specified simultaneously"
2373 fi
2374
2375 if [[ "${language}" == "1" ]]; then
2376 if [[ "${final_ABI}" == "1" ]]; then
2377 PYTHON_ABI="$(PYTHON -f --ABI)"
2378 elif [[ -z "${PYTHON_ABI}" ]]; then
2379 PYTHON_ABI="$(PYTHON --ABI)"
2380 fi
2381 language_version="${PYTHON_ABI%%-*}"
2382 if [[ "${full}" == "1" ]]; then
2383 die "${FUNCNAME}(): '--language' and '--full' options cannot be specified simultaneously"
2384 elif [[ "${major}" == "1" ]]; then
2385 echo "${language_version%.*}"
2386 elif [[ "${minor}" == "1" ]]; then
2387 echo "${language_version#*.}"
2388 elif [[ "${micro}" == "1" ]]; then
2389 die "${FUNCNAME}(): '--language' and '--micro' options cannot be specified simultaneously"
2390 else
2391 echo "${language_version}"
2392 fi
2393 else
2394 if [[ "${full}" == "1" ]]; then
2395 python_command="import sys; print('.'.join(str(x) for x in getattr(sys, 'pypy_version_info', sys.version_info)[:3]))"
2396 elif [[ "${major}" == "1" ]]; then
2397 python_command="import sys; print(getattr(sys, 'pypy_version_info', sys.version_info)[0])"
2398 elif [[ "${minor}" == "1" ]]; then
2399 python_command="import sys; print(getattr(sys, 'pypy_version_info', sys.version_info)[1])"
2400 elif [[ "${micro}" == "1" ]]; then
2401 python_command="import sys; print(getattr(sys, 'pypy_version_info', sys.version_info)[2])"
2402 else
2403 if [[ -n "${PYTHON_ABI}" && "${final_ABI}" == "0" ]]; then
2404 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "CPython" ]]; then
2405 echo "${PYTHON_ABI}"
2406 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "Jython" ]]; then
2407 echo "${PYTHON_ABI%-jython}"
2408 elif [[ "$(_python_get_implementation "${PYTHON_ABI}")" == "PyPy" ]]; then
2409 echo "${PYTHON_ABI#*-pypy-}"
2410 fi
2411 return
2412 fi
2413 python_command="from sys import version_info; print('.'.join(str(x) for x in version_info[:2]))"
2414 fi
2415
2416 if [[ "${final_ABI}" == "1" ]]; then
2417 "$(PYTHON -f)" -c "${python_command}"
2418 else
2419 "$(PYTHON ${PYTHON_ABI})" -c "${python_command}"
2420 fi
2421 fi
2422}
2423
2424# @FUNCTION: python_get_implementation_and_version
2425# @USAGE: [-f|--final-ABI]
2426# @DESCRIPTION:
2427# Print name and version of Python implementation.
2428# If version of Python implementation is not bound to version of Python language, then
2429# version of Python language is additionally printed.
2430# If --final-ABI option is specified, then final ABI from the list of enabled ABIs is used.
2431python_get_implementation_and_version() {
2432 _python_check_python_pkg_setup_execution
2433
2434 local final_ABI="0" PYTHON_ABI="${PYTHON_ABI}"
2435
2436 while (($#)); do
2437 case "$1" in
2438 -f|--final-ABI)
2439 final_ABI="1"
2440 ;;
2441 -*)
2442 die "${FUNCNAME}(): Unrecognized option '$1'"
2443 ;;
2444 *)
2445 die "${FUNCNAME}(): Invalid usage"
2446 ;;
2447 esac
2448 shift
2449 done
2450
2451 if [[ "${final_ABI}" == "1" ]]; then
2452 if ! _python_package_supporting_installation_for_multiple_python_abis; then
2453 die "${FUNCNAME}(): '--final-ABI' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2454 fi
2455 PYTHON_ABI="$(PYTHON -f --ABI)"
2456 else
2457 if _python_package_supporting_installation_for_multiple_python_abis; then
2458 if ! _python_abi-specific_local_scope; then
2459 die "${FUNCNAME}() should be used in ABI-specific local scope"
2460 fi
2461 else
2462 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
2463 fi
2464 fi
2465
2466 if [[ "${PYTHON_ABI}" =~ ^[[:digit:]]+\.[[:digit:]]+-[[:alnum:]]+-[[:digit:]]+\.[[:digit:]]+$ ]]; then
2467 echo "$(_python_get_implementation "${PYTHON_ABI}") ${PYTHON_ABI##*-} (Python ${PYTHON_ABI%%-*})"
2468 else
2469 echo "$(_python_get_implementation "${PYTHON_ABI}") ${PYTHON_ABI%%-*}"
2470 fi
1480} 2471}
1481 2472
1482# ================================================================================================ 2473# ================================================================================================
1483# ================================ FUNCTIONS FOR RUNNING OF TESTS ================================ 2474# ================================ FUNCTIONS FOR RUNNING OF TESTS ================================
1484# ================================================================================================ 2475# ================================================================================================
1487# @DESCRIPTION: 2478# @DESCRIPTION:
1488# User-configurable verbosity of tests of Python modules. 2479# User-configurable verbosity of tests of Python modules.
1489# Supported values: 0, 1, 2, 3, 4. 2480# Supported values: 0, 1, 2, 3, 4.
1490PYTHON_TEST_VERBOSITY="${PYTHON_TEST_VERBOSITY:-1}" 2481PYTHON_TEST_VERBOSITY="${PYTHON_TEST_VERBOSITY:-1}"
1491 2482
2483_python_test_hook() {
2484 if [[ "$#" -ne 1 ]]; then
2485 die "${FUNCNAME}() requires 1 argument"
2486 fi
2487
2488 if _python_package_supporting_installation_for_multiple_python_abis && [[ "$(type -t "${_PYTHON_TEST_FUNCTION}_$1_hook")" == "function" ]]; then
2489 "${_PYTHON_TEST_FUNCTION}_$1_hook"
2490 fi
2491}
2492
1492# @FUNCTION: python_execute_nosetests 2493# @FUNCTION: python_execute_nosetests
1493# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments] 2494# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
1494# @DESCRIPTION: 2495# @DESCRIPTION:
1495# Execute nosetests for all enabled versions of Python. 2496# Execute nosetests for all enabled Python ABIs.
2497# In ebuilds of packages supporting installation for multiple Python ABIs, this function calls
2498# python_execute_nosetests_pre_hook() and python_execute_nosetests_post_hook(), if they are defined.
1496python_execute_nosetests() { 2499python_execute_nosetests() {
2500 _python_check_python_pkg_setup_execution
1497 _python_set_color_variables 2501 _python_set_color_variables
1498 2502
1499 local PYTHONPATH_template= separate_build_dirs= 2503 local PYTHONPATH_template separate_build_dirs
1500 2504
1501 while (($#)); do 2505 while (($#)); do
1502 case "$1" in 2506 case "$1" in
1503 -P|--PYTHONPATH) 2507 -P|--PYTHONPATH)
1504 PYTHONPATH_template="$2" 2508 PYTHONPATH_template="$2"
1520 esac 2524 esac
1521 shift 2525 shift
1522 done 2526 done
1523 2527
1524 python_test_function() { 2528 python_test_function() {
1525 local evaluated_PYTHONPATH= 2529 local evaluated_PYTHONPATH
1526 2530
1527 if [[ -n "${PYTHONPATH_template}" ]]; then
1528 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")" 2531 eval "evaluated_PYTHONPATH=\"${PYTHONPATH_template}\""
1529 if [[ ! -e "${evaluated_PYTHONPATH}" ]]; then 2532
1530 unset evaluated_PYTHONPATH 2533 _PYTHON_TEST_FUNCTION="python_execute_nosetests" _python_test_hook pre
1531 fi
1532 fi
1533 2534
1534 if [[ -n "${evaluated_PYTHONPATH}" ]]; then 2535 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
1535 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL} 2536 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL}
1536 PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" 2537 PYTHONPATH="${evaluated_PYTHONPATH}" nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" || return "$?"
1537 else 2538 else
1538 echo ${_BOLD}nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL} 2539 echo ${_BOLD}nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@"${_NORMAL}
1539 nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" 2540 nosetests --verbosity="${PYTHON_TEST_VERBOSITY}" "$@" || return "$?"
1540 fi 2541 fi
2542
2543 _PYTHON_TEST_FUNCTION="python_execute_nosetests" _python_test_hook post
1541 } 2544 }
1542 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then 2545 if _python_package_supporting_installation_for_multiple_python_abis; then
1543 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@" 2546 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
1544 else 2547 else
1545 if [[ -n "${separate_build_dirs}" ]]; then 2548 if [[ -n "${separate_build_dirs}" ]]; then
1546 die "${FUNCNAME}(): Invalid usage" 2549 die "${FUNCNAME}(): Invalid usage"
1547 fi 2550 fi
1552} 2555}
1553 2556
1554# @FUNCTION: python_execute_py.test 2557# @FUNCTION: python_execute_py.test
1555# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments] 2558# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
1556# @DESCRIPTION: 2559# @DESCRIPTION:
1557# Execute py.test for all enabled versions of Python. 2560# Execute py.test for all enabled Python ABIs.
2561# In ebuilds of packages supporting installation for multiple Python ABIs, this function calls
2562# python_execute_py.test_pre_hook() and python_execute_py.test_post_hook(), if they are defined.
1558python_execute_py.test() { 2563python_execute_py.test() {
2564 _python_check_python_pkg_setup_execution
1559 _python_set_color_variables 2565 _python_set_color_variables
1560 2566
1561 local PYTHONPATH_template= separate_build_dirs= 2567 local PYTHONPATH_template separate_build_dirs
1562 2568
1563 while (($#)); do 2569 while (($#)); do
1564 case "$1" in 2570 case "$1" in
1565 -P|--PYTHONPATH) 2571 -P|--PYTHONPATH)
1566 PYTHONPATH_template="$2" 2572 PYTHONPATH_template="$2"
1582 esac 2588 esac
1583 shift 2589 shift
1584 done 2590 done
1585 2591
1586 python_test_function() { 2592 python_test_function() {
1587 local evaluated_PYTHONPATH= 2593 local evaluated_PYTHONPATH
1588 2594
1589 if [[ -n "${PYTHONPATH_template}" ]]; then
1590 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")" 2595 eval "evaluated_PYTHONPATH=\"${PYTHONPATH_template}\""
1591 if [[ ! -e "${evaluated_PYTHONPATH}" ]]; then 2596
1592 unset evaluated_PYTHONPATH 2597 _PYTHON_TEST_FUNCTION="python_execute_py.test" _python_test_hook pre
1593 fi
1594 fi
1595 2598
1596 if [[ -n "${evaluated_PYTHONPATH}" ]]; then 2599 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
1597 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@"${_NORMAL} 2600 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@"${_NORMAL}
1598 PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@" 2601 PYTHONPATH="${evaluated_PYTHONPATH}" py.test $([[ "${PYTHON_TEST_VERBOSITY}" -ge 2 ]] && echo -v) "$@" || return "$?"
1599 else 2602 else
1600 echo ${_BOLD}py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@"${_NORMAL} 2603 echo ${_BOLD}py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@"${_NORMAL}
1601 py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@" 2604 py.test $([[ "${PYTHON_TEST_VERBOSITY}" -gt 1 ]] && echo -v) "$@" || return "$?"
1602 fi 2605 fi
2606
2607 _PYTHON_TEST_FUNCTION="python_execute_py.test" _python_test_hook post
1603 } 2608 }
1604 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then 2609 if _python_package_supporting_installation_for_multiple_python_abis; then
1605 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@" 2610 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
1606 else 2611 else
1607 if [[ -n "${separate_build_dirs}" ]]; then 2612 if [[ -n "${separate_build_dirs}" ]]; then
1608 die "${FUNCNAME}(): Invalid usage" 2613 die "${FUNCNAME}(): Invalid usage"
1609 fi 2614 fi
1614} 2619}
1615 2620
1616# @FUNCTION: python_execute_trial 2621# @FUNCTION: python_execute_trial
1617# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments] 2622# @USAGE: [-P|--PYTHONPATH PYTHONPATH] [-s|--separate-build-dirs] [--] [arguments]
1618# @DESCRIPTION: 2623# @DESCRIPTION:
1619# Execute trial for all enabled versions of Python. 2624# Execute trial for all enabled Python ABIs.
2625# In ebuilds of packages supporting installation for multiple Python ABIs, this function
2626# calls python_execute_trial_pre_hook() and python_execute_trial_post_hook(), if they are defined.
1620python_execute_trial() { 2627python_execute_trial() {
2628 _python_check_python_pkg_setup_execution
1621 _python_set_color_variables 2629 _python_set_color_variables
1622 2630
1623 local PYTHONPATH_template= separate_build_dirs= 2631 local PYTHONPATH_template separate_build_dirs
1624 2632
1625 while (($#)); do 2633 while (($#)); do
1626 case "$1" in 2634 case "$1" in
1627 -P|--PYTHONPATH) 2635 -P|--PYTHONPATH)
1628 PYTHONPATH_template="$2" 2636 PYTHONPATH_template="$2"
1644 esac 2652 esac
1645 shift 2653 shift
1646 done 2654 done
1647 2655
1648 python_test_function() { 2656 python_test_function() {
1649 local evaluated_PYTHONPATH= 2657 local evaluated_PYTHONPATH
1650 2658
1651 if [[ -n "${PYTHONPATH_template}" ]]; then
1652 evaluated_PYTHONPATH="$(eval echo -n "${PYTHONPATH_template}")" 2659 eval "evaluated_PYTHONPATH=\"${PYTHONPATH_template}\""
1653 if [[ ! -e "${evaluated_PYTHONPATH}" ]]; then 2660
1654 unset evaluated_PYTHONPATH 2661 _PYTHON_TEST_FUNCTION="python_execute_trial" _python_test_hook pre
1655 fi
1656 fi
1657 2662
1658 if [[ -n "${evaluated_PYTHONPATH}" ]]; then 2663 if [[ -n "${evaluated_PYTHONPATH}" ]]; then
1659 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL} 2664 echo ${_BOLD}PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL}
1660 PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" 2665 PYTHONPATH="${evaluated_PYTHONPATH}" trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" || return "$?"
1661 else 2666 else
1662 echo ${_BOLD}trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL} 2667 echo ${_BOLD}trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@"${_NORMAL}
1663 trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" 2668 trial $([[ "${PYTHON_TEST_VERBOSITY}" -ge 4 ]] && echo --spew) "$@" || return "$?"
1664 fi 2669 fi
2670
2671 _PYTHON_TEST_FUNCTION="python_execute_trial" _python_test_hook post
1665 } 2672 }
1666 if [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then 2673 if _python_package_supporting_installation_for_multiple_python_abis; then
1667 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@" 2674 python_execute_function ${separate_build_dirs:+-s} python_test_function "$@"
1668 else 2675 else
1669 if [[ -n "${separate_build_dirs}" ]]; then 2676 if [[ -n "${separate_build_dirs}" ]]; then
1670 die "${FUNCNAME}(): Invalid usage" 2677 die "${FUNCNAME}(): Invalid usage"
1671 fi 2678 fi
1682# @FUNCTION: python_enable_pyc 2689# @FUNCTION: python_enable_pyc
1683# @DESCRIPTION: 2690# @DESCRIPTION:
1684# Tell Python to automatically recompile modules to .pyc/.pyo if the 2691# Tell Python to automatically recompile modules to .pyc/.pyo if the
1685# timestamps/version stamps have changed. 2692# timestamps/version stamps have changed.
1686python_enable_pyc() { 2693python_enable_pyc() {
2694 _python_check_python_pkg_setup_execution
2695
2696 if [[ "$#" -ne 0 ]]; then
2697 die "${FUNCNAME}() does not accept arguments"
2698 fi
2699
1687 unset PYTHONDONTWRITEBYTECODE 2700 unset PYTHONDONTWRITEBYTECODE
1688} 2701}
1689 2702
1690# @FUNCTION: python_disable_pyc 2703# @FUNCTION: python_disable_pyc
1691# @DESCRIPTION: 2704# @DESCRIPTION:
1692# Tell Python not to automatically recompile modules to .pyc/.pyo 2705# Tell Python not to automatically recompile modules to .pyc/.pyo
1693# even if the timestamps/version stamps do not match. This is done 2706# even if the timestamps/version stamps do not match. This is done
1694# to protect sandbox. 2707# to protect sandbox.
1695python_disable_pyc() { 2708python_disable_pyc() {
2709 _python_check_python_pkg_setup_execution
2710
2711 if [[ "$#" -ne 0 ]]; then
2712 die "${FUNCNAME}() does not accept arguments"
2713 fi
2714
1696 export PYTHONDONTWRITEBYTECODE="1" 2715 export PYTHONDONTWRITEBYTECODE="1"
1697} 2716}
1698 2717
2718_python_vecho() {
2719 [[ -z ${PORTAGE_VERBOSE} ]] || echo "$@"
2720}
2721
2722_python_clean_compiled_modules() {
2723 _python_initialize_prefix_variables
2724 _python_set_color_variables
2725
2726 [[ "${FUNCNAME[1]}" =~ ^(python_mod_optimize|python_mod_cleanup)$ ]] || die "${FUNCNAME}(): Invalid usage"
2727
2728 local base_module_name compiled_file compiled_files=() dir path py_file root
2729
2730 # Strip trailing slash from EROOT.
2731 root="${EROOT%/}"
2732
2733 for path in "$@"; do
2734 compiled_files=()
2735 if [[ -d "${path}" ]]; then
2736 while read -d $'\0' -r compiled_file; do
2737 compiled_files+=("${compiled_file}")
2738 done < <(find "${path}" "(" -name "*.py[co]" -o -name "*\$py.class" ")" -print0)
2739
2740 if [[ "${EBUILD_PHASE}" == "postrm" ]]; then
2741 # Delete empty child directories.
2742 find "${path}" -type d | sort -r | while read -r dir; do
2743 if rmdir "${dir}" 2> /dev/null; then
2744 _python_vecho "<<< ${dir}"
2745 fi
2746 done
2747 fi
2748 elif [[ "${path}" == *.py ]]; then
2749 base_module_name="${path##*/}"
2750 base_module_name="${base_module_name%.py}"
2751 if [[ -d "${path%/*}/__pycache__" ]]; then
2752 while read -d $'\0' -r compiled_file; do
2753 compiled_files+=("${compiled_file}")
2754 done < <(find "${path%/*}/__pycache__" "(" -name "${base_module_name}.*.py[co]" -o -name "${base_module_name}\$py.class" ")" -print0)
2755 fi
2756 compiled_files+=("${path}c" "${path}o" "${path%.py}\$py.class")
2757 fi
2758
2759 for compiled_file in "${compiled_files[@]}"; do
2760 [[ ! -f "${compiled_file}" ]] && continue
2761 dir="${compiled_file%/*}"
2762 dir="${dir##*/}"
2763 if [[ "${compiled_file}" == *.py[co] ]]; then
2764 if [[ "${dir}" == "__pycache__" ]]; then
2765 base_module_name="${compiled_file##*/}"
2766 base_module_name="${base_module_name%.*py[co]}"
2767 base_module_name="${base_module_name%.*}"
2768 py_file="${compiled_file%__pycache__/*}${base_module_name}.py"
2769 else
2770 py_file="${compiled_file%[co]}"
2771 fi
2772 if [[ "${EBUILD_PHASE}" == "postinst" ]]; then
2773 [[ -f "${py_file}" && "${compiled_file}" -nt "${py_file}" ]] && continue
2774 else
2775 [[ -f "${py_file}" ]] && continue
2776 fi
2777 _python_vecho "<<< ${compiled_file%[co]}[co]"
2778 rm -f "${compiled_file%[co]}"[co]
2779 elif [[ "${compiled_file}" == *\$py.class ]]; then
2780 if [[ "${dir}" == "__pycache__" ]]; then
2781 base_module_name="${compiled_file##*/}"
2782 base_module_name="${base_module_name%\$py.class}"
2783 py_file="${compiled_file%__pycache__/*}${base_module_name}.py"
2784 else
2785 py_file="${compiled_file%\$py.class}.py"
2786 fi
2787 if [[ "${EBUILD_PHASE}" == "postinst" ]]; then
2788 [[ -f "${py_file}" && "${compiled_file}" -nt "${py_file}" ]] && continue
2789 else
2790 [[ -f "${py_file}" ]] && continue
2791 fi
2792 _python_vecho "<<< ${compiled_file}"
2793 rm -f "${compiled_file}"
2794 else
2795 die "${FUNCNAME}(): Unrecognized file type: '${compiled_file}'"
2796 fi
2797
2798 # Delete empty parent directories.
2799 dir="${compiled_file%/*}"
2800 while [[ "${dir}" != "${root}" ]]; do
2801 if rmdir "${dir}" 2> /dev/null; then
2802 _python_vecho "<<< ${dir}"
2803 else
2804 break
2805 fi
2806 dir="${dir%/*}"
2807 done
2808 done
2809 done
2810}
2811
1699# @FUNCTION: python_mod_optimize 2812# @FUNCTION: python_mod_optimize
1700# @USAGE: [options] [directory|file] 2813# @USAGE: [--allow-evaluated-non-sitedir-paths] [-d directory] [-f] [-l] [-q] [-x regular_expression] [--] <file|directory> [files|directories]
1701# @DESCRIPTION: 2814# @DESCRIPTION:
1702# If no arguments supplied, it will recompile not recursively all modules 2815# Byte-compile specified Python modules.
1703# under sys.path (eg. /usr/lib/python2.6, /usr/lib/python2.6/site-packages). 2816# -d, -f, -l, -q and -x options passed to this function are passed to compileall.py.
1704# 2817#
1705# If supplied with arguments, it will recompile all modules recursively
1706# in the supplied directory.
1707# This function should only be run in pkg_postinst(). 2818# This function can be used only in pkg_postinst() phase.
1708#
1709# Options passed to this function are passed to compileall.py.
1710#
1711# Example:
1712# python_mod_optimize ctypesgencore
1713python_mod_optimize() { 2819python_mod_optimize() {
2820 if [[ "${EBUILD_PHASE}" != "postinst" ]]; then
2821 die "${FUNCNAME}() can be used only in pkg_postinst() phase"
2822 fi
2823
2824 _python_check_python_pkg_setup_execution
1714 _python_initialize_prefix_variables 2825 _python_initialize_prefix_variables
1715 2826
1716 # Check if phase is pkg_postinst(). 2827 if ! has "${EAPI:-0}" 0 1 2 || _python_package_supporting_installation_for_multiple_python_abis || _python_implementation || [[ "${CATEGORY}/${PN}" == "sys-apps/portage" ]]; then
1717 [[ ${EBUILD_PHASE} != "postinst" ]] && die "${FUNCNAME}() should only be run in pkg_postinst()" 2828 # PYTHON_ABI variable cannot be local in packages not supporting installation for multiple Python ABIs.
2829 local allow_evaluated_non_sitedir_paths="0" dir dirs=() evaluated_dirs=() evaluated_files=() file files=() iterated_PYTHON_ABIS options=() other_dirs=() other_files=() previous_PYTHON_ABI="${PYTHON_ABI}" return_code root site_packages_dirs=() site_packages_files=() stderr stderr_line
1718 2830
2831 if _python_package_supporting_installation_for_multiple_python_abis; then
1719 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then 2832 if has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_ABIS}" ]]; then
1720 local dir file options=() other_dirs=() other_files=() previous_PYTHON_ABI="${PYTHON_ABI}" PYTHON_ABI="${PYTHON_ABI}" return_code root site_packages_absolute_dirs=() site_packages_dirs=() site_packages_absolute_files=() site_packages_files=() 2833 die "${FUNCNAME}(): python_pkg_setup() or python_execute_function() not called"
2834 fi
2835 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
2836 else
2837 if has "${EAPI:-0}" 0 1 2 3; then
2838 iterated_PYTHON_ABIS="${PYTHON_ABI:=$(PYTHON --ABI)}"
2839 else
2840 iterated_PYTHON_ABIS="${PYTHON_ABI}"
2841 fi
2842 fi
1721 2843
1722 # Strip trailing slash from ROOT. 2844 # Strip trailing slash from EROOT.
1723 root="${EROOT%/}" 2845 root="${EROOT%/}"
1724 2846
1725 # Respect ROOT and options passed to compileall.py.
1726 while (($#)); do 2847 while (($#)); do
1727 case "$1" in 2848 case "$1" in
2849 --allow-evaluated-non-sitedir-paths)
2850 allow_evaluated_non_sitedir_paths="1"
2851 ;;
1728 -l|-f|-q) 2852 -l|-f|-q)
1729 options+=("$1") 2853 options+=("$1")
1730 ;; 2854 ;;
1731 -d|-x) 2855 -d|-x)
1732 options+=("$1" "$2") 2856 options+=("$1" "$2")
1733 shift 2857 shift
1734 ;; 2858 ;;
2859 --)
2860 shift
2861 break
2862 ;;
1735 -*) 2863 -*)
1736 ewarn "${FUNCNAME}(): Ignoring option '$1'" 2864 die "${FUNCNAME}(): Unrecognized option '$1'"
1737 ;; 2865 ;;
1738 *) 2866 *)
1739 if ! _python_implementation && [[ "$1" =~ ^"${EPREFIX}"/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
1740 die "${FUNCNAME}() does not support absolute paths of directories/files in site-packages directories"
1741 elif [[ "$1" =~ ^/ ]]; then
1742 if [[ -d "${root}/$1" ]]; then
1743 other_dirs+=("${root}/$1")
1744 elif [[ -f "${root}/$1" ]]; then
1745 other_files+=("${root}/$1")
1746 elif [[ -e "${root}/$1" ]]; then
1747 ewarn "'${root}/$1' is not a file or a directory!"
1748 else
1749 ewarn "'${root}/$1' does not exist!"
1750 fi
1751 else
1752 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI:-$(PYTHON --ABI)}}; do
1753 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
1754 site_packages_dirs+=("$1")
1755 break 2867 break
1756 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
1757 site_packages_files+=("$1")
1758 break
1759 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
1760 ewarn "'$1' is not a file or a directory!"
1761 else
1762 ewarn "'$1' does not exist!"
1763 fi
1764 done
1765 fi
1766 ;; 2868 ;;
1767 esac 2869 esac
1768 shift 2870 shift
1769 done 2871 done
1770 2872
2873 if [[ "${allow_evaluated_non_sitedir_paths}" == "1" ]] && ! _python_package_supporting_installation_for_multiple_python_abis; then
2874 die "${FUNCNAME}(): '--allow-evaluated-non-sitedir-paths' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
2875 fi
2876
2877 if [[ "$#" -eq 0 ]]; then
2878 die "${FUNCNAME}(): Missing files or directories"
2879 fi
2880
2881 while (($#)); do
2882 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
2883 die "${FUNCNAME}(): Invalid argument '$1'"
2884 elif ! _python_implementation && [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
2885 die "${FUNCNAME}(): Paths of directories / files in site-packages directories must be relative to site-packages directories"
2886 elif [[ "$1" =~ ^/ ]]; then
2887 if _python_package_supporting_installation_for_multiple_python_abis; then
2888 if [[ "${allow_evaluated_non_sitedir_paths}" != "1" ]]; then
2889 die "${FUNCNAME}(): Absolute paths cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
2890 fi
2891 if [[ "$1" != *\$* ]]; then
2892 die "${FUNCNAME}(): '$1' has invalid syntax"
2893 fi
2894 if [[ "$1" == *.py ]]; then
2895 evaluated_files+=("$1")
2896 else
2897 evaluated_dirs+=("$1")
2898 fi
2899 else
2900 if [[ -d "${root}$1" ]]; then
2901 other_dirs+=("${root}$1")
2902 elif [[ -f "${root}$1" ]]; then
2903 other_files+=("${root}$1")
2904 elif [[ -e "${root}$1" ]]; then
2905 eerror "${FUNCNAME}(): '${root}$1' is not a regular file or a directory"
2906 else
2907 eerror "${FUNCNAME}(): '${root}$1' does not exist"
2908 fi
2909 fi
2910 else
2911 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
2912 if [[ -d "${root}$(python_get_sitedir)/$1" ]]; then
2913 site_packages_dirs+=("$1")
2914 break
2915 elif [[ -f "${root}$(python_get_sitedir)/$1" ]]; then
2916 site_packages_files+=("$1")
2917 break
2918 elif [[ -e "${root}$(python_get_sitedir)/$1" ]]; then
2919 eerror "${FUNCNAME}(): '$1' is not a regular file or a directory"
2920 else
2921 eerror "${FUNCNAME}(): '$1' does not exist"
2922 fi
2923 done
2924 fi
2925 shift
2926 done
2927
1771 # Set additional options. 2928 # Set additional options.
1772 options+=("-q") 2929 options+=("-q")
1773 2930
1774 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI:-$(PYTHON --ABI)}}; do 2931 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
1775 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})); then 2932 if ((${#site_packages_dirs[@]})) || ((${#site_packages_files[@]})) || ((${#evaluated_dirs[@]})) || ((${#evaluated_files[@]})); then
1776 return_code="0" 2933 return_code="0"
2934 stderr=""
1777 ebegin "Compilation and optimization of Python modules for $(python_get_implementation) $(python_get_version)" 2935 ebegin "Compilation and optimization of Python modules for $(python_get_implementation_and_version)"
1778 if ((${#site_packages_dirs[@]})); then 2936 if ((${#site_packages_dirs[@]})) || ((${#evaluated_dirs[@]})); then
1779 for dir in "${site_packages_dirs[@]}"; do 2937 for dir in "${site_packages_dirs[@]}"; do
1780 site_packages_absolute_dirs+=("${root}$(python_get_sitedir)/${dir}") 2938 dirs+=("${root}$(python_get_sitedir)/${dir}")
1781 done 2939 done
1782 "$(PYTHON)" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" || return_code="1" 2940 for dir in "${evaluated_dirs[@]}"; do
2941 eval "dirs+=(\"\${root}${dir}\")"
2942 done
2943 stderr+="${stderr:+$'\n'}$("$(PYTHON)" -m compileall "${options[@]}" "${dirs[@]}" 2>&1)" || return_code="1"
1783 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then 2944 if ! has "$(_python_get_implementation "${PYTHON_ABI}")" Jython PyPy; then
1784 "$(PYTHON)" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${site_packages_absolute_dirs[@]}" &> /dev/null || return_code="1" 2945 "$(PYTHON)" -O -m compileall "${options[@]}" "${dirs[@]}" &> /dev/null || return_code="1"
1785 fi 2946 fi
2947 _python_clean_compiled_modules "${dirs[@]}"
1786 fi 2948 fi
1787 if ((${#site_packages_files[@]})); then 2949 if ((${#site_packages_files[@]})) || ((${#evaluated_files[@]})); then
1788 for file in "${site_packages_files[@]}"; do 2950 for file in "${site_packages_files[@]}"; do
1789 site_packages_absolute_files+=("${root}$(python_get_sitedir)/${file}") 2951 files+=("${root}$(python_get_sitedir)/${file}")
1790 done 2952 done
1791 "$(PYTHON)" "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" || return_code="1" 2953 for file in "${evaluated_files[@]}"; do
2954 eval "files+=(\"\${root}${file}\")"
2955 done
2956 stderr+="${stderr:+$'\n'}$("$(PYTHON)" -m py_compile "${files[@]}" 2>&1)" || return_code="1"
1792 if [[ "$(_python_get_implementation "${PYTHON_ABI}")" != "Jython" ]]; then 2957 if ! has "$(_python_get_implementation "${PYTHON_ABI}")" Jython PyPy; then
1793 "$(PYTHON)" -O "${root}$(python_get_libdir)/py_compile.py" "${site_packages_absolute_files[@]}" &> /dev/null || return_code="1" 2958 "$(PYTHON)" -O -m py_compile "${files[@]}" &> /dev/null || return_code="1"
1794 fi 2959 fi
2960 _python_clean_compiled_modules "${files[@]}"
1795 fi 2961 fi
1796 eend "${return_code}" 2962 eend "${return_code}"
2963 if [[ -n "${stderr}" ]]; then
2964 eerror "Syntax errors / warnings in Python modules for $(python_get_implementation_and_version):" &> /dev/null
2965 while read stderr_line; do
2966 eerror " ${stderr_line}"
2967 done <<< "${stderr}"
1797 fi 2968 fi
1798 unset site_packages_absolute_dirs site_packages_absolute_files 2969 fi
2970 unset dirs files
1799 done 2971 done
1800 2972
2973 if _python_package_supporting_installation_for_multiple_python_abis; then
1801 # Restore previous value of PYTHON_ABI. 2974 # Restore previous value of PYTHON_ABI.
1802 if [[ -n "${previous_PYTHON_ABI}" ]]; then 2975 if [[ -n "${previous_PYTHON_ABI}" ]]; then
1803 PYTHON_ABI="${previous_PYTHON_ABI}" 2976 PYTHON_ABI="${previous_PYTHON_ABI}"
1804 else 2977 else
1805 unset PYTHON_ABI 2978 unset PYTHON_ABI
2979 fi
1806 fi 2980 fi
1807 2981
1808 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then 2982 if ((${#other_dirs[@]})) || ((${#other_files[@]})); then
1809 return_code="0" 2983 return_code="0"
2984 stderr=""
1810 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for $(python_get_implementation) $(python_get_version)" 2985 ebegin "Compilation and optimization of Python modules placed outside of site-packages directories for $(python_get_implementation_and_version)"
1811 if ((${#other_dirs[@]})); then 2986 if ((${#other_dirs[@]})); then
1812 "$(PYTHON ${PYTHON_ABI})" "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" || return_code="1" 2987 stderr+="${stderr:+$'\n'}$("$(PYTHON ${PYTHON_ABI})" -m compileall "${options[@]}" "${other_dirs[@]}" 2>&1)" || return_code="1"
1813 if [[ "$(_python_get_implementation "${PYTHON_ABI-$(PYTHON --ABI)}")" != "Jython" ]]; then 2988 if ! has "$(_python_get_implementation "${PYTHON_ABI}")" Jython PyPy; then
1814 "$(PYTHON ${PYTHON_ABI})" -O "${root}$(python_get_libdir)/compileall.py" "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1" 2989 "$(PYTHON ${PYTHON_ABI})" -O -m compileall "${options[@]}" "${other_dirs[@]}" &> /dev/null || return_code="1"
1815 fi 2990 fi
2991 _python_clean_compiled_modules "${other_dirs[@]}"
1816 fi 2992 fi
1817 if ((${#other_files[@]})); then 2993 if ((${#other_files[@]})); then
1818 "$(PYTHON ${PYTHON_ABI})" "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" || return_code="1" 2994 stderr+="${stderr:+$'\n'}$("$(PYTHON ${PYTHON_ABI})" -m py_compile "${other_files[@]}" 2>&1)" || return_code="1"
1819 if [[ "$(_python_get_implementation "${PYTHON_ABI-$(PYTHON --ABI)}")" != "Jython" ]]; then 2995 if ! has "$(_python_get_implementation "${PYTHON_ABI}")" Jython PyPy; then
1820 "$(PYTHON ${PYTHON_ABI})" -O "${root}$(python_get_libdir)/py_compile.py" "${other_files[@]}" &> /dev/null || return_code="1" 2996 "$(PYTHON ${PYTHON_ABI})" -O -m py_compile "${other_files[@]}" &> /dev/null || return_code="1"
1821 fi 2997 fi
2998 _python_clean_compiled_modules "${other_files[@]}"
1822 fi 2999 fi
1823 eend "${return_code}" 3000 eend "${return_code}"
3001 if [[ -n "${stderr}" ]]; then
3002 eerror "Syntax errors / warnings in Python modules placed outside of site-packages directories for $(python_get_implementation_and_version):" &> /dev/null
3003 while read stderr_line; do
3004 eerror " ${stderr_line}"
3005 done <<< "${stderr}"
3006 fi
1824 fi 3007 fi
1825 else 3008 else
3009 # Deprecated part of python_mod_optimize()
3010
1826 local myroot mydirs=() myfiles=() myopts=() return_code="0" 3011 local myroot mydirs=() myfiles=() myopts=() return_code="0"
1827 3012
1828 # strip trailing slash 3013 # strip trailing slash
1829 myroot="${EROOT%/}" 3014 myroot="${EROOT%/}"
1830 3015
1831 # respect ROOT and options passed to compileall.py 3016 # respect EROOT and options passed to compileall.py
1832 while (($#)); do 3017 while (($#)); do
1833 case "$1" in 3018 case "$1" in
1834 -l|-f|-q) 3019 -l|-f|-q)
1835 myopts+=("$1") 3020 myopts+=("$1")
1836 ;; 3021 ;;
1837 -d|-x) 3022 -d|-x)
1838 myopts+=("$1" "$2") 3023 myopts+=("$1" "$2")
1839 shift 3024 shift
1840 ;; 3025 ;;
3026 --)
3027 shift
3028 break
3029 ;;
1841 -*) 3030 -*)
1842 ewarn "${FUNCNAME}(): Ignoring option '$1'" 3031 die "${FUNCNAME}(): Unrecognized option '$1'"
1843 ;; 3032 ;;
1844 *) 3033 *)
1845 if [[ -d "${myroot}"/$1 ]]; then 3034 break
1846 mydirs+=("${myroot}/$1")
1847 elif [[ -f "${myroot}"/$1 ]]; then
1848 # Files are passed to python_mod_compile which is ROOT-aware
1849 myfiles+=("$1")
1850 elif [[ -e "${myroot}/$1" ]]; then
1851 ewarn "${myroot}/$1 is not a file or directory!"
1852 else
1853 ewarn "${myroot}/$1 does not exist!"
1854 fi
1855 ;; 3035 ;;
1856 esac 3036 esac
1857 shift 3037 shift
1858 done 3038 done
1859 3039
3040 if [[ "$#" -eq 0 ]]; then
3041 die "${FUNCNAME}(): Missing files or directories"
3042 fi
3043
3044 while (($#)); do
3045 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
3046 die "${FUNCNAME}(): Invalid argument '$1'"
3047 elif [[ -d "${myroot}/${1#/}" ]]; then
3048 mydirs+=("${myroot}/${1#/}")
3049 elif [[ -f "${myroot}/${1#/}" ]]; then
3050 myfiles+=("${myroot}/${1#/}")
3051 elif [[ -e "${myroot}/${1#/}" ]]; then
3052 eerror "${FUNCNAME}(): ${myroot}/${1#/} is not a regular file or directory"
3053 else
3054 eerror "${FUNCNAME}(): ${myroot}/${1#/} does not exist"
3055 fi
3056 shift
3057 done
3058
1860 # set additional opts 3059 # set additional opts
1861 myopts+=(-q) 3060 myopts+=(-q)
3061
3062 PYTHON_ABI="${PYTHON_ABI:-$(PYTHON --ABI)}"
1862 3063
1863 ebegin "Compilation and optimization of Python modules for $(python_get_implementation) $(python_get_version)" 3064 ebegin "Compilation and optimization of Python modules for $(python_get_implementation) $(python_get_version)"
1864 if ((${#mydirs[@]})); then 3065 if ((${#mydirs[@]})); then
1865 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" || return_code="1" 3066 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" || return_code="1"
1866 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1" 3067 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/compileall.py" "${myopts[@]}" "${mydirs[@]}" &> /dev/null || return_code="1"
3068 _python_clean_compiled_modules "${mydirs[@]}"
1867 fi 3069 fi
1868 3070
1869 if ((${#myfiles[@]})); then 3071 if ((${#myfiles[@]})); then
3072 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" || return_code="1"
3073 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" &> /dev/null || return_code="1"
1870 python_mod_compile "${myfiles[@]}" 3074 _python_clean_compiled_modules "${myfiles[@]}"
1871 fi 3075 fi
1872 3076
1873 eend "${return_code}" 3077 eend "${return_code}"
1874 fi 3078 fi
1875} 3079}
1876 3080
1877# @FUNCTION: python_mod_cleanup 3081# @FUNCTION: python_mod_cleanup
1878# @USAGE: [directory|file] 3082# @USAGE: [--allow-evaluated-non-sitedir-paths] [--] <file|directory> [files|directories]
1879# @DESCRIPTION: 3083# @DESCRIPTION:
1880# Run with optional arguments, where arguments are Python modules. If none given, 3084# Delete orphaned byte-compiled Python modules corresponding to specified Python modules.
1881# it will look in /usr/lib/python[0-9].[0-9].
1882# 3085#
1883# It will recursively scan all compiled Python modules in the directories and
1884# determine if they are orphaned (i.e. their corresponding .py files are missing.)
1885# If they are, then it will remove their corresponding .pyc and .pyo files.
1886#
1887# This function should only be run in pkg_postrm(). 3086# This function can be used only in pkg_postrm() phase.
1888python_mod_cleanup() { 3087python_mod_cleanup() {
3088 if [[ "${EBUILD_PHASE}" != "postrm" ]]; then
3089 die "${FUNCNAME}() can be used only in pkg_postrm() phase"
3090 fi
3091
3092 _python_check_python_pkg_setup_execution
1889 _python_initialize_prefix_variables 3093 _python_initialize_prefix_variables
1890 _python_set_color_variables
1891 3094
1892 local path py_file PYTHON_ABI="${PYTHON_ABI}" SEARCH_PATH=() root 3095 local allow_evaluated_non_sitedir_paths="0" dir iterated_PYTHON_ABIS PYTHON_ABI="${PYTHON_ABI}" root search_paths=() sitedir
1893 3096
1894 # Check if phase is pkg_postrm(). 3097 if _python_package_supporting_installation_for_multiple_python_abis; then
1895 [[ ${EBUILD_PHASE} != "postrm" ]] && die "${FUNCNAME}() should only be run in pkg_postrm()" 3098 if has "${EAPI:-0}" 0 1 2 3 && [[ -z "${PYTHON_ABIS}" ]]; then
3099 die "${FUNCNAME}(): python_pkg_setup() or python_execute_function() not called"
3100 fi
3101 iterated_PYTHON_ABIS="${PYTHON_ABIS}"
3102 else
3103 if has "${EAPI:-0}" 0 1 2 3; then
3104 iterated_PYTHON_ABIS="${PYTHON_ABI:-$(PYTHON --ABI)}"
3105 else
3106 iterated_PYTHON_ABIS="${PYTHON_ABI}"
3107 fi
3108 fi
1896 3109
1897 # Strip trailing slash from ROOT. 3110 # Strip trailing slash from EROOT.
1898 root="${EROOT%/}" 3111 root="${EROOT%/}"
1899 3112
1900 if (($#)); then 3113 while (($#)); do
1901 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then 3114 case "$1" in
3115 --allow-evaluated-non-sitedir-paths)
3116 allow_evaluated_non_sitedir_paths="1"
3117 ;;
3118 --)
3119 shift
3120 break
3121 ;;
3122 -*)
3123 die "${FUNCNAME}(): Unrecognized option '$1'"
3124 ;;
3125 *)
3126 break
3127 ;;
3128 esac
3129 shift
3130 done
3131
3132 if [[ "${allow_evaluated_non_sitedir_paths}" == "1" ]] && ! _python_package_supporting_installation_for_multiple_python_abis; then
3133 die "${FUNCNAME}(): '--allow-evaluated-non-sitedir-paths' option cannot be used in ebuilds of packages not supporting installation for multiple Python ABIs"
3134 fi
3135
3136 if [[ "$#" -eq 0 ]]; then
3137 die "${FUNCNAME}(): Missing files or directories"
3138 fi
3139
3140 if ! has "${EAPI:-0}" 0 1 2 || _python_package_supporting_installation_for_multiple_python_abis || _python_implementation || [[ "${CATEGORY}/${PN}" == "sys-apps/portage" ]]; then
1902 while (($#)); do 3141 while (($#)); do
3142 if [[ "$1" =~ ^($|(\.|\.\.|/)($|/)) ]]; then
3143 die "${FUNCNAME}(): Invalid argument '$1'"
1903 if ! _python_implementation && [[ "$1" =~ ^"${EPREFIX}"/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then 3144 elif ! _python_implementation && [[ "$1" =~ ^/usr/lib(32|64)?/python[[:digit:]]+\.[[:digit:]]+ ]]; then
1904 die "${FUNCNAME}() does not support absolute paths of directories/files in site-packages directories" 3145 die "${FUNCNAME}(): Paths of directories / files in site-packages directories must be relative to site-packages directories"
1905 elif [[ "$1" =~ ^/ ]]; then 3146 elif [[ "$1" =~ ^/ ]]; then
1906 SEARCH_PATH+=("${root}/${1#/}") 3147 if _python_package_supporting_installation_for_multiple_python_abis; then
3148 if [[ "${allow_evaluated_non_sitedir_paths}" != "1" ]]; then
3149 die "${FUNCNAME}(): Absolute paths cannot be used in ebuilds of packages supporting installation for multiple Python ABIs"
3150 fi
3151 if [[ "$1" != *\$* ]]; then
3152 die "${FUNCNAME}(): '$1' has invalid syntax"
3153 fi
3154 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
3155 eval "search_paths+=(\"\${root}$1\")"
3156 done
1907 else 3157 else
1908 for PYTHON_ABI in ${PYTHON_ABIS-${PYTHON_ABI:-$(PYTHON --ABI)}}; do 3158 search_paths+=("${root}$1")
3159 fi
3160 else
3161 for PYTHON_ABI in ${iterated_PYTHON_ABIS}; do
1909 SEARCH_PATH+=("${root}$(python_get_sitedir)/$1") 3162 search_paths+=("${root}$(python_get_sitedir)/$1")
1910 done 3163 done
1911 fi 3164 fi
1912 shift 3165 shift
1913 done 3166 done
1914 else
1915 SEARCH_PATH=("${@#/}")
1916 SEARCH_PATH=("${SEARCH_PATH[@]/#/${root}/}")
1917 fi
1918 else 3167 else
1919 local dir sitedir 3168 # Deprecated part of python_mod_cleanup()
1920 for dir in "${root}"/usr/lib*; do
1921 if [[ -d "${dir}" && ! -L "${dir}" ]]; then
1922 for sitedir in "${dir}"/python*/site-packages; do
1923 if [[ -d "${sitedir}" ]]; then
1924 SEARCH_PATH+=("${sitedir}")
1925 fi
1926 done
1927 fi
1928 done
1929 for sitedir in "${root}"/usr/share/jython-*/Lib/site-packages; do
1930 if [[ -d "${sitedir}" ]]; then
1931 SEARCH_PATH+=("${sitedir}")
1932 fi
1933 done
1934 fi
1935 3169
1936 for path in "${SEARCH_PATH[@]}"; do 3170 search_paths=("${@#/}")
1937 if [[ -d "${path}" ]]; then 3171 search_paths=("${search_paths[@]/#/${root}/}")
1938 find "${path}" "(" -name "*.py[co]" -o -name "*\$py.class" ")" -print0 | while read -rd ''; do
1939 if [[ "${REPLY}" == *[co] ]]; then
1940 py_file="${REPLY%[co]}"
1941 [[ -f "${py_file}" || (! -f "${py_file}c" && ! -f "${py_file}o") ]] && continue
1942 einfo "${_BLUE}<<< ${py_file}[co]${_NORMAL}"
1943 rm -f "${py_file}"[co]
1944 elif [[ "${REPLY}" == *\$py.class ]]; then
1945 py_file="${REPLY%\$py.class}.py"
1946 [[ -f "${py_file}" || ! -f "${py_file%.py}\$py.class" ]] && continue
1947 einfo "${_BLUE}<<< ${py_file%.py}\$py.class${_NORMAL}"
1948 rm -f "${py_file%.py}\$py.class"
1949 fi
1950 done
1951
1952 # Attempt to delete directories, which may be empty.
1953 find "${path}" -type d | sort -r | while read -r dir; do
1954 rmdir "${dir}" 2>/dev/null && einfo "${_CYAN}<<< ${dir}${_NORMAL}"
1955 done
1956 elif [[ "${path}" == *.py && ! -f "${path}" ]]; then
1957 if [[ (-f "${path}c" || -f "${path}o") ]]; then
1958 einfo "${_BLUE}<<< ${path}[co]${_NORMAL}"
1959 rm -f "${path}"[co]
1960 fi
1961 if [[ -f "${path%.py}\$py.class" ]]; then
1962 einfo "${_BLUE}<<< ${path%.py}\$py.class${_NORMAL}"
1963 rm -f "${path%.py}\$py.class"
1964 fi
1965 fi 3172 fi
1966 done 3173
3174 _python_clean_compiled_modules "${search_paths[@]}"
1967} 3175}
1968 3176
1969# ================================================================================================ 3177# ================================================================================================
1970# ===================================== DEPRECATED FUNCTIONS ===================================== 3178# ===================================== DEPRECATED FUNCTIONS =====================================
1971# ================================================================================================ 3179# ================================================================================================
1972 3180
1973# @FUNCTION: python_version 3181fi # _PYTHON_ECLASS_INHERITED
1974# @DESCRIPTION:
1975# Run without arguments and it will export the version of python
1976# currently in use as $PYVER; sets PYVER/PYVER_MAJOR/PYVER_MINOR
1977python_version() {
1978 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
1979 eerror "Use PYTHON() and/or python_get_*() instead of ${FUNCNAME}()."
1980 die "${FUNCNAME}() cannot be used in this EAPI"
1981 fi
1982
1983 [[ -n "${PYVER}" ]] && return 0
1984 local tmpstr
1985 python="${python:-${EPREFIX}/usr/bin/python}"
1986 tmpstr="$(EPYTHON= ${python} -V 2>&1 )"
1987 export PYVER_ALL="${tmpstr#Python }"
1988 export PYVER_MAJOR="${PYVER_ALL:0:1}"
1989 export PYVER_MINOR="${PYVER_ALL:2:1}"
1990 if [[ "${PYVER_ALL:3:1}" == "." ]]; then
1991 export PYVER_MICRO="${PYVER_ALL:4}"
1992 fi
1993 export PYVER="${PYVER_MAJOR}.${PYVER_MINOR}"
1994}
1995
1996# @FUNCTION: python_mod_exists
1997# @USAGE: <module>
1998# @DESCRIPTION:
1999# Run with the module name as an argument. It will check if a
2000# Python module is installed and loadable. It will return
2001# TRUE(0) if the module exists, and FALSE(1) if the module does
2002# not exist.
2003#
2004# Example:
2005# if python_mod_exists gtk; then
2006# echo "gtk support enabled"
2007# fi
2008python_mod_exists() {
2009 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
2010 eerror "Use USE dependencies and/or has_version() instead of ${FUNCNAME}()."
2011 die "${FUNCNAME}() cannot be used in this EAPI"
2012 fi
2013
2014 if [[ "$#" -ne 1 ]]; then
2015 die "${FUNCNAME}() requires 1 argument"
2016 fi
2017 "$(PYTHON ${PYTHON_ABI})" -c "import $1" &> /dev/null
2018}
2019
2020# @FUNCTION: python_tkinter_exists
2021# @DESCRIPTION:
2022# Run without arguments, checks if Python was compiled with Tkinter
2023# support. If not, prints an error message and dies.
2024python_tkinter_exists() {
2025 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
2026 eerror "Use PYTHON_USE_WITH=\"xml\" and python_pkg_setup() instead of ${FUNCNAME}()."
2027 die "${FUNCNAME}() cannot be used in this EAPI"
2028 fi
2029
2030 if ! "$(PYTHON ${PYTHON_ABI})" -c "from sys import version_info
2031if version_info[0] == 3:
2032 import tkinter
2033else:
2034 import Tkinter" &> /dev/null; then
2035 eerror "Python needs to be rebuilt with tkinter support enabled."
2036 eerror "Add the following line to '${EPREFIX}/etc/portage/package.use' and rebuild Python"
2037 eerror "dev-lang/python tk"
2038 die "Python installed without support for tkinter"
2039 fi
2040}
2041
2042# @FUNCTION: python_mod_compile
2043# @USAGE: <file> [more files ...]
2044# @DESCRIPTION:
2045# Given filenames, it will pre-compile the module's .pyc and .pyo.
2046# This function should only be run in pkg_postinst()
2047#
2048# Example:
2049# python_mod_compile /usr/lib/python2.3/site-packages/pygoogle.py
2050#
2051python_mod_compile() {
2052 if ! has "${EAPI:-0}" 0 1 2 || [[ -n "${SUPPORT_PYTHON_ABIS}" ]]; then
2053 eerror "Use python_mod_optimize() instead of ${FUNCNAME}()."
2054 die "${FUNCNAME}() cannot be used in this EAPI"
2055 fi
2056
2057 _python_initialize_prefix_variables
2058
2059 local f myroot myfiles=()
2060
2061 # Check if phase is pkg_postinst()
2062 [[ ${EBUILD_PHASE} != postinst ]] && die "${FUNCNAME}() should only be run in pkg_postinst()"
2063
2064 # strip trailing slash
2065 myroot="${EROOT%/}"
2066
2067 # respect ROOT
2068 for f in "$@"; do
2069 [[ -f "${myroot}/${f}" ]] && myfiles+=("${myroot}/${f}")
2070 done
2071
2072 if ((${#myfiles[@]})); then
2073 "$(PYTHON ${PYTHON_ABI})" "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}"
2074 "$(PYTHON ${PYTHON_ABI})" -O "${myroot}$(python_get_libdir)/py_compile.py" "${myfiles[@]}" &> /dev/null
2075 else
2076 ewarn "No files to compile!"
2077 fi
2078}

Legend:
Removed from v.1.91  
changed lines
  Added in v.1.171

  ViewVC Help
Powered by ViewVC 1.1.20