papp-text/dos2unix: Bump to version 7.4.1
[gentoo.git] / eclass / python-r1.eclass
1 # Copyright 1999-2018 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: python-r1.eclass
5 # @MAINTAINER:
6 # Python team <python@gentoo.org>
7 # @AUTHOR:
8 # Author: Michał Górny <mgorny@gentoo.org>
9 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10 # @SUPPORTED_EAPIS: 5 6 7
11 # @BLURB: A common, simple eclass for Python packages.
12 # @DESCRIPTION:
13 # A common eclass providing helper functions to build and install
14 # packages supporting being installed for multiple Python
15 # implementations.
16 #
17 # This eclass sets correct IUSE. Modification of REQUIRED_USE has to
18 # be done by the author of the ebuild (but PYTHON_REQUIRED_USE is
19 # provided for convenience, see below). python-r1 exports PYTHON_DEPS
20 # and PYTHON_USEDEP so you can create correct dependencies for your
21 # package easily. It also provides methods to easily run a command for
22 # each enabled Python implementation and duplicate the sources for them.
23 #
24 # Please note that python-r1 will always inherit python-utils-r1 as
25 # well. Thus, all the functions defined there can be used
26 # in the packages using python-r1, and there is no need ever to inherit
27 # both.
28 #
29 # For more information, please see the wiki:
30 # https://wiki.gentoo.org/wiki/Project:Python/python-r1
31
32 case "${EAPI:-0}" in
33         0|1|2|3|4)
34                 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
35                 ;;
36         5|6|7)
37                 # EAPI=5 is required for sane USE_EXPAND dependencies
38                 ;;
39         *)
40                 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
41                 ;;
42 esac
43
44 if [[ ! ${_PYTHON_R1} ]]; then
45
46 if [[ ${_PYTHON_SINGLE_R1} ]]; then
47         die 'python-r1.eclass can not be used with python-single-r1.eclass.'
48 elif [[ ${_PYTHON_ANY_R1} ]]; then
49         die 'python-r1.eclass can not be used with python-any-r1.eclass.'
50 fi
51
52 [[ ${EAPI} == [45] ]] && inherit eutils
53 inherit multibuild python-utils-r1
54
55 fi
56
57 # @ECLASS-VARIABLE: PYTHON_COMPAT
58 # @REQUIRED
59 # @DESCRIPTION:
60 # This variable contains a list of Python implementations the package
61 # supports. It must be set before the `inherit' call. It has to be
62 # an array.
63 #
64 # Example:
65 # @CODE
66 # PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
67 # @CODE
68 #
69 # Please note that you can also use bash brace expansion if you like:
70 # @CODE
71 # PYTHON_COMPAT=( python2_7 python3_{3,4} )
72 # @CODE
73
74 # @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
75 # @INTERNAL
76 # @DESCRIPTION:
77 # This variable can be used when working with ebuilds to override
78 # the in-ebuild PYTHON_COMPAT. It is a string listing all
79 # the implementations which package will be built for. It need be
80 # specified in the calling environment, and not in ebuilds.
81 #
82 # It should be noted that in order to preserve metadata immutability,
83 # PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
84 # The state of PYTHON_TARGETS is ignored, and all the implementations
85 # in PYTHON_COMPAT_OVERRIDE are built. Dependencies need to be satisfied
86 # manually.
87 #
88 # Example:
89 # @CODE
90 # PYTHON_COMPAT_OVERRIDE='pypy python3_3' emerge -1v dev-python/foo
91 # @CODE
92
93 # @ECLASS-VARIABLE: PYTHON_REQ_USE
94 # @DEFAULT_UNSET
95 # @DESCRIPTION:
96 # The list of USEflags required to be enabled on the chosen Python
97 # implementations, formed as a USE-dependency string. It should be valid
98 # for all implementations in PYTHON_COMPAT, so it may be necessary to
99 # use USE defaults.
100 #
101 # This should be set before calling `inherit'.
102 #
103 # Example:
104 # @CODE
105 # PYTHON_REQ_USE="gdbm,ncurses(-)?"
106 # @CODE
107 #
108 # It will cause the Python dependencies to look like:
109 # @CODE
110 # python_targets_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
111 # @CODE
112
113 # @ECLASS-VARIABLE: PYTHON_DEPS
114 # @DESCRIPTION:
115 # This is an eclass-generated Python dependency string for all
116 # implementations listed in PYTHON_COMPAT.
117 #
118 # Example use:
119 # @CODE
120 # RDEPEND="${PYTHON_DEPS}
121 #       dev-foo/mydep"
122 # DEPEND="${RDEPEND}"
123 # @CODE
124 #
125 # Example value:
126 # @CODE
127 # dev-lang/python-exec:=
128 # python_targets_python2_7? ( dev-lang/python:2.7[gdbm] )
129 # python_targets_pypy? ( virtual/pypy[gdbm] )
130 # @CODE
131
132 # @ECLASS-VARIABLE: PYTHON_USEDEP
133 # @DESCRIPTION:
134 # This is an eclass-generated USE-dependency string which can be used to
135 # depend on another Python package being built for the same Python
136 # implementations.
137 #
138 # The generate USE-flag list is compatible with packages using python-r1
139 # and python-distutils-ng eclasses. It must not be used on packages
140 # using python.eclass.
141 #
142 # Example use:
143 # @CODE
144 # RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
145 # @CODE
146 #
147 # Example value:
148 # @CODE
149 # python_targets_python2_7(-)?,python_targets_python3_4(-)?
150 # @CODE
151
152 # @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
153 # @DESCRIPTION:
154 # This is an eclass-generated required-use expression which ensures at
155 # least one Python implementation has been enabled.
156 #
157 # This expression should be utilized in an ebuild by including it in
158 # REQUIRED_USE, optionally behind a use flag.
159 #
160 # Example use:
161 # @CODE
162 # REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
163 # @CODE
164 #
165 # Example value:
166 # @CODE
167 # || ( python_targets_python2_7 python_targets_python3_4 )
168 # @CODE
169
170 _python_set_globals() {
171         local deps i PYTHON_PKG_DEP
172
173         _python_set_impls
174
175         for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
176                 python_export "${i}" PYTHON_PKG_DEP
177                 deps+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) "
178         done
179
180         local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
181         local optflags=${flags[@]/%/(-)?}
182
183         # A nice QA trick here. Since a python-single-r1 package has to have
184         # at least one PYTHON_SINGLE_TARGET enabled (REQUIRED_USE),
185         # the following check will always fail on those packages. Therefore,
186         # it should prevent developers from mistakenly depending on packages
187         # not supporting multiple Python implementations.
188
189         local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" )
190         optflags+=,${flags_st[@]/%/(-)}
191         local requse="|| ( ${flags[*]} )"
192         local usedep=${optflags// /,}
193
194         # 1) well, python-exec would suffice as an RDEP
195         # but no point in making this overcomplex, BDEP doesn't hurt anyone
196         # 2) python-exec should be built with all targets forced anyway
197         # but if new targets were added, we may need to force a rebuild
198         if [[ ${_PYTHON_WANT_PYTHON_EXEC2} == 0 ]]; then
199                 die "python-exec:0 is no longer supported, please fix your ebuild to work with python-exec:2"
200         else
201                 deps+=">=dev-lang/python-exec-2:=[${usedep}]"
202         fi
203
204         if [[ ${PYTHON_DEPS+1} ]]; then
205                 # IUSE is magical, so we can't really check it
206                 # (but we verify PYTHON_COMPAT already)
207
208                 if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
209                         eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
210                         eerror "Before: ${PYTHON_DEPS}"
211                         eerror "Now   : ${deps}"
212                         die "PYTHON_DEPS integrity check failed"
213                 fi
214
215                 # these two are formality -- they depend on PYTHON_COMPAT only
216                 if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
217                         eerror "PYTHON_REQUIRED_USE have changed between inherits!"
218                         eerror "Before: ${PYTHON_REQUIRED_USE}"
219                         eerror "Now   : ${requse}"
220                         die "PYTHON_REQUIRED_USE integrity check failed"
221                 fi
222
223                 if [[ ${PYTHON_USEDEP} != "${usedep}" ]]; then
224                         eerror "PYTHON_USEDEP have changed between inherits!"
225                         eerror "Before: ${PYTHON_USEDEP}"
226                         eerror "Now   : ${usedep}"
227                         die "PYTHON_USEDEP integrity check failed"
228                 fi
229         else
230                 IUSE=${flags[*]}
231
232                 PYTHON_DEPS=${deps}
233                 PYTHON_REQUIRED_USE=${requse}
234                 PYTHON_USEDEP=${usedep}
235                 readonly PYTHON_DEPS PYTHON_REQUIRED_USE
236         fi
237 }
238 _python_set_globals
239 unset -f _python_set_globals
240
241 if [[ ! ${_PYTHON_R1} ]]; then
242
243 # @FUNCTION: _python_validate_useflags
244 # @INTERNAL
245 # @DESCRIPTION:
246 # Enforce the proper setting of PYTHON_TARGETS, if PYTHON_COMPAT_OVERRIDE
247 # is not in effect. If it is, just warn that the flags will be ignored.
248 _python_validate_useflags() {
249         debug-print-function ${FUNCNAME} "${@}"
250
251         if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
252                 if [[ ! ${_PYTHON_COMPAT_OVERRIDE_WARNED} ]]; then
253                         ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
254                         ewarn "implementations will be enabled:"
255                         ewarn
256                         ewarn " ${PYTHON_COMPAT_OVERRIDE}"
257                         ewarn
258                         ewarn "Dependencies won't be satisfied, and PYTHON_TARGETS will be ignored."
259                         _PYTHON_COMPAT_OVERRIDE_WARNED=1
260                 fi
261                 # we do not use flags with PCO
262                 return
263         fi
264
265         local i
266
267         for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
268                 use "python_targets_${i}" && return 0
269         done
270
271         eerror "No Python implementation selected for the build. Please add one"
272         eerror "of the following values to your PYTHON_TARGETS (in make.conf):"
273         eerror
274         eerror "${PYTHON_COMPAT[@]}"
275         echo
276         die "No supported Python implementation in PYTHON_TARGETS."
277 }
278
279 # @FUNCTION: python_gen_usedep
280 # @USAGE: <pattern> [...]
281 # @DESCRIPTION:
282 # Output a USE dependency string for Python implementations which
283 # are both in PYTHON_COMPAT and match any of the patterns passed
284 # as parameters to the function.
285 #
286 # The patterns can be either fnmatch-style patterns (matched via bash
287 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
288 # appropriately all enabled Python 2/3 implementations (alike
289 # python_is_python3). Remember to escape or quote the fnmatch patterns
290 # to prevent accidental shell filename expansion.
291 #
292 # When all implementations are requested, please use ${PYTHON_USEDEP}
293 # instead. Please also remember to set an appropriate REQUIRED_USE
294 # to avoid ineffective USE flags.
295 #
296 # Example:
297 # @CODE
298 # PYTHON_COMPAT=( python{2_7,3_4} )
299 # DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
300 # @CODE
301 #
302 # It will cause the dependency to look like:
303 # @CODE
304 # DEPEND="doc? ( dev-python/epydoc[python_targets_python2_7?] )"
305 # @CODE
306 python_gen_usedep() {
307         debug-print-function ${FUNCNAME} "${@}"
308
309         local impl matches=()
310
311         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
312                 if _python_impl_matches "${impl}" "${@}"; then
313                         matches+=(
314                                 "python_targets_${impl}(-)?"
315                                 "-python_single_target_${impl}(-)"
316                         )
317                 fi
318         done
319
320         [[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
321
322         local out=${matches[@]}
323         echo "${out// /,}"
324 }
325
326 # @FUNCTION: python_gen_useflags
327 # @USAGE: <pattern> [...]
328 # @DESCRIPTION:
329 # Output a list of USE flags for Python implementations which
330 # are both in PYTHON_COMPAT and match any of the patterns passed
331 # as parameters to the function.
332 #
333 # The patterns can be either fnmatch-style patterns (matched via bash
334 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
335 # appropriately all enabled Python 2/3 implementations (alike
336 # python_is_python3). Remember to escape or quote the fnmatch patterns
337 # to prevent accidental shell filename expansion.
338 #
339 # Example:
340 # @CODE
341 # PYTHON_COMPAT=( python{2_7,3_4} )
342 # REQUIRED_USE="doc? ( || ( $(python_gen_useflags python2*) ) )"
343 # @CODE
344 #
345 # It will cause the variable to look like:
346 # @CODE
347 # REQUIRED_USE="doc? ( || ( python_targets_python2_7 ) )"
348 # @CODE
349 python_gen_useflags() {
350         debug-print-function ${FUNCNAME} "${@}"
351
352         local impl matches=()
353
354         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
355                 if _python_impl_matches "${impl}" "${@}"; then
356                         matches+=( "python_targets_${impl}" )
357                 fi
358         done
359
360         echo "${matches[@]}"
361 }
362
363 # @FUNCTION: python_gen_cond_dep
364 # @USAGE: <dependency> <pattern> [...]
365 # @DESCRIPTION:
366 # Output a list of <dependency>-ies made conditional to USE flags
367 # of Python implementations which are both in PYTHON_COMPAT and match
368 # any of the patterns passed as the remaining parameters.
369 #
370 # The patterns can be either fnmatch-style patterns (matched via bash
371 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
372 # appropriately all enabled Python 2/3 implementations (alike
373 # python_is_python3). Remember to escape or quote the fnmatch patterns
374 # to prevent accidental shell filename expansion.
375 #
376 # In order to enforce USE constraints on the packages, verbatim
377 # '${PYTHON_USEDEP}' (quoted!) may be placed in the dependency
378 # specification. It will get expanded within the function into a proper
379 # USE dependency string.
380 #
381 # Example:
382 # @CODE
383 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
384 # RDEPEND="$(python_gen_cond_dep \
385 #   'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
386 # @CODE
387 #
388 # It will cause the variable to look like:
389 # @CODE
390 # RDEPEND="python_targets_python2_7? (
391 #     dev-python/unittest2[python_targets_python2_7?] )
392 #       python_targets_pypy? (
393 #     dev-python/unittest2[python_targets_pypy?] )"
394 # @CODE
395 python_gen_cond_dep() {
396         debug-print-function ${FUNCNAME} "${@}"
397
398         local impl matches=()
399         local dep=${1}
400         shift
401
402         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
403                 if _python_impl_matches "${impl}" "${@}"; then
404                         # substitute ${PYTHON_USEDEP} if used
405                         # (since python_gen_usedep() will not return ${PYTHON_USEDEP}
406                         #  the code is run at most once)
407                         if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
408                                 local usedep=$(python_gen_usedep "${@}")
409                                 dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
410                         fi
411
412                         matches+=( "python_targets_${impl}? ( ${dep} )" )
413                 fi
414         done
415
416         echo "${matches[@]}"
417 }
418
419 # @FUNCTION: python_gen_impl_dep
420 # @USAGE: [<requested-use-flags> [<impl-pattern>...]]
421 # @DESCRIPTION:
422 # Output a dependency on Python implementations with the specified USE
423 # dependency string appended, or no USE dependency string if called
424 # without the argument (or with empty argument). If any implementation
425 # patterns are passed, the output dependencies will be generated only
426 # for the implementations matching them.
427 #
428 # The patterns can be either fnmatch-style patterns (matched via bash
429 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
430 # appropriately all enabled Python 2/3 implementations (alike
431 # python_is_python3). Remember to escape or quote the fnmatch patterns
432 # to prevent accidental shell filename expansion.
433 #
434 # Use this function when you need to request different USE flags
435 # on the Python interpreter depending on package's USE flags. If you
436 # only need a single set of interpreter USE flags, just set
437 # PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
438 #
439 # Example:
440 # @CODE
441 # PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
442 # RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
443 # @CODE
444 #
445 # It will cause the variable to look like:
446 # @CODE
447 # RDEPEND="foo? (
448 #   python_targets_python2_7? (
449 #     dev-lang/python:2.7[xml(+)] )
450 #       python_targets_pypy? (
451 #     dev-python/pypy[xml(+)] ) )"
452 # @CODE
453 python_gen_impl_dep() {
454         debug-print-function ${FUNCNAME} "${@}"
455
456         local impl matches=()
457         local PYTHON_REQ_USE=${1}
458         shift
459
460         local patterns=( "${@-*}" )
461         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
462                 if _python_impl_matches "${impl}" "${patterns[@]}"; then
463                         local PYTHON_PKG_DEP
464                         python_export "${impl}" PYTHON_PKG_DEP
465                         matches+=( "python_targets_${impl}? ( ${PYTHON_PKG_DEP} )" )
466                 fi
467         done
468
469         echo "${matches[@]}"
470 }
471
472 # @FUNCTION: python_gen_any_dep
473 # @USAGE: <dependency-block> [<impl-pattern>...]
474 # @DESCRIPTION:
475 # Generate an any-of dependency that enforces a version match between
476 # the Python interpreter and Python packages. <dependency-block> needs
477 # to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
478 # references (quoted!) that will get expanded inside the function.
479 # Optionally, patterns may be specified to restrict the dependency
480 # to a subset of Python implementations supported by the ebuild.
481 #
482 # The patterns can be either fnmatch-style patterns (matched via bash
483 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
484 # appropriately all enabled Python 2/3 implementations (alike
485 # python_is_python3). Remember to escape or quote the fnmatch patterns
486 # to prevent accidental shell filename expansion.
487 #
488 # This should be used along with an appropriate python_check_deps()
489 # that checks which of the any-of blocks were matched, and python_setup
490 # call that enables use of the matched implementation.
491 #
492 # Example use:
493 # @CODE
494 # DEPEND="$(python_gen_any_dep '
495 #       dev-python/foo[${PYTHON_USEDEP}]
496 #       || ( dev-python/bar[${PYTHON_USEDEP}]
497 #               dev-python/baz[${PYTHON_USEDEP}] )' -2)"
498 #
499 # python_check_deps() {
500 #       has_version "dev-python/foo[${PYTHON_USEDEP}]" \
501 #               && { has_version "dev-python/bar[${PYTHON_USEDEP}]" \
502 #                       || has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
503 # }
504 #
505 # src_compile() {
506 #       python_foreach_impl usual_code
507 #
508 #       # some common post-build task that requires Python 2
509 #       python_setup -2
510 #       emake frobnicate
511 # }
512 # @CODE
513 #
514 # Example value:
515 # @CODE
516 # || (
517 #       (
518 #               dev-lang/python:2.7
519 #               dev-python/foo[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
520 #               || ( dev-python/bar[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
521 #                       dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] )
522 #       )
523 #       (
524 #               dev-lang/python:3.3
525 #               dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
526 #               || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
527 #                       dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] )
528 #       )
529 # )
530 # @CODE
531 python_gen_any_dep() {
532         debug-print-function ${FUNCNAME} "${@}"
533
534         local depstr=${1}
535         [[ ${depstr} ]] || die "No dependency string provided"
536         shift
537
538         local i PYTHON_PKG_DEP out=
539         for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
540                 if _python_impl_matches "${i}" "${@-*}"; then
541                         local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
542                         python_export "${i}" PYTHON_PKG_DEP
543
544                         local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
545                         # note: need to strip '=' slot operator for || deps
546                         out="( ${PYTHON_PKG_DEP%=} ${i_depstr} ) ${out}"
547                 fi
548         done
549         echo "|| ( ${out})"
550 }
551
552 # @ECLASS-VARIABLE: BUILD_DIR
553 # @DESCRIPTION:
554 # The current build directory. In global scope, it is supposed to
555 # contain an initial build directory; if unset, it defaults to ${S}.
556 #
557 # In functions run by python_foreach_impl(), the BUILD_DIR is locally
558 # set to an implementation-specific build directory. That path is
559 # created through appending a hyphen and the implementation name
560 # to the final component of the initial BUILD_DIR.
561 #
562 # Example value:
563 # @CODE
564 # ${WORKDIR}/foo-1.3-python2_7
565 # @CODE
566
567 # @FUNCTION: python_copy_sources
568 # @DESCRIPTION:
569 # Create a single copy of the package sources for each enabled Python
570 # implementation.
571 #
572 # The sources are always copied from initial BUILD_DIR (or S if unset)
573 # to implementation-specific build directory matching BUILD_DIR used by
574 # python_foreach_abi().
575 python_copy_sources() {
576         debug-print-function ${FUNCNAME} "${@}"
577
578         local MULTIBUILD_VARIANTS
579         _python_obtain_impls
580
581         multibuild_copy_sources
582 }
583
584 # @FUNCTION: _python_obtain_impls
585 # @INTERNAL
586 # @DESCRIPTION:
587 # Set up the enabled implementation list.
588 _python_obtain_impls() {
589         _python_validate_useflags
590
591         if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
592                 MULTIBUILD_VARIANTS=( ${PYTHON_COMPAT_OVERRIDE} )
593                 return
594         fi
595
596         MULTIBUILD_VARIANTS=()
597
598         local impl
599         for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
600                 has "${impl}" "${PYTHON_COMPAT[@]}" && \
601                 use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" )
602         done
603 }
604
605 # @FUNCTION: _python_multibuild_wrapper
606 # @USAGE: <command> [<args>...]
607 # @INTERNAL
608 # @DESCRIPTION:
609 # Initialize the environment for Python implementation selected
610 # for multibuild.
611 _python_multibuild_wrapper() {
612         debug-print-function ${FUNCNAME} "${@}"
613
614         local -x EPYTHON PYTHON
615         local -x PATH=${PATH} PKG_CONFIG_PATH=${PKG_CONFIG_PATH}
616         python_export "${MULTIBUILD_VARIANT}" EPYTHON PYTHON
617         python_wrapper_setup
618
619         "${@}"
620 }
621
622 # @FUNCTION: python_foreach_impl
623 # @USAGE: <command> [<args>...]
624 # @DESCRIPTION:
625 # Run the given command for each of the enabled Python implementations.
626 # If additional parameters are passed, they will be passed through
627 # to the command.
628 #
629 # The function will return 0 status if all invocations succeed.
630 # Otherwise, the return code from first failing invocation will
631 # be returned.
632 #
633 # For each command being run, EPYTHON, PYTHON and BUILD_DIR are set
634 # locally, and the former two are exported to the command environment.
635 python_foreach_impl() {
636         debug-print-function ${FUNCNAME} "${@}"
637
638         local MULTIBUILD_VARIANTS
639         _python_obtain_impls
640
641         multibuild_foreach_variant _python_multibuild_wrapper "${@}"
642 }
643
644 # @FUNCTION: python_setup
645 # @USAGE: [<impl-pattern>...]
646 # @DESCRIPTION:
647 # Find the best (most preferred) Python implementation that is suitable
648 # for running common Python code. Set the Python build environment up
649 # for that implementation. This function has two modes of operation:
650 # pure and any-of dep.
651 #
652 # The pure mode is used if python_check_deps() function is not declared.
653 # In this case, an implementation is considered suitable if it is
654 # supported (in PYTHON_COMPAT), enabled (via USE flags) and matches
655 # at least one of the patterns passed (or '*' if no patterns passed).
656 #
657 # Implementation restrictions in the pure mode need to be accompanied
658 # by appropriate REQUIRED_USE constraints. Otherwise, the eclass may
659 # fail at build time due to unsatisfied dependencies.
660 #
661 # The any-of dep mode is used if python_check_deps() is declared.
662 # In this mode, an implementation is considered suitable if it is
663 # supported, matches at least one of the patterns and python_check_deps()
664 # has successful return code. USE flags are not considered.
665 #
666 # The python_check_deps() function in the any-of mode needs to be
667 # accompanied by appropriate any-of dependencies.
668 #
669 # The patterns can be either fnmatch-style patterns (matched via bash
670 # == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
671 # appropriately all enabled Python 2/3 implementations (alike
672 # python_is_python3). Remember to escape or quote the fnmatch patterns
673 # to prevent accidental shell filename expansion.
674 #
675 # This function needs to be used when Python is being called outside
676 # of python_foreach_impl calls (e.g. for shared processes like doc
677 # building). python_foreach_impl sets up the build environment itself.
678 #
679 # Pure mode example:
680 # @CODE
681 # DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
682 # REQUIRED_USE="doc? ( $(python_gen_useflags 'python2*') )"
683 #
684 # src_compile() {
685 #   #...
686 #   if use doc; then
687 #     python_setup 'python2*'
688 #     make doc
689 #   fi
690 # }
691 # @CODE
692 #
693 # Any-of mode example:
694 # @CODE
695 # DEPEND="doc? (
696 #       $(python_gen_any_dep 'dev-python/epydoc[${PYTHON_USEDEP}]' 'python2*') )"
697 #
698 # python_check_deps() {
699 #       has_version "dev-python/epydoc[${PYTHON_USEDEP}]"
700 # }
701 #
702 # src_compile() {
703 #   #...
704 #   if use doc; then
705 #     python_setup 'python2*'
706 #     make doc
707 #   fi
708 # }
709 # @CODE
710 python_setup() {
711         debug-print-function ${FUNCNAME} "${@}"
712
713         _python_validate_useflags
714         local pycompat=( "${PYTHON_COMPAT[@]}" )
715         if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
716                 pycompat=( ${PYTHON_COMPAT_OVERRIDE} )
717         fi
718
719         local has_check_deps
720         declare -f python_check_deps >/dev/null && has_check_deps=1
721
722         # (reverse iteration -- newest impl first)
723         local found
724         for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
725                 local impl=${_PYTHON_SUPPORTED_IMPLS[i]}
726
727                 # check PYTHON_COMPAT[_OVERRIDE]
728                 has "${impl}" "${pycompat[@]}" || continue
729
730                 # match USE flags only if override is not in effect
731                 # and python_check_deps() is not defined
732                 if [[ ! ${PYTHON_COMPAT_OVERRIDE} && ! ${has_check_deps} ]]; then
733                         use "python_targets_${impl}" || continue
734                 fi
735
736                 # check patterns
737                 _python_impl_matches "${impl}" "${@-*}" || continue
738
739                 python_export "${impl}" EPYTHON PYTHON
740
741                 # if python_check_deps() is declared, switch into any-of mode
742                 if [[ ${has_check_deps} ]]; then
743                         # first check if the interpreter is installed
744                         python_is_installed "${impl}" || continue
745                         # then run python_check_deps
746                         local PYTHON_USEDEP="python_targets_${impl}(-),python_single_target_${impl}(+)"
747                         python_check_deps || continue
748                 fi
749
750                 found=1
751                 break
752         done
753
754         if [[ ! ${found} ]]; then
755                 eerror "${FUNCNAME}: none of the enabled implementation matched the patterns."
756                 eerror "  patterns: ${@-'(*)'}"
757                 eerror "Likely a REQUIRED_USE constraint (possibly USE-conditional) is missing."
758                 eerror "  suggested: || ( \$(python_gen_useflags ${@}) )"
759                 eerror "(remember to quote all the patterns with '')"
760                 die "${FUNCNAME}: no enabled implementation satisfy requirements"
761         fi
762
763         python_wrapper_setup
764 }
765
766 # @FUNCTION: python_export_best
767 # @USAGE: [<variable>...]
768 # @DESCRIPTION:
769 # Find the best (most preferred) Python implementation enabled
770 # and export given variables for it. If no variables are provided,
771 # EPYTHON & PYTHON will be exported.
772 python_export_best() {
773         debug-print-function ${FUNCNAME} "${@}"
774
775         [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI ${EAPI}"
776
777         eqawarn "python_export_best() is deprecated. Please use python_setup instead,"
778         eqawarn "combined with python_export if necessary."
779
780         [[ ${#} -gt 0 ]] || set -- EPYTHON PYTHON
781
782         local best MULTIBUILD_VARIANTS
783         _python_obtain_impls
784
785         _python_set_best() {
786                 best=${MULTIBUILD_VARIANT}
787         }
788         multibuild_for_best_variant _python_set_best
789         unset -f _python_set_best
790
791         debug-print "${FUNCNAME}: Best implementation is: ${best}"
792         python_export "${best}" "${@}"
793         python_wrapper_setup
794 }
795
796 # @FUNCTION: python_replicate_script
797 # @USAGE: <path>...
798 # @DESCRIPTION:
799 # Copy the given script to variants for all enabled Python
800 # implementations, then replace it with a symlink to the wrapper.
801 #
802 # All specified files must start with a 'python' shebang. A file not
803 # having a matching shebang will be refused.
804 python_replicate_script() {
805         debug-print-function ${FUNCNAME} "${@}"
806
807         _python_replicate_script() {
808                 local _PYTHON_FIX_SHEBANG_QUIET=1
809
810                 local PYTHON_SCRIPTDIR
811                 python_export PYTHON_SCRIPTDIR
812
813                 (
814                         exeopts -m 0755
815                         exeinto "${PYTHON_SCRIPTDIR#${EPREFIX}}"
816                         doexe "${files[@]}"
817                 )
818
819                 python_fix_shebang -q \
820                         "${files[@]/*\//${D%/}/${PYTHON_SCRIPTDIR}/}"
821         }
822
823         local files=( "${@}" )
824         python_foreach_impl _python_replicate_script
825         unset -f _python_replicate_script
826
827         # install the wrappers
828         local f
829         for f; do
830                 _python_ln_rel "${ED%/}/usr/lib/python-exec/python-exec2" "${f}" || die
831         done
832 }
833
834 _PYTHON_R1=1
835 fi