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