Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: python@g.o, "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH v2 01/20] eclass: Copy python-r1 suite to python-r2
Date: Thu, 05 Mar 2020 15:11:29
Message-Id: 20200305151024.125834-2-mgorny@gentoo.org
In Reply to: [gentoo-dev] [PATCH v2 00/20] python-r2 suite by "Michał Górny"
1 Signed-off-by: Michał Górny <mgorny@g.o>
2 ---
3 eclass/distutils-r2.eclass | 1188 ++++++++++++++++++++++++
4 eclass/python-any-r2.eclass | 364 ++++++++
5 eclass/python-r2.eclass | 829 +++++++++++++++++
6 eclass/python-single-r2.eclass | 512 +++++++++++
7 eclass/python-utils-r2.eclass | 1508 +++++++++++++++++++++++++++++++
8 eclass/tests/distutils-r2.sh | 98 ++
9 eclass/tests/python-utils-r2.sh | 237 +++++
10 7 files changed, 4736 insertions(+)
11 create mode 100644 eclass/distutils-r2.eclass
12 create mode 100644 eclass/python-any-r2.eclass
13 create mode 100644 eclass/python-r2.eclass
14 create mode 100644 eclass/python-single-r2.eclass
15 create mode 100644 eclass/python-utils-r2.eclass
16 create mode 100755 eclass/tests/distutils-r2.sh
17 create mode 100755 eclass/tests/python-utils-r2.sh
18
19 diff --git a/eclass/distutils-r2.eclass b/eclass/distutils-r2.eclass
20 new file mode 100644
21 index 000000000000..559ca2b72c1c
22 --- /dev/null
23 +++ b/eclass/distutils-r2.eclass
24 @@ -0,0 +1,1188 @@
25 +# Copyright 1999-2020 Gentoo Authors
26 +# Distributed under the terms of the GNU General Public License v2
27 +
28 +# @ECLASS: distutils-r2.eclass
29 +# @MAINTAINER:
30 +# Python team <python@g.o>
31 +# @AUTHOR:
32 +# Author: Michał Górny <mgorny@g.o>
33 +# @SUPPORTED_EAPIS: 5 6 7
34 +# @BLURB: A simple eclass to build Python packages using distutils.
35 +# @DESCRIPTION:
36 +# A simple eclass providing functions to build Python packages using
37 +# the distutils build system. It exports phase functions for all
38 +# the src_* phases. Each of the phases runs two pseudo-phases:
39 +# python_..._all() (e.g. python_prepare_all()) once in ${S}, then
40 +# python_...() (e.g. python_prepare()) for each implementation
41 +# (see: python_foreach_impl() in python-r2).
42 +#
43 +# In distutils-r2_src_prepare(), the 'all' function is run before
44 +# per-implementation ones (because it creates the implementations),
45 +# per-implementation functions are run in a random order.
46 +#
47 +# In remaining phase functions, the per-implementation functions are run
48 +# before the 'all' one, and they are ordered from the least to the most
49 +# preferred implementation (so that 'better' files overwrite 'worse'
50 +# ones).
51 +#
52 +# If the ebuild doesn't specify a particular pseudo-phase function,
53 +# the default one will be used (distutils-r2_...). Defaults are provided
54 +# for all per-implementation pseudo-phases, python_prepare_all()
55 +# and python_install_all(); whenever writing your own pseudo-phase
56 +# functions, you should consider calling the defaults (and especially
57 +# distutils-r2_python_prepare_all).
58 +#
59 +# Please note that distutils-r2 sets RDEPEND and DEPEND unconditionally
60 +# for you.
61 +#
62 +# Also, please note that distutils-r2 will always inherit python-r2
63 +# as well. Thus, all the variables defined and documented there are
64 +# relevant to the packages using distutils-r2.
65 +#
66 +# For more information, please see the Python Guide:
67 +# https://dev.gentoo.org/~mgorny/python-guide/
68 +
69 +case "${EAPI:-0}" in
70 + 0|1|2|3|4)
71 + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
72 + ;;
73 + 5|6|7)
74 + ;;
75 + *)
76 + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
77 + ;;
78 +esac
79 +
80 +# @ECLASS-VARIABLE: DISTUTILS_OPTIONAL
81 +# @DEFAULT_UNSET
82 +# @DESCRIPTION:
83 +# If set to a non-null value, distutils part in the ebuild will
84 +# be considered optional. No dependencies will be added and no phase
85 +# functions will be exported.
86 +#
87 +# If you enable DISTUTILS_OPTIONAL, you have to set proper dependencies
88 +# for your package (using ${PYTHON_DEPS}) and to either call
89 +# distutils-r2 default phase functions or call the build system
90 +# manually.
91 +
92 +# @ECLASS-VARIABLE: DISTUTILS_SINGLE_IMPL
93 +# @DEFAULT_UNSET
94 +# @DESCRIPTION:
95 +# If set to a non-null value, the ebuild will support setting a single
96 +# Python implementation only. It will effectively replace the python-r2
97 +# eclass inherit with python-single-r2.
98 +#
99 +# Note that inheriting python-single-r2 will cause pkg_setup()
100 +# to be exported. It must be run in order for the eclass functions
101 +# to function properly.
102 +
103 +# @ECLASS-VARIABLE: DISTUTILS_USE_SETUPTOOLS
104 +# @PRE_INHERIT
105 +# @DESCRIPTION:
106 +# Controls adding dev-python/setuptools dependency. The allowed values
107 +# are:
108 +#
109 +# - no -- do not add the dependency (pure distutils package)
110 +# - bdepend -- add it to BDEPEND (the default)
111 +# - rdepend -- add it to BDEPEND+RDEPEND (when using entry_points)
112 +# - pyproject.toml -- use pyproject2setuptools to install a project
113 +# using pyproject.toml (flit, poetry...)
114 +# - manual -- do not add the depedency and suppress the checks
115 +# (assumes you will take care of doing it correctly)
116 +#
117 +# This variable is effective only if DISTUTILS_OPTIONAL is disabled.
118 +# It needs to be set before the inherit line.
119 +: ${DISTUTILS_USE_SETUPTOOLS:=bdepend}
120 +
121 +if [[ ! ${_DISTUTILS_R2} ]]; then
122 +
123 +[[ ${EAPI} == [456] ]] && inherit eutils
124 +[[ ${EAPI} == [56] ]] && inherit xdg-utils
125 +inherit multiprocessing toolchain-funcs
126 +
127 +if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
128 + inherit python-r2
129 +else
130 + inherit python-single-r2
131 +fi
132 +
133 +fi
134 +
135 +if [[ ! ${DISTUTILS_OPTIONAL} ]]; then
136 + EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
137 +fi
138 +
139 +if [[ ! ${_DISTUTILS_R2} ]]; then
140 +
141 +_distutils_set_globals() {
142 + local rdep=${PYTHON_DEPS}
143 + local bdep=${rdep}
144 +
145 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
146 + local sdep="dev-python/setuptools[${PYTHON_USEDEP}]"
147 + else
148 + local sdep="$(python_gen_cond_dep '
149 + dev-python/setuptools[${PYTHON_MULTI_USEDEP}]
150 + ')"
151 + fi
152 +
153 + case ${DISTUTILS_USE_SETUPTOOLS} in
154 + no|manual)
155 + ;;
156 + bdepend)
157 + bdep+=" ${sdep}"
158 + ;;
159 + rdepend)
160 + bdep+=" ${sdep}"
161 + rdep+=" ${sdep}"
162 + ;;
163 + pyproject.toml)
164 + bdep+=" dev-python/pyproject2setuppy[${PYTHON_USEDEP}]"
165 + ;;
166 + *)
167 + die "Invalid DISTUTILS_USE_SETUPTOOLS=${DISTUTILS_USE_SETUPTOOLS}"
168 + ;;
169 + esac
170 +
171 + RDEPEND=${rdep}
172 + if [[ ${EAPI} != [56] ]]; then
173 + BDEPEND=${bdep}
174 + else
175 + DEPEND=${bdep}
176 + fi
177 + REQUIRED_USE=${PYTHON_REQUIRED_USE}
178 +}
179 +[[ ! ${DISTUTILS_OPTIONAL} ]] && _distutils_set_globals
180 +unset -f _distutils_set_globals
181 +
182 +# @ECLASS-VARIABLE: PATCHES
183 +# @DEFAULT_UNSET
184 +# @DESCRIPTION:
185 +# An array containing patches to be applied to the sources before
186 +# copying them.
187 +#
188 +# If unset, no custom patches will be applied.
189 +#
190 +# Please note, however, that at some point the eclass may apply
191 +# additional distutils patches/quirks independently of this variable.
192 +#
193 +# Example:
194 +# @CODE
195 +# PATCHES=( "${FILESDIR}"/${P}-make-gentoo-happy.patch )
196 +# @CODE
197 +
198 +# @ECLASS-VARIABLE: DOCS
199 +# @DEFAULT_UNSET
200 +# @DESCRIPTION:
201 +# An array containing documents installed using dodoc. The files listed
202 +# there must exist in the directory from which
203 +# distutils-r2_python_install_all() is run (${S} by default).
204 +#
205 +# If unset, the function will instead look up files matching default
206 +# filename pattern list (from the Package Manager Specification),
207 +# and install those found.
208 +#
209 +# Example:
210 +# @CODE
211 +# DOCS=( NEWS README )
212 +# @CODE
213 +
214 +# @ECLASS-VARIABLE: HTML_DOCS
215 +# @DEFAULT_UNSET
216 +# @DESCRIPTION:
217 +# An array containing documents installed using dohtml. The files
218 +# and directories listed there must exist in the directory from which
219 +# distutils-r2_python_install_all() is run (${S} by default).
220 +#
221 +# If unset, no HTML docs will be installed.
222 +#
223 +# Example:
224 +# @CODE
225 +# HTML_DOCS=( doc/html/. )
226 +# @CODE
227 +
228 +# @ECLASS-VARIABLE: EXAMPLES
229 +# @DEFAULT_UNSET
230 +# @DESCRIPTION:
231 +# OBSOLETE: this variable is deprecated and banned in EAPI 6
232 +#
233 +# An array containing examples installed into 'examples' doc
234 +# subdirectory. The files and directories listed there must exist
235 +# in the directory from which distutils-r2_python_install_all() is run
236 +# (${S} by default).
237 +#
238 +# The 'examples' subdirectory will be marked not to be compressed
239 +# automatically.
240 +#
241 +# If unset, no examples will be installed.
242 +#
243 +# Example:
244 +# @CODE
245 +# EXAMPLES=( examples/. demos/. )
246 +# @CODE
247 +
248 +# @ECLASS-VARIABLE: DISTUTILS_IN_SOURCE_BUILD
249 +# @DEFAULT_UNSET
250 +# @DESCRIPTION:
251 +# If set to a non-null value, in-source builds will be enabled.
252 +# If unset, the default is to use in-source builds when python_prepare()
253 +# is declared, and out-of-source builds otherwise.
254 +#
255 +# If in-source builds are used, the eclass will create a copy of package
256 +# sources for each Python implementation in python_prepare_all(),
257 +# and work on that copy afterwards.
258 +#
259 +# If out-of-source builds are used, the eclass will instead work
260 +# on the sources directly, prepending setup.py arguments with
261 +# 'build --build-base ${BUILD_DIR}' to enforce keeping & using built
262 +# files in the specific root.
263 +
264 +# @ECLASS-VARIABLE: DISTUTILS_ALL_SUBPHASE_IMPLS
265 +# @DEFAULT_UNSET
266 +# @DESCRIPTION:
267 +# An array of patterns specifying which implementations can be used
268 +# for *_all() sub-phase functions. If undefined, defaults to '*'
269 +# (allowing any implementation). If multiple values are specified,
270 +# implementations matching any of the patterns will be accepted.
271 +#
272 +# The patterns can be either fnmatch-style patterns (matched via bash
273 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
274 +# appropriately all enabled Python 2/3 implementations (alike
275 +# python_is_python3). Remember to escape or quote the fnmatch patterns
276 +# to prevent accidental shell filename expansion.
277 +#
278 +# If the restriction needs to apply conditionally to a USE flag,
279 +# the variable should be set conditionally as well (e.g. in an early
280 +# phase function or other convenient location).
281 +#
282 +# Please remember to add a matching || block to REQUIRED_USE,
283 +# to ensure that at least one implementation matching the patterns will
284 +# be enabled.
285 +#
286 +# Example:
287 +# @CODE
288 +# REQUIRED_USE="doc? ( || ( $(python_gen_useflags 'python2*') ) )"
289 +#
290 +# pkg_setup() {
291 +# use doc && DISTUTILS_ALL_SUBPHASE_IMPLS=( 'python2*' )
292 +# }
293 +# @CODE
294 +
295 +# @ECLASS-VARIABLE: mydistutilsargs
296 +# @DEFAULT_UNSET
297 +# @DESCRIPTION:
298 +# An array containing options to be passed to setup.py.
299 +#
300 +# Example:
301 +# @CODE
302 +# python_configure_all() {
303 +# mydistutilsargs=( --enable-my-hidden-option )
304 +# }
305 +# @CODE
306 +
307 +# @FUNCTION: distutils_enable_sphinx
308 +# @USAGE: <subdir> [--no-autodoc | <plugin-pkgs>...]
309 +# @DESCRIPTION:
310 +# Set up IUSE, BDEPEND, python_check_deps() and python_compile_all() for
311 +# building HTML docs via dev-python/sphinx. python_compile_all() will
312 +# append to HTML_DOCS if docs are enabled.
313 +#
314 +# This helper is meant for the most common case, that is a single Sphinx
315 +# subdirectory with standard layout, building and installing HTML docs
316 +# behind USE=doc. It assumes it's the only consumer of the three
317 +# aforementioned functions. If you need to use a custom implemention,
318 +# you can't use it.
319 +#
320 +# If your package uses additional Sphinx plugins, they should be passed
321 +# (without PYTHON_USEDEP) as <plugin-pkgs>. The function will take care
322 +# of setting appropriate any-of dep and python_check_deps().
323 +#
324 +# If no plugin packages are specified, the eclass will still utilize
325 +# any-r2 API to support autodoc (documenting source code).
326 +# If the package uses neither autodoc nor additional plugins, you should
327 +# pass --no-autodoc to disable this API and simplify the resulting code.
328 +#
329 +# This function must be called in global scope. Take care not to
330 +# overwrite the variables set by it. If you need to extend
331 +# python_compile_all(), you can call the original implementation
332 +# as sphinx_compile_all.
333 +distutils_enable_sphinx() {
334 + debug-print-function ${FUNCNAME} "${@}"
335 + [[ ${#} -ge 1 ]] || die "${FUNCNAME} takes at least one arg: <subdir>"
336 +
337 + _DISTUTILS_SPHINX_SUBDIR=${1}
338 + shift
339 + _DISTUTILS_SPHINX_PLUGINS=( "${@}" )
340 +
341 + local deps autodoc=1 d
342 + for d; do
343 + if [[ ${d} == --no-autodoc ]]; then
344 + autodoc=
345 + else
346 + deps+="
347 + ${d}[\${PYTHON_USEDEP}]"
348 + fi
349 + done
350 +
351 + if [[ ! ${autodoc} && -n ${deps} ]]; then
352 + die "${FUNCNAME}: do not pass --no-autodoc if external plugins are used"
353 + fi
354 + if [[ ${autodoc} ]]; then
355 + deps="$(python_gen_any_dep "
356 + dev-python/sphinx[\${PYTHON_USEDEP}]
357 + ${deps}")"
358 +
359 + python_check_deps() {
360 + use doc || return 0
361 + local p
362 + for p in dev-python/sphinx "${_DISTUTILS_SPHINX_PLUGINS[@]}"; do
363 + has_version "${p}[${PYTHON_USEDEP}]" || return 1
364 + done
365 + }
366 + else
367 + deps="dev-python/sphinx"
368 + fi
369 +
370 + sphinx_compile_all() {
371 + use doc || return
372 +
373 + local confpy=${_DISTUTILS_SPHINX_SUBDIR}/conf.py
374 + [[ -f ${confpy} ]] ||
375 + die "${confpy} not found, distutils_enable_sphinx call wrong"
376 +
377 + if [[ ${_DISTUTILS_SPHINX_PLUGINS[0]} == --no-autodoc ]]; then
378 + if grep -F -q 'sphinx.ext.autodoc' "${confpy}"; then
379 + die "distutils_enable_sphinx: --no-autodoc passed but sphinx.ext.autodoc found in ${confpy}"
380 + fi
381 + else
382 + if ! grep -F -q 'sphinx.ext.autodoc' "${confpy}"; then
383 + die "distutils_enable_sphinx: sphinx.ext.autodoc not found in ${confpy}, pass --no-autodoc"
384 + fi
385 + fi
386 +
387 + build_sphinx "${_DISTUTILS_SPHINX_SUBDIR}"
388 + }
389 + python_compile_all() { sphinx_compile_all; }
390 +
391 + IUSE+=" doc"
392 + if [[ ${EAPI} == [56] ]]; then
393 + DEPEND+=" doc? ( ${deps} )"
394 + else
395 + BDEPEND+=" doc? ( ${deps} )"
396 + fi
397 +
398 + # we need to ensure successful return in case we're called last,
399 + # otherwise Portage may wrongly assume sourcing failed
400 + return 0
401 +}
402 +
403 +# @FUNCTION: distutils_enable_tests
404 +# @USAGE: <test-runner>
405 +# @DESCRIPTION:
406 +# Set up IUSE, RESTRICT, BDEPEND and python_test() for running tests
407 +# with the specified test runner. Also copies the current value
408 +# of RDEPEND to test?-BDEPEND. The test-runner argument must be one of:
409 +#
410 +# - nose: nosetests (dev-python/nose)
411 +# - pytest: dev-python/pytest
412 +# - setup.py: setup.py test (no deps included)
413 +# - unittest: for built-in Python unittest module
414 +#
415 +# This function is meant as a helper for common use cases, and it only
416 +# takes care of basic setup. You still need to list additional test
417 +# dependencies manually. If you have uncommon use case, you should
418 +# not use it and instead enable tests manually.
419 +#
420 +# This function must be called in global scope, after RDEPEND has been
421 +# declared. Take care not to overwrite the variables set by it.
422 +distutils_enable_tests() {
423 + debug-print-function ${FUNCNAME} "${@}"
424 + [[ ${#} -eq 1 ]] || die "${FUNCNAME} takes exactly one argument: test-runner"
425 +
426 + local test_pkg
427 + case ${1} in
428 + nose)
429 + test_pkg="dev-python/nose"
430 + python_test() {
431 + nosetests -v || die "Tests fail with ${EPYTHON}"
432 + }
433 + ;;
434 + pytest)
435 + test_pkg="dev-python/pytest"
436 + python_test() {
437 + pytest -vv || die "Tests fail with ${EPYTHON}"
438 + }
439 + ;;
440 + setup.py)
441 + python_test() {
442 + esetup.py test --verbose
443 + }
444 + ;;
445 + unittest)
446 + python_test() {
447 + "${EPYTHON}" -m unittest discover -v ||
448 + die "Tests fail with ${EPYTHON}"
449 + }
450 + ;;
451 + *)
452 + die "${FUNCNAME}: unsupported argument: ${1}"
453 + esac
454 +
455 + local test_deps=${RDEPEND}
456 + if [[ -n ${test_pkg} ]]; then
457 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
458 + test_deps+=" ${test_pkg}[${PYTHON_USEDEP}]"
459 + else
460 + test_deps+=" $(python_gen_cond_dep "
461 + ${test_pkg}[\${PYTHON_MULTI_USEDEP}]
462 + ")"
463 + fi
464 + fi
465 + if [[ -n ${test_deps} ]]; then
466 + IUSE+=" test"
467 + RESTRICT+=" !test? ( test )"
468 + if [[ ${EAPI} == [56] ]]; then
469 + DEPEND+=" test? ( ${test_deps} )"
470 + else
471 + BDEPEND+=" test? ( ${test_deps} )"
472 + fi
473 + fi
474 +
475 + # we need to ensure successful return in case we're called last,
476 + # otherwise Portage may wrongly assume sourcing failed
477 + return 0
478 +}
479 +
480 +# @FUNCTION: _distutils-r2_verify_use_setuptools
481 +# @INTERNAL
482 +# @DESCRIPTION:
483 +# Check setup.py for signs that DISTUTILS_USE_SETUPTOOLS have been set
484 +# incorrectly.
485 +_distutils_verify_use_setuptools() {
486 + [[ ${DISTUTILS_OPTIONAL} ]] && return
487 + [[ ${DISTUTILS_USE_SETUPTOOLS} == manual ]] && return
488 + [[ ${DISTUTILS_USE_SETUPTOOLS} == pyproject.toml ]] && return
489 +
490 + # ok, those are cheap greps. we can try toimprove them if we hit
491 + # false positives.
492 + local expected=no
493 + if [[ ${CATEGORY}/${PN} == dev-python/setuptools ]]; then
494 + # as a special case, setuptools provides itself ;-)
495 + :
496 + elif grep -E -q -s '(from|import)\s+setuptools' setup.py; then
497 + if grep -E -q -s 'entry_points\s*=' setup.py; then
498 + expected=rdepend
499 + elif grep -F -q -s '[options.entry_points]' setup.cfg; then
500 + expected=rdepend
501 + else
502 + expected=bdepend
503 + fi
504 + fi
505 +
506 + if [[ ${DISTUTILS_USE_SETUPTOOLS} != ${expected} ]]; then
507 + if [[ ! ${_DISTUTILS_SETUPTOOLS_WARNED} ]]; then
508 + _DISTUTILS_SETUPTOOLS_WARNED=1
509 + local def=
510 + [[ ${DISTUTILS_USE_SETUPTOOLS} == bdepend ]] && def=' (default?)'
511 +
512 + eqawarn "DISTUTILS_USE_SETUPTOOLS value is probably incorrect"
513 + eqawarn " value: DISTUTILS_USE_SETUPTOOLS=${DISTUTILS_USE_SETUPTOOLS}${def}"
514 + eqawarn " expected: DISTUTILS_USE_SETUPTOOLS=${expected}"
515 + fi
516 + fi
517 +}
518 +
519 +# @FUNCTION: esetup.py
520 +# @USAGE: [<args>...]
521 +# @DESCRIPTION:
522 +# Run setup.py using currently selected Python interpreter
523 +# (if ${EPYTHON} is set; fallback 'python' otherwise).
524 +#
525 +# setup.py will be passed the following, in order:
526 +# 1. ${mydistutilsargs[@]}
527 +# 2. additional arguments passed to the esetup.py function.
528 +#
529 +# Please note that setup.py will respect defaults (unless overridden
530 +# via command-line options) from setup.cfg that is created
531 +# in distutils-r2_python_compile and in distutils-r2_python_install.
532 +#
533 +# This command dies on failure.
534 +esetup.py() {
535 + debug-print-function ${FUNCNAME} "${@}"
536 +
537 + local die_args=()
538 + [[ ${EAPI} != [45] ]] && die_args+=( -n )
539 +
540 + [[ ${BUILD_DIR} ]] && _distutils-r2_create_setup_cfg
541 + _distutils_verify_use_setuptools
542 +
543 + set -- "${EPYTHON:-python}" setup.py "${mydistutilsargs[@]}" "${@}"
544 +
545 + echo "${@}" >&2
546 + "${@}" || die "${die_args[@]}"
547 + local ret=${?}
548 +
549 + if [[ ${BUILD_DIR} ]]; then
550 + rm "${HOME}"/.pydistutils.cfg || die "${die_args[@]}"
551 + fi
552 +
553 + return ${ret}
554 +}
555 +
556 +# @FUNCTION: distutils_install_for_testing
557 +# @USAGE: [<args>...]
558 +# @DESCRIPTION:
559 +# Install the package into a temporary location for running tests.
560 +# Update PYTHONPATH appropriately and set TEST_DIR to the test
561 +# installation root. The Python packages will be installed in 'lib'
562 +# subdir, and scripts in 'scripts' subdir (like in BUILD_DIR).
563 +#
564 +# Please note that this function should be only used if package uses
565 +# namespaces (and therefore proper install needs to be done to enforce
566 +# PYTHONPATH) or tests rely on the results of install command.
567 +# For most of the packages, tests built in BUILD_DIR are good enough.
568 +distutils_install_for_testing() {
569 + debug-print-function ${FUNCNAME} "${@}"
570 +
571 + # A few notes:
572 + # 1) because of namespaces, we can't use 'install --root',
573 + # 2) 'install --home' is terribly broken on pypy, so we need
574 + # to override --install-lib and --install-scripts,
575 + # 3) non-root 'install' complains about PYTHONPATH and missing dirs,
576 + # so we need to set it properly and mkdir them,
577 + # 4) it runs a bunch of commands which write random files to cwd,
578 + # in order to avoid that, we add the necessary path overrides
579 + # in _distutils-r2_create_setup_cfg.
580 +
581 + TEST_DIR=${BUILD_DIR}/test
582 + local bindir=${TEST_DIR}/scripts
583 + local libdir=${TEST_DIR}/lib
584 + PYTHONPATH=${libdir}:${PYTHONPATH}
585 +
586 + local add_args=(
587 + install
588 + --home="${TEST_DIR}"
589 + --install-lib="${libdir}"
590 + --install-scripts="${bindir}"
591 + )
592 +
593 + mkdir -p "${libdir}" || die
594 + esetup.py "${add_args[@]}" "${@}"
595 +}
596 +
597 +# @FUNCTION: _distutils-r2_disable_ez_setup
598 +# @INTERNAL
599 +# @DESCRIPTION:
600 +# Stub out ez_setup.py and distribute_setup.py to prevent packages
601 +# from trying to download a local copy of setuptools.
602 +_distutils-r2_disable_ez_setup() {
603 + local stub="def use_setuptools(*args, **kwargs): pass"
604 + if [[ -f ez_setup.py ]]; then
605 + echo "${stub}" > ez_setup.py || die
606 + fi
607 + if [[ -f distribute_setup.py ]]; then
608 + echo "${stub}" > distribute_setup.py || die
609 + fi
610 +}
611 +
612 +# @FUNCTION: _distutils-r2_handle_pyproject_toml
613 +# @INTERNAL
614 +# @DESCRIPTION:
615 +# Generate setup.py for pyproject.toml if requested.
616 +_distutils-r2_handle_pyproject_toml() {
617 + if [[ ! -f setup.py && -f pyproject.toml ]]; then
618 + if [[ ${DISTUTILS_USE_SETUPTOOLS} == pyproject.toml ]]; then
619 + cat > setup.py <<-EOF || die
620 + #!/usr/bin/env python
621 + from pyproject2setuppy.main import main
622 + main()
623 + EOF
624 + chmod +x setup.py || die
625 + else
626 + eerror "No setup.py found but pyproject.toml is present. In order to enable"
627 + eerror "pyproject.toml support in distutils-r2, set:"
628 + eerror " DISTUTILS_USE_SETUPTOOLS=pyproject.toml"
629 + die "No setup.py found and DISTUTILS_USE_SETUPTOOLS!=pyproject.toml"
630 + fi
631 + fi
632 +}
633 +
634 +# @FUNCTION: distutils-r2_python_prepare_all
635 +# @DESCRIPTION:
636 +# The default python_prepare_all(). It applies the patches from PATCHES
637 +# array, then user patches and finally calls python_copy_sources to
638 +# create copies of resulting sources for each Python implementation.
639 +#
640 +# At some point in the future, it may also apply eclass-specific
641 +# distutils patches and/or quirks.
642 +distutils-r2_python_prepare_all() {
643 + debug-print-function ${FUNCNAME} "${@}"
644 +
645 + if [[ ! ${DISTUTILS_OPTIONAL} ]]; then
646 + if [[ ${EAPI} != [45] ]]; then
647 + default
648 + else
649 + [[ ${PATCHES} ]] && epatch "${PATCHES[@]}"
650 + epatch_user
651 + fi
652 + fi
653 +
654 + # by default, use in-source build if python_prepare() is used
655 + if [[ ! ${DISTUTILS_IN_SOURCE_BUILD+1} ]]; then
656 + if declare -f python_prepare >/dev/null; then
657 + DISTUTILS_IN_SOURCE_BUILD=1
658 + fi
659 + fi
660 +
661 + _distutils-r2_disable_ez_setup
662 + _distutils-r2_handle_pyproject_toml
663 +
664 + if [[ ${DISTUTILS_IN_SOURCE_BUILD} && ! ${DISTUTILS_SINGLE_IMPL} ]]
665 + then
666 + # create source copies for each implementation
667 + python_copy_sources
668 + fi
669 +
670 + _DISTUTILS_DEFAULT_CALLED=1
671 +}
672 +
673 +# @FUNCTION: distutils-r2_python_prepare
674 +# @DESCRIPTION:
675 +# The default python_prepare(). A no-op.
676 +distutils-r2_python_prepare() {
677 + debug-print-function ${FUNCNAME} "${@}"
678 +
679 + [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI 6 (it was a no-op)"
680 +}
681 +
682 +# @FUNCTION: distutils-r2_python_configure
683 +# @DESCRIPTION:
684 +# The default python_configure(). A no-op.
685 +distutils-r2_python_configure() {
686 + debug-print-function ${FUNCNAME} "${@}"
687 +
688 + [[ ${EAPI} == [45] ]] || die "${FUNCNAME} is banned in EAPI 6 (it was a no-op)"
689 +}
690 +
691 +# @FUNCTION: _distutils-r2_create_setup_cfg
692 +# @INTERNAL
693 +# @DESCRIPTION:
694 +# Create implementation-specific configuration file for distutils,
695 +# setting proper build-dir (and install-dir) paths.
696 +_distutils-r2_create_setup_cfg() {
697 + cat > "${HOME}"/.pydistutils.cfg <<-_EOF_ || die
698 + [build]
699 + build-base = ${BUILD_DIR}
700 +
701 + # using a single directory for them helps us export
702 + # ${PYTHONPATH} and ebuilds find the sources independently
703 + # of whether the package installs extensions or not
704 + #
705 + # note: due to some packages (wxpython) relying on separate
706 + # platlib & purelib dirs, we do not set --build-lib (which
707 + # can not be overridden with --build-*lib)
708 + build-platlib = %(build-base)s/lib
709 + build-purelib = %(build-base)s/lib
710 +
711 + # make the ebuild writer lives easier
712 + build-scripts = %(build-base)s/scripts
713 +
714 + # this is needed by distutils_install_for_testing since
715 + # setuptools like to create .egg files for install --home.
716 + [bdist_egg]
717 + dist-dir = ${BUILD_DIR}/dist
718 + _EOF_
719 +
720 + # we can't refer to ${D} before src_install()
721 + if [[ ${EBUILD_PHASE} == install ]]; then
722 + cat >> "${HOME}"/.pydistutils.cfg <<-_EOF_ || die
723 +
724 + # installation paths -- allow calling extra install targets
725 + # without the default 'install'
726 + [install]
727 + compile = True
728 + optimize = 2
729 + root = ${D%/}
730 + _EOF_
731 +
732 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
733 + cat >> "${HOME}"/.pydistutils.cfg <<-_EOF_ || die
734 + install-scripts = $(python_get_scriptdir)
735 + _EOF_
736 + fi
737 + fi
738 +}
739 +
740 +# @FUNCTION: _distutils-r2_copy_egg_info
741 +# @INTERNAL
742 +# @DESCRIPTION:
743 +# Copy egg-info files to the ${BUILD_DIR} (that's going to become
744 +# egg-base in esetup.py). This way, we respect whatever's in upstream
745 +# egg-info.
746 +_distutils-r2_copy_egg_info() {
747 + mkdir -p "${BUILD_DIR}" || die
748 + # stupid freebsd can't do 'cp -t ${BUILD_DIR} {} +'
749 + find -name '*.egg-info' -type d -exec cp -R -p {} "${BUILD_DIR}"/ ';' || die
750 +}
751 +
752 +# @FUNCTION: distutils-r2_python_compile
753 +# @USAGE: [additional-args...]
754 +# @DESCRIPTION:
755 +# The default python_compile(). Runs 'esetup.py build'. Any parameters
756 +# passed to this function will be appended to setup.py invocation,
757 +# i.e. passed as options to the 'build' command.
758 +#
759 +# This phase also sets up initial setup.cfg with build directories
760 +# and copies upstream egg-info files if supplied.
761 +distutils-r2_python_compile() {
762 + debug-print-function ${FUNCNAME} "${@}"
763 +
764 + _distutils-r2_copy_egg_info
765 +
766 + local build_args=()
767 + # distutils is parallel-capable since py3.5
768 + # to avoid breaking stable ebuilds, enable it only if either:
769 + # a. we're dealing with EAPI 7
770 + # b. we're dealing with Python 3.7 or PyPy3
771 + if python_is_python3 && [[ ${EPYTHON} != python3.4 ]]; then
772 + if [[ ${EAPI} != [56] || ${EPYTHON} != python3.[56] ]]; then
773 + local jobs=$(makeopts_jobs "${MAKEOPTS}" INF)
774 + if [[ ${jobs} == INF ]]; then
775 + local nproc=$(get_nproc)
776 + jobs=$(( nproc + 1 ))
777 + fi
778 + build_args+=( -j "${jobs}" )
779 + fi
780 + fi
781 +
782 + esetup.py build "${build_args[@]}" "${@}"
783 +}
784 +
785 +# @FUNCTION: _distutils-r2_wrap_scripts
786 +# @USAGE: <path> <bindir>
787 +# @INTERNAL
788 +# @DESCRIPTION:
789 +# Moves and wraps all installed scripts/executables as necessary.
790 +_distutils-r2_wrap_scripts() {
791 + debug-print-function ${FUNCNAME} "${@}"
792 +
793 + [[ ${#} -eq 2 ]] || die "usage: ${FUNCNAME} <path> <bindir>"
794 + local path=${1}
795 + local bindir=${2}
796 +
797 + local PYTHON_SCRIPTDIR
798 + python_export PYTHON_SCRIPTDIR
799 +
800 + local f python_files=() non_python_files=()
801 +
802 + if [[ -d ${path}${PYTHON_SCRIPTDIR} ]]; then
803 + for f in "${path}${PYTHON_SCRIPTDIR}"/*; do
804 + [[ -d ${f} ]] && die "Unexpected directory: ${f}"
805 + debug-print "${FUNCNAME}: found executable at ${f#${path}/}"
806 +
807 + local shebang
808 + read -r shebang < "${f}"
809 + if [[ ${shebang} == '#!'*${EPYTHON}* ]]; then
810 + debug-print "${FUNCNAME}: matching shebang: ${shebang}"
811 + python_files+=( "${f}" )
812 + else
813 + debug-print "${FUNCNAME}: non-matching shebang: ${shebang}"
814 + non_python_files+=( "${f}" )
815 + fi
816 +
817 + mkdir -p "${path}${bindir}" || die
818 + done
819 +
820 + for f in "${python_files[@]}"; do
821 + local basename=${f##*/}
822 +
823 + debug-print "${FUNCNAME}: installing wrapper at ${bindir}/${basename}"
824 + _python_ln_rel "${path}${EPREFIX}"/usr/lib/python-exec/python-exec2 \
825 + "${path}${bindir}/${basename}" || die
826 + done
827 +
828 + for f in "${non_python_files[@]}"; do
829 + local basename=${f##*/}
830 +
831 + debug-print "${FUNCNAME}: moving ${f#${path}/} to ${bindir}/${basename}"
832 + mv "${f}" "${path}${bindir}/${basename}" || die
833 + done
834 + fi
835 +}
836 +
837 +# @FUNCTION: distutils-r2_python_install
838 +# @USAGE: [additional-args...]
839 +# @DESCRIPTION:
840 +# The default python_install(). Runs 'esetup.py install', doing
841 +# intermediate root install and handling script wrapping afterwards.
842 +# Any parameters passed to this function will be appended
843 +# to the setup.py invocation (i.e. as options to the 'install' command).
844 +#
845 +# This phase updates the setup.cfg file with install directories.
846 +distutils-r2_python_install() {
847 + debug-print-function ${FUNCNAME} "${@}"
848 +
849 + local args=( "${@}" )
850 +
851 + # enable compilation for the install phase.
852 + local -x PYTHONDONTWRITEBYTECODE=
853 +
854 + # python likes to compile any module it sees, which triggers sandbox
855 + # failures if some packages haven't compiled their modules yet.
856 + addpredict "${EPREFIX}/usr/lib/${EPYTHON}"
857 + addpredict "${EPREFIX}/usr/$(get_libdir)/${EPYTHON}"
858 + addpredict /usr/lib/pypy2.7
859 + addpredict /usr/lib/pypy3.6
860 + addpredict /usr/lib/portage/pym
861 + addpredict /usr/local # bug 498232
862 +
863 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
864 + # user may override --install-scripts
865 + # note: this is poor but distutils argv parsing is dumb
866 + local mydistutilsargs=( "${mydistutilsargs[@]}" )
867 + local scriptdir=${EPREFIX}/usr/bin
868 +
869 + # construct a list of mydistutilsargs[0] args[0] args[1]...
870 + local arg arg_vars
871 + [[ ${mydistutilsargs[@]} ]] && eval arg_vars+=(
872 + 'mydistutilsargs['{0..$(( ${#mydistutilsargs[@]} - 1 ))}']'
873 + )
874 + [[ ${args[@]} ]] && eval arg_vars+=(
875 + 'args['{0..$(( ${#args[@]} - 1 ))}']'
876 + )
877 +
878 + set -- "${arg_vars[@]}"
879 + while [[ ${@} ]]; do
880 + local arg_var=${1}
881 + shift
882 + local a=${!arg_var}
883 +
884 + case "${a}" in
885 + --install-scripts=*)
886 + scriptdir=${a#--install-scripts=}
887 + unset "${arg_var}"
888 + ;;
889 + --install-scripts)
890 + scriptdir=${!1}
891 + unset "${arg_var}" "${1}"
892 + shift
893 + ;;
894 + esac
895 + done
896 + fi
897 +
898 + local root=${D%/}/_${EPYTHON}
899 + [[ ${DISTUTILS_SINGLE_IMPL} ]] && root=${D%/}
900 +
901 + esetup.py install --root="${root}" "${args[@]}"
902 +
903 + local forbidden_package_names=( examples test tests .pytest_cache )
904 + local p
905 + for p in "${forbidden_package_names[@]}"; do
906 + if [[ -d ${root}$(python_get_sitedir)/${p} ]]; then
907 + die "Package installs '${p}' package which is forbidden and likely a bug in the build system."
908 + fi
909 + done
910 +
911 + local shopt_save=$(shopt -p nullglob)
912 + shopt -s nullglob
913 + local pypy_dirs=(
914 + "${root}/usr/$(get_libdir)"/pypy*/share
915 + "${root}/usr/lib"/pypy*/share
916 + )
917 + ${shopt_save}
918 +
919 + if [[ -n ${pypy_dirs} ]]; then
920 + die "Package installs 'share' in PyPy prefix, see bug #465546."
921 + fi
922 +
923 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
924 + _distutils-r2_wrap_scripts "${root}" "${scriptdir}"
925 + multibuild_merge_root "${root}" "${D%/}"
926 + fi
927 +}
928 +
929 +# @FUNCTION: distutils-r2_python_install_all
930 +# @DESCRIPTION:
931 +# The default python_install_all(). It installs the documentation.
932 +distutils-r2_python_install_all() {
933 + debug-print-function ${FUNCNAME} "${@}"
934 +
935 + einstalldocs
936 +
937 + if declare -p EXAMPLES &>/dev/null; then
938 + [[ ${EAPI} != [45] ]] && die "EXAMPLES are banned in EAPI ${EAPI}"
939 +
940 + (
941 + docinto examples
942 + dodoc -r "${EXAMPLES[@]}"
943 + )
944 + docompress -x "/usr/share/doc/${PF}/examples"
945 + fi
946 +}
947 +
948 +# @FUNCTION: distutils-r2_run_phase
949 +# @USAGE: [<argv>...]
950 +# @INTERNAL
951 +# @DESCRIPTION:
952 +# Run the given command.
953 +#
954 +# If out-of-source builds are used, the phase function is run in source
955 +# directory, with BUILD_DIR pointing at the build directory
956 +# and PYTHONPATH having an entry for the module build directory.
957 +#
958 +# If in-source builds are used, the command is executed in the directory
959 +# holding the per-implementation copy of sources. BUILD_DIR points
960 +# to the 'build' subdirectory.
961 +distutils-r2_run_phase() {
962 + debug-print-function ${FUNCNAME} "${@}"
963 +
964 + if [[ ${DISTUTILS_IN_SOURCE_BUILD} ]]; then
965 + # only force BUILD_DIR if implementation is explicitly enabled
966 + # for building; any-r2 API may select one that is not
967 + # https://bugs.gentoo.org/701506
968 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]] &&
969 + has "${EPYTHON/./_}" ${PYTHON_TARGETS}; then
970 + cd "${BUILD_DIR}" || die
971 + fi
972 + local BUILD_DIR=${BUILD_DIR}/build
973 + fi
974 + local -x PYTHONPATH="${BUILD_DIR}/lib:${PYTHONPATH}"
975 +
976 + # Bug 559644
977 + # using PYTHONPATH when the ${BUILD_DIR}/lib is not created yet might lead to
978 + # problems in setup.py scripts that try to import modules/packages from that path
979 + # during the build process (Python at startup evaluates PYTHONPATH, if the dir is
980 + # not valid then associates a NullImporter object to ${BUILD_DIR}/lib storing it
981 + # in the sys.path_importer_cache)
982 + mkdir -p "${BUILD_DIR}/lib" || die
983 +
984 + # Set up build environment, bug #513664.
985 + local -x AR=${AR} CC=${CC} CPP=${CPP} CXX=${CXX}
986 + tc-export AR CC CPP CXX
987 +
988 + # How to build Python modules in different worlds...
989 + local ldopts
990 + case "${CHOST}" in
991 + # provided by haubi, 2014-07-08
992 + *-aix*) ldopts='-shared -Wl,-berok';; # good enough
993 + # provided by grobian, 2014-06-22, bug #513664 c7
994 + *-darwin*) ldopts='-bundle -undefined dynamic_lookup';;
995 + *) ldopts='-shared';;
996 + esac
997 +
998 + local -x LDSHARED="${CC} ${ldopts}" LDCXXSHARED="${CXX} ${ldopts}"
999 +
1000 + "${@}"
1001 +
1002 + cd "${_DISTUTILS_INITIAL_CWD}" || die
1003 +}
1004 +
1005 +# @FUNCTION: _distutils-r2_run_common_phase
1006 +# @USAGE: [<argv>...]
1007 +# @INTERNAL
1008 +# @DESCRIPTION:
1009 +# Run the given command, restoring the state for a most preferred Python
1010 +# implementation matching DISTUTILS_ALL_SUBPHASE_IMPLS.
1011 +#
1012 +# If in-source build is used, the command will be run in the copy
1013 +# of sources made for the selected Python interpreter.
1014 +_distutils-r2_run_common_phase() {
1015 + local DISTUTILS_ORIG_BUILD_DIR=${BUILD_DIR}
1016 +
1017 + if [[ ${DISTUTILS_SINGLE_IMPL} ]]; then
1018 + # reuse the dedicated code branch
1019 + _distutils-r2_run_foreach_impl "${@}"
1020 + else
1021 + local -x EPYTHON PYTHON
1022 + local -x PATH=${PATH} PKG_CONFIG_PATH=${PKG_CONFIG_PATH}
1023 + python_setup "${DISTUTILS_ALL_SUBPHASE_IMPLS[@]}"
1024 +
1025 + local MULTIBUILD_VARIANTS=( "${EPYTHON/./_}" )
1026 + # store for restoring after distutils-r2_run_phase.
1027 + local _DISTUTILS_INITIAL_CWD=${PWD}
1028 + multibuild_foreach_variant \
1029 + distutils-r2_run_phase "${@}"
1030 + fi
1031 +}
1032 +
1033 +# @FUNCTION: _distutils-r2_run_foreach_impl
1034 +# @INTERNAL
1035 +# @DESCRIPTION:
1036 +# Run the given phase for each implementation if multiple implementations
1037 +# are enabled, once otherwise.
1038 +_distutils-r2_run_foreach_impl() {
1039 + debug-print-function ${FUNCNAME} "${@}"
1040 +
1041 + # store for restoring after distutils-r2_run_phase.
1042 + local _DISTUTILS_INITIAL_CWD=${PWD}
1043 + set -- distutils-r2_run_phase "${@}"
1044 +
1045 + if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
1046 + python_foreach_impl "${@}"
1047 + else
1048 + if [[ ! ${EPYTHON} ]]; then
1049 + die "EPYTHON unset, python-single-r2_pkg_setup not called?!"
1050 + fi
1051 + local BUILD_DIR=${BUILD_DIR:-${S}}
1052 + BUILD_DIR=${BUILD_DIR%%/}_${EPYTHON}
1053 +
1054 + "${@}"
1055 + fi
1056 +}
1057 +
1058 +distutils-r2_src_prepare() {
1059 + debug-print-function ${FUNCNAME} "${@}"
1060 +
1061 + local _DISTUTILS_DEFAULT_CALLED
1062 +
1063 + # common preparations
1064 + if declare -f python_prepare_all >/dev/null; then
1065 + python_prepare_all
1066 + else
1067 + distutils-r2_python_prepare_all
1068 + fi
1069 +
1070 + if [[ ! ${_DISTUTILS_DEFAULT_CALLED} ]]; then
1071 + local cmd=die
1072 + [[ ${EAPI} == [45] ]] && cmd=eqawarn
1073 +
1074 + "${cmd}" "QA: python_prepare_all() didn't call distutils-r2_python_prepare_all"
1075 + fi
1076 +
1077 + if declare -f python_prepare >/dev/null; then
1078 + _distutils-r2_run_foreach_impl python_prepare
1079 + fi
1080 +}
1081 +
1082 +distutils-r2_src_configure() {
1083 + python_export_utf8_locale
1084 + [[ ${EAPI} == [56] ]] && xdg_environment_reset # Bug 577704
1085 +
1086 + if declare -f python_configure >/dev/null; then
1087 + _distutils-r2_run_foreach_impl python_configure
1088 + fi
1089 +
1090 + if declare -f python_configure_all >/dev/null; then
1091 + _distutils-r2_run_common_phase python_configure_all
1092 + fi
1093 +}
1094 +
1095 +distutils-r2_src_compile() {
1096 + debug-print-function ${FUNCNAME} "${@}"
1097 +
1098 + if declare -f python_compile >/dev/null; then
1099 + _distutils-r2_run_foreach_impl python_compile
1100 + else
1101 + _distutils-r2_run_foreach_impl distutils-r2_python_compile
1102 + fi
1103 +
1104 + if declare -f python_compile_all >/dev/null; then
1105 + _distutils-r2_run_common_phase python_compile_all
1106 + fi
1107 +}
1108 +
1109 +# @FUNCTION: _distutils-r2_clean_egg_info
1110 +# @INTERNAL
1111 +# @DESCRIPTION:
1112 +# Clean up potential stray egg-info files left by setuptools test phase.
1113 +# Those files ended up being unversioned, and caused issues:
1114 +# https://bugs.gentoo.org/534058
1115 +_distutils-r2_clean_egg_info() {
1116 + rm -rf "${BUILD_DIR}"/lib/*.egg-info || die
1117 +}
1118 +
1119 +distutils-r2_src_test() {
1120 + debug-print-function ${FUNCNAME} "${@}"
1121 +
1122 + if declare -f python_test >/dev/null; then
1123 + _distutils-r2_run_foreach_impl python_test
1124 + _distutils-r2_run_foreach_impl _distutils-r2_clean_egg_info
1125 + fi
1126 +
1127 + if declare -f python_test_all >/dev/null; then
1128 + _distutils-r2_run_common_phase python_test_all
1129 + fi
1130 +}
1131 +
1132 +# @FUNCTION: _distutils-r2_check_namespace_pth
1133 +# @INTERNAL
1134 +# @DESCRIPTION:
1135 +# Check if any *-nspkg.pth files were installed (by setuptools)
1136 +# and warn about the policy non-conformance if they were.
1137 +_distutils-r2_check_namespace_pth() {
1138 + local f pth=()
1139 +
1140 + while IFS= read -r -d '' f; do
1141 + pth+=( "${f}" )
1142 + done < <(find "${ED%/}" -name '*-nspkg.pth' -print0)
1143 +
1144 + if [[ ${pth[@]} ]]; then
1145 + ewarn "The following *-nspkg.pth files were found installed:"
1146 + ewarn
1147 + for f in "${pth[@]}"; do
1148 + ewarn " ${f#${ED%/}}"
1149 + done
1150 + ewarn
1151 + ewarn "The presence of those files may break namespaces in Python 3.5+. Please"
1152 + ewarn "read our documentation on reliable handling of namespaces and update"
1153 + ewarn "the ebuild accordingly:"
1154 + ewarn
1155 + ewarn " https://wiki.gentoo.org/wiki/Project:Python/Namespace_packages"
1156 + fi
1157 +}
1158 +
1159 +distutils-r2_src_install() {
1160 + debug-print-function ${FUNCNAME} "${@}"
1161 +
1162 + if declare -f python_install >/dev/null; then
1163 + _distutils-r2_run_foreach_impl python_install
1164 + else
1165 + _distutils-r2_run_foreach_impl distutils-r2_python_install
1166 + fi
1167 +
1168 + if declare -f python_install_all >/dev/null; then
1169 + _distutils-r2_run_common_phase python_install_all
1170 + else
1171 + _distutils-r2_run_common_phase distutils-r2_python_install_all
1172 + fi
1173 +
1174 + _distutils-r2_check_namespace_pth
1175 +}
1176 +
1177 +# -- distutils.eclass functions --
1178 +
1179 +distutils_get_intermediate_installation_image() {
1180 + die "${FUNCNAME}() is invalid for distutils-r2"
1181 +}
1182 +
1183 +distutils_src_unpack() {
1184 + die "${FUNCNAME}() is invalid for distutils-r2, and you don't want it in EAPI ${EAPI} anyway"
1185 +}
1186 +
1187 +distutils_src_prepare() {
1188 + die "${FUNCNAME}() is invalid for distutils-r2, you probably want: ${FUNCNAME/_/-r2_}"
1189 +}
1190 +
1191 +distutils_src_compile() {
1192 + die "${FUNCNAME}() is invalid for distutils-r2, you probably want: ${FUNCNAME/_/-r2_}"
1193 +}
1194 +
1195 +distutils_src_test() {
1196 + die "${FUNCNAME}() is invalid for distutils-r2, you probably want: ${FUNCNAME/_/-r2_}"
1197 +}
1198 +
1199 +distutils_src_install() {
1200 + die "${FUNCNAME}() is invalid for distutils-r2, you probably want: ${FUNCNAME/_/-r2_}"
1201 +}
1202 +
1203 +distutils_pkg_postinst() {
1204 + die "${FUNCNAME}() is invalid for distutils-r2, and pkg_postinst is unnecessary"
1205 +}
1206 +
1207 +distutils_pkg_postrm() {
1208 + die "${FUNCNAME}() is invalid for distutils-r2, and pkg_postrm is unnecessary"
1209 +}
1210 +
1211 +_DISTUTILS_R2=1
1212 +fi
1213 diff --git a/eclass/python-any-r2.eclass b/eclass/python-any-r2.eclass
1214 new file mode 100644
1215 index 000000000000..08e424254983
1216 --- /dev/null
1217 +++ b/eclass/python-any-r2.eclass
1218 @@ -0,0 +1,364 @@
1219 +# Copyright 1999-2020 Gentoo Authors
1220 +# Distributed under the terms of the GNU General Public License v2
1221 +
1222 +# @ECLASS: python-any-r2.eclass
1223 +# @MAINTAINER:
1224 +# Python team <python@g.o>
1225 +# @AUTHOR:
1226 +# Author: Michał Górny <mgorny@g.o>
1227 +# @SUPPORTED_EAPIS: 5 6 7
1228 +# @BLURB: An eclass for packages having build-time dependency on Python.
1229 +# @DESCRIPTION:
1230 +# A minimal eclass for packages which need any Python interpreter
1231 +# installed without a need for explicit choice and invariability.
1232 +# This usually involves packages requiring Python at build-time
1233 +# but having no other relevance to it.
1234 +#
1235 +# This eclass provides a minimal PYTHON_DEPS variable with a dependency
1236 +# string on any of the supported Python implementations. It also exports
1237 +# pkg_setup() which finds the best supported implementation and sets it
1238 +# as the active one.
1239 +#
1240 +# Optionally, you can define a python_check_deps() function. It will
1241 +# be called by the eclass with EPYTHON set to each matching Python
1242 +# implementation and it is expected to check whether the implementation
1243 +# fulfills the package requirements. You can use the locally exported
1244 +# PYTHON_USEDEP to check USE-dependencies of relevant packages. It
1245 +# should return a true value (0) if the Python implementation fulfills
1246 +# the requirements, a false value (non-zero) otherwise.
1247 +#
1248 +# Please note that python-any-r2 will always inherit python-utils-r2
1249 +# as well. Thus, all the functions defined there can be used in the
1250 +# packages using python-any-r2, and there is no need ever to inherit
1251 +# both.
1252 +#
1253 +# For more information, please see the Python Guide:
1254 +# https://dev.gentoo.org/~mgorny/python-guide/
1255 +
1256 +case "${EAPI:-0}" in
1257 + [0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
1258 + [5-7]) ;;
1259 + *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
1260 +esac
1261 +
1262 +if [[ ! ${_PYTHON_ANY_R2} ]]; then
1263 +
1264 +if [[ ${_PYTHON_R2} ]]; then
1265 + die 'python-any-r2.eclass can not be used with python-r2.eclass.'
1266 +elif [[ ${_PYTHON_SINGLE_R2} ]]; then
1267 + die 'python-any-r2.eclass can not be used with python-single-r2.eclass.'
1268 +fi
1269 +
1270 +inherit python-utils-r2
1271 +
1272 +fi
1273 +
1274 +EXPORT_FUNCTIONS pkg_setup
1275 +
1276 +# @ECLASS-VARIABLE: PYTHON_COMPAT
1277 +# @REQUIRED
1278 +# @DESCRIPTION:
1279 +# This variable contains a list of Python implementations the package
1280 +# supports. It must be set before the `inherit' call. It has to be
1281 +# an array.
1282 +#
1283 +# Example:
1284 +# @CODE
1285 +# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
1286 +# @CODE
1287 +
1288 +# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
1289 +# @INTERNAL
1290 +# @DESCRIPTION:
1291 +# This variable can be used when working with ebuilds to override
1292 +# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
1293 +# which will be used to build the package. It needs to be specified
1294 +# in the calling environment, and not in ebuilds.
1295 +#
1296 +# It should be noted that in order to preserve metadata immutability,
1297 +# PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of
1298 +# EPYTHON and eselect-python preferences are ignored. Dependencies need
1299 +# to be satisfied manually.
1300 +#
1301 +# Example:
1302 +# @CODE
1303 +# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
1304 +# @CODE
1305 +
1306 +# @ECLASS-VARIABLE: PYTHON_REQ_USE
1307 +# @DEFAULT_UNSET
1308 +# @DESCRIPTION:
1309 +# The list of USEflags required to be enabled on the Python
1310 +# implementations, formed as a USE-dependency string. It should be valid
1311 +# for all implementations in PYTHON_COMPAT, so it may be necessary to
1312 +# use USE defaults.
1313 +#
1314 +# Example:
1315 +# @CODE
1316 +# PYTHON_REQ_USE="gdbm,ncurses(-)?"
1317 +# @CODE
1318 +#
1319 +# It will cause the Python dependencies to look like:
1320 +# @CODE
1321 +# || ( dev-lang/python:X.Y[gdbm,ncurses(-)?] ... )
1322 +# @CODE
1323 +
1324 +# @ECLASS-VARIABLE: PYTHON_DEPS
1325 +# @DESCRIPTION:
1326 +# This is an eclass-generated Python dependency string for all
1327 +# implementations listed in PYTHON_COMPAT.
1328 +#
1329 +# Any of the supported interpreters will satisfy the dependency.
1330 +#
1331 +# Example use:
1332 +# @CODE
1333 +# DEPEND="${RDEPEND}
1334 +# ${PYTHON_DEPS}"
1335 +# @CODE
1336 +#
1337 +# Example value:
1338 +# @CODE
1339 +# || ( dev-lang/python:2.7[gdbm]
1340 +# dev-lang/python:2.6[gdbm] )
1341 +# @CODE
1342 +
1343 +# @ECLASS-VARIABLE: PYTHON_USEDEP
1344 +# @DESCRIPTION:
1345 +# An eclass-generated USE-dependency string for the currently tested
1346 +# implementation. It is set locally for python_check_deps() call.
1347 +#
1348 +# The generate USE-flag list is compatible with packages using python-r2,
1349 +# python-single-r2 and python-distutils-ng eclasses. It must not be used
1350 +# on packages using python.eclass.
1351 +#
1352 +# Example use:
1353 +# @CODE
1354 +# python_check_deps() {
1355 +# has_version "dev-python/foo[${PYTHON_USEDEP}]"
1356 +# }
1357 +# @CODE
1358 +#
1359 +# Example value:
1360 +# @CODE
1361 +# python_targets_python2_7(-)?,python_single_target_python2_7(+)?
1362 +# @CODE
1363 +
1364 +_python_any_set_globals() {
1365 + local usestr deps i PYTHON_PKG_DEP
1366 + [[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
1367 +
1368 + _python_set_impls
1369 +
1370 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1371 + python_export "${i}" PYTHON_PKG_DEP
1372 +
1373 + # note: need to strip '=' slot operator for || deps
1374 + deps="${PYTHON_PKG_DEP/:0=/:0} ${deps}"
1375 + done
1376 + deps="|| ( ${deps})"
1377 +
1378 + if [[ ${PYTHON_DEPS+1} ]]; then
1379 + if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
1380 + eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
1381 + eerror "Before: ${PYTHON_DEPS}"
1382 + eerror "Now : ${deps}"
1383 + die "PYTHON_DEPS integrity check failed"
1384 + fi
1385 + else
1386 + PYTHON_DEPS=${deps}
1387 + readonly PYTHON_DEPS
1388 + fi
1389 +
1390 + if [[ ! ${PYTHON_REQUIRED_USE+1} ]]; then
1391 + # fake var to catch mistaken usage
1392 + PYTHON_REQUIRED_USE='I-DO-NOT-EXIST-IN-PYTHON-ANY-R1'
1393 + readonly PYTHON_REQUIRED_USE
1394 + fi
1395 +}
1396 +_python_any_set_globals
1397 +unset -f _python_any_set_globals
1398 +
1399 +if [[ ! ${_PYTHON_ANY_R2} ]]; then
1400 +
1401 +# @FUNCTION: python_gen_any_dep
1402 +# @USAGE: <dependency-block>
1403 +# @DESCRIPTION:
1404 +# Generate an any-of dependency that enforces a version match between
1405 +# the Python interpreter and Python packages. <dependency-block> needs
1406 +# to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
1407 +# references (quoted!) that will get expanded inside the function.
1408 +#
1409 +# This should be used along with an appropriate python_check_deps()
1410 +# that checks which of the any-of blocks were matched.
1411 +#
1412 +# Example use:
1413 +# @CODE
1414 +# DEPEND="$(python_gen_any_dep '
1415 +# dev-python/foo[${PYTHON_USEDEP}]
1416 +# || ( dev-python/bar[${PYTHON_USEDEP}]
1417 +# dev-python/baz[${PYTHON_USEDEP}] )')"
1418 +#
1419 +# python_check_deps() {
1420 +# has_version "dev-python/foo[${PYTHON_USEDEP}]" \
1421 +# && { has_version "dev-python/bar[${PYTHON_USEDEP}]" \
1422 +# || has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
1423 +# }
1424 +# @CODE
1425 +#
1426 +# Example value:
1427 +# @CODE
1428 +# || (
1429 +# (
1430 +# dev-lang/python:2.7
1431 +# dev-python/foo[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
1432 +# || ( dev-python/bar[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
1433 +# dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] )
1434 +# )
1435 +# (
1436 +# dev-lang/python:3.3
1437 +# dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
1438 +# || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
1439 +# dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] )
1440 +# )
1441 +# )
1442 +# @CODE
1443 +python_gen_any_dep() {
1444 + debug-print-function ${FUNCNAME} "${@}"
1445 +
1446 + local depstr=${1}
1447 + [[ ${depstr} ]] || die "No dependency string provided"
1448 +
1449 + local i PYTHON_PKG_DEP out=
1450 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1451 + local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
1452 + python_export "${i}" PYTHON_PKG_DEP
1453 +
1454 + local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
1455 + # note: need to strip '=' slot operator for || deps
1456 + out="( ${PYTHON_PKG_DEP%=} ${i_depstr} ) ${out}"
1457 + done
1458 + echo "|| ( ${out})"
1459 +}
1460 +
1461 +# @FUNCTION: _python_EPYTHON_supported
1462 +# @USAGE: <epython>
1463 +# @INTERNAL
1464 +# @DESCRIPTION:
1465 +# Check whether the specified implementation is supported by package
1466 +# (specified in PYTHON_COMPAT). Calls python_check_deps() if declared.
1467 +_python_EPYTHON_supported() {
1468 + debug-print-function ${FUNCNAME} "${@}"
1469 +
1470 + local EPYTHON=${1}
1471 + local i=${EPYTHON/./_}
1472 +
1473 + case "${i}" in
1474 + python*|jython*|pypy*)
1475 + ;;
1476 + *)
1477 + ewarn "Invalid EPYTHON: ${EPYTHON}"
1478 + return 1
1479 + ;;
1480 + esac
1481 +
1482 + if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
1483 + if python_is_installed "${i}"; then
1484 + if declare -f python_check_deps >/dev/null; then
1485 + local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
1486 + python_check_deps
1487 + return ${?}
1488 + fi
1489 +
1490 + return 0
1491 + fi
1492 + elif ! has "${i}" "${_PYTHON_ALL_IMPLS[@]}"; then
1493 + ewarn "Invalid EPYTHON: ${EPYTHON}"
1494 + fi
1495 + return 1
1496 +}
1497 +
1498 +# @FUNCTION: python_setup
1499 +# @DESCRIPTION:
1500 +# Determine what the best installed (and supported) Python
1501 +# implementation is, and set the Python build environment up for it.
1502 +#
1503 +# This function will call python_check_deps() if defined.
1504 +python_setup() {
1505 + debug-print-function ${FUNCNAME} "${@}"
1506 +
1507 + # support developer override
1508 + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
1509 + local impls=( ${PYTHON_COMPAT_OVERRIDE} )
1510 + [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r2"
1511 +
1512 + ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
1513 + ewarn "implementation will be used:"
1514 + ewarn
1515 + ewarn " ${PYTHON_COMPAT_OVERRIDE}"
1516 + ewarn
1517 + ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
1518 +
1519 + python_export "${impls[0]}" EPYTHON PYTHON
1520 + python_wrapper_setup
1521 + einfo "Using ${EPYTHON} to build"
1522 + return
1523 + fi
1524 +
1525 + # first, try ${EPYTHON}... maybe it's good enough for us.
1526 + if [[ ${EPYTHON} ]]; then
1527 + if _python_EPYTHON_supported "${EPYTHON}"; then
1528 + python_export EPYTHON PYTHON
1529 + python_wrapper_setup
1530 + einfo "Using ${EPYTHON} to build"
1531 + return
1532 + fi
1533 + fi
1534 +
1535 + # then, try eselect-python
1536 + local variant i
1537 + for variant in '' '--python2' '--python3'; do
1538 + i=$(eselect python --show ${variant} 2>/dev/null)
1539 +
1540 + if [[ ! ${i} ]]; then
1541 + # no eselect-python?
1542 + break
1543 + elif _python_EPYTHON_supported "${i}"; then
1544 + python_export "${i}" EPYTHON PYTHON
1545 + python_wrapper_setup
1546 + einfo "Using ${EPYTHON} to build"
1547 + return
1548 + fi
1549 + done
1550 +
1551 + # fallback to best installed impl.
1552 + # (reverse iteration over _PYTHON_SUPPORTED_IMPLS)
1553 + for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
1554 + python_export "${_PYTHON_SUPPORTED_IMPLS[i]}" EPYTHON PYTHON
1555 + if _python_EPYTHON_supported "${EPYTHON}"; then
1556 + python_wrapper_setup
1557 + einfo "Using ${EPYTHON} to build"
1558 + return
1559 + fi
1560 + done
1561 +
1562 + eerror "No Python implementation found for the build. This is usually"
1563 + eerror "a bug in the ebuild. Please report it to bugs.gentoo.org"
1564 + eerror "along with the build log."
1565 + echo
1566 + die "No supported Python implementation installed."
1567 +}
1568 +
1569 +# @FUNCTION: python-any-r2_pkg_setup
1570 +# @DESCRIPTION:
1571 +# Runs python_setup during from-source installs.
1572 +#
1573 +# In a binary package installs is a no-op. If you need Python in pkg_*
1574 +# phases of a binary package, call python_setup directly.
1575 +python-any-r2_pkg_setup() {
1576 + debug-print-function ${FUNCNAME} "${@}"
1577 +
1578 + [[ ${MERGE_TYPE} != binary ]] && python_setup
1579 +}
1580 +
1581 +_PYTHON_ANY_R2=1
1582 +fi
1583 diff --git a/eclass/python-r2.eclass b/eclass/python-r2.eclass
1584 new file mode 100644
1585 index 000000000000..a71ebeba7c54
1586 --- /dev/null
1587 +++ b/eclass/python-r2.eclass
1588 @@ -0,0 +1,829 @@
1589 +# Copyright 1999-2020 Gentoo Authors
1590 +# Distributed under the terms of the GNU General Public License v2
1591 +
1592 +# @ECLASS: python-r2.eclass
1593 +# @MAINTAINER:
1594 +# Python team <python@g.o>
1595 +# @AUTHOR:
1596 +# Author: Michał Górny <mgorny@g.o>
1597 +# @SUPPORTED_EAPIS: 5 6 7
1598 +# @BLURB: A common, simple eclass for Python packages.
1599 +# @DESCRIPTION:
1600 +# A common eclass providing helper functions to build and install
1601 +# packages supporting being installed for multiple Python
1602 +# implementations.
1603 +#
1604 +# This eclass sets correct IUSE. Modification of REQUIRED_USE has to
1605 +# be done by the author of the ebuild (but PYTHON_REQUIRED_USE is
1606 +# provided for convenience, see below). python-r2 exports PYTHON_DEPS
1607 +# and PYTHON_USEDEP so you can create correct dependencies for your
1608 +# package easily. It also provides methods to easily run a command for
1609 +# each enabled Python implementation and duplicate the sources for them.
1610 +#
1611 +# Please note that python-r2 will always inherit python-utils-r2 as
1612 +# well. Thus, all the functions defined there can be used
1613 +# in the packages using python-r2, and there is no need ever to inherit
1614 +# both.
1615 +#
1616 +# For more information, please see the Python Guide:
1617 +# https://dev.gentoo.org/~mgorny/python-guide/
1618 +
1619 +case "${EAPI:-0}" in
1620 + 0|1|2|3|4)
1621 + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
1622 + ;;
1623 + 5|6|7)
1624 + # EAPI=5 is required for sane USE_EXPAND dependencies
1625 + ;;
1626 + *)
1627 + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
1628 + ;;
1629 +esac
1630 +
1631 +if [[ ! ${_PYTHON_R2} ]]; then
1632 +
1633 +if [[ ${_PYTHON_SINGLE_R2} ]]; then
1634 + die 'python-r2.eclass can not be used with python-single-r2.eclass.'
1635 +elif [[ ${_PYTHON_ANY_R2} ]]; then
1636 + die 'python-r2.eclass can not be used with python-any-r2.eclass.'
1637 +fi
1638 +
1639 +[[ ${EAPI} == [45] ]] && inherit eutils
1640 +inherit multibuild python-utils-r2
1641 +
1642 +fi
1643 +
1644 +# @ECLASS-VARIABLE: PYTHON_COMPAT
1645 +# @REQUIRED
1646 +# @DESCRIPTION:
1647 +# This variable contains a list of Python implementations the package
1648 +# supports. It must be set before the `inherit' call. It has to be
1649 +# an array.
1650 +#
1651 +# Example:
1652 +# @CODE
1653 +# PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
1654 +# @CODE
1655 +#
1656 +# Please note that you can also use bash brace expansion if you like:
1657 +# @CODE
1658 +# PYTHON_COMPAT=( python2_7 python3_{3,4} )
1659 +# @CODE
1660 +
1661 +# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
1662 +# @INTERNAL
1663 +# @DESCRIPTION:
1664 +# This variable can be used when working with ebuilds to override
1665 +# the in-ebuild PYTHON_COMPAT. It is a string listing all
1666 +# the implementations which package will be built for. It need be
1667 +# specified in the calling environment, and not in ebuilds.
1668 +#
1669 +# It should be noted that in order to preserve metadata immutability,
1670 +# PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
1671 +# The state of PYTHON_TARGETS is ignored, and all the implementations
1672 +# in PYTHON_COMPAT_OVERRIDE are built. Dependencies need to be satisfied
1673 +# manually.
1674 +#
1675 +# Example:
1676 +# @CODE
1677 +# PYTHON_COMPAT_OVERRIDE='pypy python3_3' emerge -1v dev-python/foo
1678 +# @CODE
1679 +
1680 +# @ECLASS-VARIABLE: PYTHON_REQ_USE
1681 +# @DEFAULT_UNSET
1682 +# @DESCRIPTION:
1683 +# The list of USEflags required to be enabled on the chosen Python
1684 +# implementations, formed as a USE-dependency string. It should be valid
1685 +# for all implementations in PYTHON_COMPAT, so it may be necessary to
1686 +# use USE defaults.
1687 +#
1688 +# This should be set before calling `inherit'.
1689 +#
1690 +# Example:
1691 +# @CODE
1692 +# PYTHON_REQ_USE="gdbm,ncurses(-)?"
1693 +# @CODE
1694 +#
1695 +# It will cause the Python dependencies to look like:
1696 +# @CODE
1697 +# python_targets_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
1698 +# @CODE
1699 +
1700 +# @ECLASS-VARIABLE: PYTHON_DEPS
1701 +# @DESCRIPTION:
1702 +# This is an eclass-generated Python dependency string for all
1703 +# implementations listed in PYTHON_COMPAT.
1704 +#
1705 +# Example use:
1706 +# @CODE
1707 +# RDEPEND="${PYTHON_DEPS}
1708 +# dev-foo/mydep"
1709 +# DEPEND="${RDEPEND}"
1710 +# @CODE
1711 +#
1712 +# Example value:
1713 +# @CODE
1714 +# dev-lang/python-exec:=
1715 +# python_targets_python2_7? ( dev-lang/python:2.7[gdbm] )
1716 +# python_targets_pypy? ( dev-python/pypy[gdbm] )
1717 +# @CODE
1718 +
1719 +# @ECLASS-VARIABLE: PYTHON_USEDEP
1720 +# @DESCRIPTION:
1721 +# This is an eclass-generated USE-dependency string which can be used to
1722 +# depend on another Python package being built for the same Python
1723 +# implementations.
1724 +#
1725 +# The generate USE-flag list is compatible with packages using python-r2
1726 +# and python-distutils-ng eclasses. It must not be used on packages
1727 +# using python.eclass.
1728 +#
1729 +# Example use:
1730 +# @CODE
1731 +# RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
1732 +# @CODE
1733 +#
1734 +# Example value:
1735 +# @CODE
1736 +# python_targets_python2_7(-)?,python_targets_python3_4(-)?
1737 +# @CODE
1738 +
1739 +# @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
1740 +# @DESCRIPTION:
1741 +# This is an eclass-generated required-use expression which ensures at
1742 +# least one Python implementation has been enabled.
1743 +#
1744 +# This expression should be utilized in an ebuild by including it in
1745 +# REQUIRED_USE, optionally behind a use flag.
1746 +#
1747 +# Example use:
1748 +# @CODE
1749 +# REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
1750 +# @CODE
1751 +#
1752 +# Example value:
1753 +# @CODE
1754 +# || ( python_targets_python2_7 python_targets_python3_4 )
1755 +# @CODE
1756 +
1757 +_python_set_globals() {
1758 + local deps i PYTHON_PKG_DEP
1759 +
1760 + _python_set_impls
1761 +
1762 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1763 + python_export "${i}" PYTHON_PKG_DEP
1764 + deps+="python_targets_${i}? ( ${PYTHON_PKG_DEP} ) "
1765 + done
1766 +
1767 + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_targets_}" )
1768 + local optflags=${flags[@]/%/(-)?}
1769 +
1770 + # A nice QA trick here. Since a python-single-r2 package has to have
1771 + # at least one PYTHON_SINGLE_TARGET enabled (REQUIRED_USE),
1772 + # the following check will always fail on those packages. Therefore,
1773 + # it should prevent developers from mistakenly depending on packages
1774 + # not supporting multiple Python implementations.
1775 +
1776 + local flags_st=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/-python_single_target_}" )
1777 + optflags+=,${flags_st[@]/%/(-)}
1778 + local requse="|| ( ${flags[*]} )"
1779 + local usedep=${optflags// /,}
1780 +
1781 + # 1) well, python-exec would suffice as an RDEP
1782 + # but no point in making this overcomplex, BDEP doesn't hurt anyone
1783 + # 2) python-exec should be built with all targets forced anyway
1784 + # but if new targets were added, we may need to force a rebuild
1785 + deps+=">=dev-lang/python-exec-2:=[${usedep}]"
1786 +
1787 + if [[ ${PYTHON_DEPS+1} ]]; then
1788 + # IUSE is magical, so we can't really check it
1789 + # (but we verify PYTHON_COMPAT already)
1790 +
1791 + if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
1792 + eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
1793 + eerror "Before: ${PYTHON_DEPS}"
1794 + eerror "Now : ${deps}"
1795 + die "PYTHON_DEPS integrity check failed"
1796 + fi
1797 +
1798 + # these two are formality -- they depend on PYTHON_COMPAT only
1799 + if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
1800 + eerror "PYTHON_REQUIRED_USE have changed between inherits!"
1801 + eerror "Before: ${PYTHON_REQUIRED_USE}"
1802 + eerror "Now : ${requse}"
1803 + die "PYTHON_REQUIRED_USE integrity check failed"
1804 + fi
1805 +
1806 + if [[ ${PYTHON_USEDEP} != "${usedep}" ]]; then
1807 + eerror "PYTHON_USEDEP have changed between inherits!"
1808 + eerror "Before: ${PYTHON_USEDEP}"
1809 + eerror "Now : ${usedep}"
1810 + die "PYTHON_USEDEP integrity check failed"
1811 + fi
1812 + else
1813 + IUSE=${flags[*]}
1814 +
1815 + PYTHON_DEPS=${deps}
1816 + PYTHON_REQUIRED_USE=${requse}
1817 + PYTHON_USEDEP=${usedep}
1818 + readonly PYTHON_DEPS PYTHON_REQUIRED_USE
1819 + fi
1820 +}
1821 +_python_set_globals
1822 +unset -f _python_set_globals
1823 +
1824 +if [[ ! ${_PYTHON_R2} ]]; then
1825 +
1826 +# @FUNCTION: _python_validate_useflags
1827 +# @INTERNAL
1828 +# @DESCRIPTION:
1829 +# Enforce the proper setting of PYTHON_TARGETS, if PYTHON_COMPAT_OVERRIDE
1830 +# is not in effect. If it is, just warn that the flags will be ignored.
1831 +_python_validate_useflags() {
1832 + debug-print-function ${FUNCNAME} "${@}"
1833 +
1834 + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
1835 + if [[ ! ${_PYTHON_COMPAT_OVERRIDE_WARNED} ]]; then
1836 + ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
1837 + ewarn "implementations will be enabled:"
1838 + ewarn
1839 + ewarn " ${PYTHON_COMPAT_OVERRIDE}"
1840 + ewarn
1841 + ewarn "Dependencies won't be satisfied, and PYTHON_TARGETS will be ignored."
1842 + _PYTHON_COMPAT_OVERRIDE_WARNED=1
1843 + fi
1844 + # we do not use flags with PCO
1845 + return
1846 + fi
1847 +
1848 + local i
1849 +
1850 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1851 + use "python_targets_${i}" && return 0
1852 + done
1853 +
1854 + eerror "No Python implementation selected for the build. Please add one"
1855 + eerror "of the following values to your PYTHON_TARGETS (in make.conf):"
1856 + eerror
1857 + eerror "${PYTHON_COMPAT[@]}"
1858 + echo
1859 + die "No supported Python implementation in PYTHON_TARGETS."
1860 +}
1861 +
1862 +# @FUNCTION: _python_gen_usedep
1863 +# @INTERNAL
1864 +# @USAGE: [<pattern>...]
1865 +# @DESCRIPTION:
1866 +# Output a USE dependency string for Python implementations which
1867 +# are both in PYTHON_COMPAT and match any of the patterns passed
1868 +# as parameters to the function.
1869 +#
1870 +# The patterns can be either fnmatch-style patterns (matched via bash
1871 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
1872 +# appropriately all enabled Python 2/3 implementations (alike
1873 +# python_is_python3). Remember to escape or quote the fnmatch patterns
1874 +# to prevent accidental shell filename expansion.
1875 +#
1876 +# This is an internal function used to implement python_gen_cond_dep
1877 +# and deprecated python_gen_usedep.
1878 +_python_gen_usedep() {
1879 + debug-print-function ${FUNCNAME} "${@}"
1880 +
1881 + local impl matches=()
1882 +
1883 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1884 + if _python_impl_matches "${impl}" "${@}"; then
1885 + matches+=(
1886 + "python_targets_${impl}(-)?"
1887 + "-python_single_target_${impl}(-)"
1888 + )
1889 + fi
1890 + done
1891 +
1892 + [[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
1893 +
1894 + local out=${matches[@]}
1895 + echo "${out// /,}"
1896 +}
1897 +
1898 +# @FUNCTION: python_gen_usedep
1899 +# @USAGE: <pattern> [...]
1900 +# @DESCRIPTION:
1901 +# DEPRECATED. Please use python_gen_cond_dep instead.
1902 +#
1903 +# Output a USE dependency string for Python implementations which
1904 +# are both in PYTHON_COMPAT and match any of the patterns passed
1905 +# as parameters to the function.
1906 +#
1907 +# The patterns can be either fnmatch-style patterns (matched via bash
1908 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
1909 +# appropriately all enabled Python 2/3 implementations (alike
1910 +# python_is_python3). Remember to escape or quote the fnmatch patterns
1911 +# to prevent accidental shell filename expansion.
1912 +#
1913 +# When all implementations are requested, please use ${PYTHON_USEDEP}
1914 +# instead. Please also remember to set an appropriate REQUIRED_USE
1915 +# to avoid ineffective USE flags.
1916 +#
1917 +# Example:
1918 +# @CODE
1919 +# PYTHON_COMPAT=( python{2_7,3_4} )
1920 +# DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
1921 +# @CODE
1922 +#
1923 +# It will cause the dependency to look like:
1924 +# @CODE
1925 +# DEPEND="doc? ( dev-python/epydoc[python_targets_python2_7?] )"
1926 +# @CODE
1927 +python_gen_usedep() {
1928 + debug-print-function ${FUNCNAME} "${@}"
1929 +
1930 + # output only once, during some reasonable phase
1931 + # (avoid spamming cache regen runs)
1932 + if [[ ${EBUILD_PHASE} == setup ]]; then
1933 + eqawarn "python_gen_usedep() is deprecated. Please use python_gen_cond_dep instead."
1934 + fi
1935 + _python_gen_usedep "${@}"
1936 +}
1937 +
1938 +# @FUNCTION: python_gen_useflags
1939 +# @USAGE: [<pattern>...]
1940 +# @DESCRIPTION:
1941 +# Output a list of USE flags for Python implementations which
1942 +# are both in PYTHON_COMPAT and match any of the patterns passed
1943 +# as parameters to the function.
1944 +#
1945 +# The patterns can be either fnmatch-style patterns (matched via bash
1946 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
1947 +# appropriately all enabled Python 2/3 implementations (alike
1948 +# python_is_python3). Remember to escape or quote the fnmatch patterns
1949 +# to prevent accidental shell filename expansion.
1950 +#
1951 +# Example:
1952 +# @CODE
1953 +# PYTHON_COMPAT=( python{2_7,3_4} )
1954 +# REQUIRED_USE="doc? ( || ( $(python_gen_useflags python2*) ) )"
1955 +# @CODE
1956 +#
1957 +# It will cause the variable to look like:
1958 +# @CODE
1959 +# REQUIRED_USE="doc? ( || ( python_targets_python2_7 ) )"
1960 +# @CODE
1961 +python_gen_useflags() {
1962 + debug-print-function ${FUNCNAME} "${@}"
1963 +
1964 + local impl matches=()
1965 +
1966 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
1967 + if _python_impl_matches "${impl}" "${@}"; then
1968 + matches+=( "python_targets_${impl}" )
1969 + fi
1970 + done
1971 +
1972 + echo "${matches[@]}"
1973 +}
1974 +
1975 +# @FUNCTION: python_gen_cond_dep
1976 +# @USAGE: <dependency> [<pattern>...]
1977 +# @DESCRIPTION:
1978 +# Output a list of <dependency>-ies made conditional to USE flags
1979 +# of Python implementations which are both in PYTHON_COMPAT and match
1980 +# any of the patterns passed as the remaining parameters.
1981 +#
1982 +# The patterns can be either fnmatch-style patterns (matched via bash
1983 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
1984 +# appropriately all enabled Python 2/3 implementations (alike
1985 +# python_is_python3). Remember to escape or quote the fnmatch patterns
1986 +# to prevent accidental shell filename expansion.
1987 +#
1988 +# In order to enforce USE constraints on the packages, verbatim
1989 +# '${PYTHON_USEDEP}' (quoted!) may be placed in the dependency
1990 +# specification. It will get expanded within the function into a proper
1991 +# USE dependency string.
1992 +#
1993 +# Example:
1994 +# @CODE
1995 +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
1996 +# RDEPEND="$(python_gen_cond_dep \
1997 +# 'dev-python/unittest2[${PYTHON_USEDEP}]' python2_7 pypy )"
1998 +# @CODE
1999 +#
2000 +# It will cause the variable to look like:
2001 +# @CODE
2002 +# RDEPEND="python_targets_python2_7? (
2003 +# dev-python/unittest2[python_targets_python2_7?] )
2004 +# python_targets_pypy? (
2005 +# dev-python/unittest2[python_targets_pypy?] )"
2006 +# @CODE
2007 +python_gen_cond_dep() {
2008 + debug-print-function ${FUNCNAME} "${@}"
2009 +
2010 + local impl matches=()
2011 + local dep=${1}
2012 + shift
2013 +
2014 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2015 + if _python_impl_matches "${impl}" "${@}"; then
2016 + # substitute ${PYTHON_USEDEP} if used
2017 + # (since python_gen_usedep() will not return ${PYTHON_USEDEP}
2018 + # the code is run at most once)
2019 + if [[ ${dep} == *'${PYTHON_USEDEP}'* ]]; then
2020 + local usedep=$(_python_gen_usedep "${@}")
2021 + dep=${dep//\$\{PYTHON_USEDEP\}/${usedep}}
2022 + fi
2023 +
2024 + matches+=( "python_targets_${impl}? ( ${dep} )" )
2025 + fi
2026 + done
2027 +
2028 + echo "${matches[@]}"
2029 +}
2030 +
2031 +# @FUNCTION: python_gen_impl_dep
2032 +# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
2033 +# @DESCRIPTION:
2034 +# Output a dependency on Python implementations with the specified USE
2035 +# dependency string appended, or no USE dependency string if called
2036 +# without the argument (or with empty argument). If any implementation
2037 +# patterns are passed, the output dependencies will be generated only
2038 +# for the implementations matching them.
2039 +#
2040 +# The patterns can be either fnmatch-style patterns (matched via bash
2041 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2042 +# appropriately all enabled Python 2/3 implementations (alike
2043 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2044 +# to prevent accidental shell filename expansion.
2045 +#
2046 +# Use this function when you need to request different USE flags
2047 +# on the Python interpreter depending on package's USE flags. If you
2048 +# only need a single set of interpreter USE flags, just set
2049 +# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
2050 +#
2051 +# Example:
2052 +# @CODE
2053 +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
2054 +# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
2055 +# @CODE
2056 +#
2057 +# It will cause the variable to look like:
2058 +# @CODE
2059 +# RDEPEND="foo? (
2060 +# python_targets_python2_7? (
2061 +# dev-lang/python:2.7[xml(+)] )
2062 +# python_targets_pypy? (
2063 +# dev-python/pypy[xml(+)] ) )"
2064 +# @CODE
2065 +python_gen_impl_dep() {
2066 + debug-print-function ${FUNCNAME} "${@}"
2067 +
2068 + local impl matches=()
2069 + local PYTHON_REQ_USE=${1}
2070 + shift
2071 +
2072 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2073 + if _python_impl_matches "${impl}" "${@}"; then
2074 + local PYTHON_PKG_DEP
2075 + python_export "${impl}" PYTHON_PKG_DEP
2076 + matches+=( "python_targets_${impl}? ( ${PYTHON_PKG_DEP} )" )
2077 + fi
2078 + done
2079 +
2080 + echo "${matches[@]}"
2081 +}
2082 +
2083 +# @FUNCTION: python_gen_any_dep
2084 +# @USAGE: <dependency-block> [<impl-pattern>...]
2085 +# @DESCRIPTION:
2086 +# Generate an any-of dependency that enforces a version match between
2087 +# the Python interpreter and Python packages. <dependency-block> needs
2088 +# to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
2089 +# references (quoted!) that will get expanded inside the function.
2090 +# Optionally, patterns may be specified to restrict the dependency
2091 +# to a subset of Python implementations supported by the ebuild.
2092 +#
2093 +# The patterns can be either fnmatch-style patterns (matched via bash
2094 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2095 +# appropriately all enabled Python 2/3 implementations (alike
2096 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2097 +# to prevent accidental shell filename expansion.
2098 +#
2099 +# This should be used along with an appropriate python_check_deps()
2100 +# that checks which of the any-of blocks were matched, and python_setup
2101 +# call that enables use of the matched implementation.
2102 +#
2103 +# Example use:
2104 +# @CODE
2105 +# DEPEND="$(python_gen_any_dep '
2106 +# dev-python/foo[${PYTHON_USEDEP}]
2107 +# || ( dev-python/bar[${PYTHON_USEDEP}]
2108 +# dev-python/baz[${PYTHON_USEDEP}] )' -2)"
2109 +#
2110 +# python_check_deps() {
2111 +# has_version "dev-python/foo[${PYTHON_USEDEP}]" \
2112 +# && { has_version "dev-python/bar[${PYTHON_USEDEP}]" \
2113 +# || has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
2114 +# }
2115 +#
2116 +# src_compile() {
2117 +# python_foreach_impl usual_code
2118 +#
2119 +# # some common post-build task that requires Python 2
2120 +# python_setup -2
2121 +# emake frobnicate
2122 +# }
2123 +# @CODE
2124 +#
2125 +# Example value:
2126 +# @CODE
2127 +# || (
2128 +# (
2129 +# dev-lang/python:2.7
2130 +# dev-python/foo[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
2131 +# || ( dev-python/bar[python_targets_python2_7(-)?,python_single_target_python2_7(+)?]
2132 +# dev-python/baz[python_targets_python2_7(-)?,python_single_target_python2_7(+)?] )
2133 +# )
2134 +# (
2135 +# dev-lang/python:3.3
2136 +# dev-python/foo[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
2137 +# || ( dev-python/bar[python_targets_python3_3(-)?,python_single_target_python3_3(+)?]
2138 +# dev-python/baz[python_targets_python3_3(-)?,python_single_target_python3_3(+)?] )
2139 +# )
2140 +# )
2141 +# @CODE
2142 +python_gen_any_dep() {
2143 + debug-print-function ${FUNCNAME} "${@}"
2144 +
2145 + local depstr=${1}
2146 + [[ ${depstr} ]] || die "No dependency string provided"
2147 + shift
2148 +
2149 + local i PYTHON_PKG_DEP out=
2150 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2151 + if _python_impl_matches "${i}" "${@}"; then
2152 + local PYTHON_USEDEP="python_targets_${i}(-),python_single_target_${i}(+)"
2153 + python_export "${i}" PYTHON_PKG_DEP
2154 +
2155 + local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
2156 + # note: need to strip '=' slot operator for || deps
2157 + out="( ${PYTHON_PKG_DEP/:0=/:0} ${i_depstr} ) ${out}"
2158 + fi
2159 + done
2160 + echo "|| ( ${out})"
2161 +}
2162 +
2163 +# @ECLASS-VARIABLE: BUILD_DIR
2164 +# @DESCRIPTION:
2165 +# The current build directory. In global scope, it is supposed to
2166 +# contain an initial build directory; if unset, it defaults to ${S}.
2167 +#
2168 +# In functions run by python_foreach_impl(), the BUILD_DIR is locally
2169 +# set to an implementation-specific build directory. That path is
2170 +# created through appending a hyphen and the implementation name
2171 +# to the final component of the initial BUILD_DIR.
2172 +#
2173 +# Example value:
2174 +# @CODE
2175 +# ${WORKDIR}/foo-1.3-python2_7
2176 +# @CODE
2177 +
2178 +# @FUNCTION: python_copy_sources
2179 +# @DESCRIPTION:
2180 +# Create a single copy of the package sources for each enabled Python
2181 +# implementation.
2182 +#
2183 +# The sources are always copied from initial BUILD_DIR (or S if unset)
2184 +# to implementation-specific build directory matching BUILD_DIR used by
2185 +# python_foreach_abi().
2186 +python_copy_sources() {
2187 + debug-print-function ${FUNCNAME} "${@}"
2188 +
2189 + local MULTIBUILD_VARIANTS
2190 + _python_obtain_impls
2191 +
2192 + multibuild_copy_sources
2193 +}
2194 +
2195 +# @FUNCTION: _python_obtain_impls
2196 +# @INTERNAL
2197 +# @DESCRIPTION:
2198 +# Set up the enabled implementation list.
2199 +_python_obtain_impls() {
2200 + _python_validate_useflags
2201 +
2202 + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
2203 + MULTIBUILD_VARIANTS=( ${PYTHON_COMPAT_OVERRIDE} )
2204 + return
2205 + fi
2206 +
2207 + MULTIBUILD_VARIANTS=()
2208 +
2209 + local impl
2210 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2211 + has "${impl}" "${PYTHON_COMPAT[@]}" && \
2212 + use "python_targets_${impl}" && MULTIBUILD_VARIANTS+=( "${impl}" )
2213 + done
2214 +}
2215 +
2216 +# @FUNCTION: _python_multibuild_wrapper
2217 +# @USAGE: <command> [<args>...]
2218 +# @INTERNAL
2219 +# @DESCRIPTION:
2220 +# Initialize the environment for Python implementation selected
2221 +# for multibuild.
2222 +_python_multibuild_wrapper() {
2223 + debug-print-function ${FUNCNAME} "${@}"
2224 +
2225 + local -x EPYTHON PYTHON
2226 + local -x PATH=${PATH} PKG_CONFIG_PATH=${PKG_CONFIG_PATH}
2227 + python_export "${MULTIBUILD_VARIANT}" EPYTHON PYTHON
2228 + python_wrapper_setup
2229 +
2230 + "${@}"
2231 +}
2232 +
2233 +# @FUNCTION: python_foreach_impl
2234 +# @USAGE: <command> [<args>...]
2235 +# @DESCRIPTION:
2236 +# Run the given command for each of the enabled Python implementations.
2237 +# If additional parameters are passed, they will be passed through
2238 +# to the command.
2239 +#
2240 +# The function will return 0 status if all invocations succeed.
2241 +# Otherwise, the return code from first failing invocation will
2242 +# be returned.
2243 +#
2244 +# For each command being run, EPYTHON, PYTHON and BUILD_DIR are set
2245 +# locally, and the former two are exported to the command environment.
2246 +python_foreach_impl() {
2247 + debug-print-function ${FUNCNAME} "${@}"
2248 +
2249 + local MULTIBUILD_VARIANTS
2250 + _python_obtain_impls
2251 +
2252 + multibuild_foreach_variant _python_multibuild_wrapper "${@}"
2253 +}
2254 +
2255 +# @FUNCTION: python_setup
2256 +# @USAGE: [<impl-pattern>...]
2257 +# @DESCRIPTION:
2258 +# Find the best (most preferred) Python implementation that is suitable
2259 +# for running common Python code. Set the Python build environment up
2260 +# for that implementation. This function has two modes of operation:
2261 +# pure and any-of dep.
2262 +#
2263 +# The pure mode is used if python_check_deps() function is not declared.
2264 +# In this case, an implementation is considered suitable if it is
2265 +# supported (in PYTHON_COMPAT), enabled (via USE flags) and matches
2266 +# at least one of the patterns passed (or '*' if no patterns passed).
2267 +#
2268 +# Implementation restrictions in the pure mode need to be accompanied
2269 +# by appropriate REQUIRED_USE constraints. Otherwise, the eclass may
2270 +# fail at build time due to unsatisfied dependencies.
2271 +#
2272 +# The any-of dep mode is used if python_check_deps() is declared.
2273 +# In this mode, an implementation is considered suitable if it is
2274 +# supported, matches at least one of the patterns and python_check_deps()
2275 +# has successful return code. USE flags are not considered.
2276 +#
2277 +# The python_check_deps() function in the any-of mode needs to be
2278 +# accompanied by appropriate any-of dependencies.
2279 +#
2280 +# The patterns can be either fnmatch-style patterns (matched via bash
2281 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2282 +# appropriately all enabled Python 2/3 implementations (alike
2283 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2284 +# to prevent accidental shell filename expansion.
2285 +#
2286 +# This function needs to be used when Python is being called outside
2287 +# of python_foreach_impl calls (e.g. for shared processes like doc
2288 +# building). python_foreach_impl sets up the build environment itself.
2289 +#
2290 +# Pure mode example:
2291 +# @CODE
2292 +# DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
2293 +# REQUIRED_USE="doc? ( $(python_gen_useflags 'python2*') )"
2294 +#
2295 +# src_compile() {
2296 +# #...
2297 +# if use doc; then
2298 +# python_setup 'python2*'
2299 +# make doc
2300 +# fi
2301 +# }
2302 +# @CODE
2303 +#
2304 +# Any-of mode example:
2305 +# @CODE
2306 +# DEPEND="doc? (
2307 +# $(python_gen_any_dep 'dev-python/epydoc[${PYTHON_USEDEP}]' 'python2*') )"
2308 +#
2309 +# python_check_deps() {
2310 +# has_version "dev-python/epydoc[${PYTHON_USEDEP}]"
2311 +# }
2312 +#
2313 +# src_compile() {
2314 +# #...
2315 +# if use doc; then
2316 +# python_setup 'python2*'
2317 +# make doc
2318 +# fi
2319 +# }
2320 +# @CODE
2321 +python_setup() {
2322 + debug-print-function ${FUNCNAME} "${@}"
2323 +
2324 + _python_validate_useflags
2325 + local pycompat=( "${PYTHON_COMPAT[@]}" )
2326 + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
2327 + pycompat=( ${PYTHON_COMPAT_OVERRIDE} )
2328 + fi
2329 +
2330 + local has_check_deps
2331 + declare -f python_check_deps >/dev/null && has_check_deps=1
2332 +
2333 + # (reverse iteration -- newest impl first)
2334 + local found
2335 + for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
2336 + local impl=${_PYTHON_SUPPORTED_IMPLS[i]}
2337 +
2338 + # check PYTHON_COMPAT[_OVERRIDE]
2339 + has "${impl}" "${pycompat[@]}" || continue
2340 +
2341 + # match USE flags only if override is not in effect
2342 + # and python_check_deps() is not defined
2343 + if [[ ! ${PYTHON_COMPAT_OVERRIDE} && ! ${has_check_deps} ]]; then
2344 + use "python_targets_${impl}" || continue
2345 + fi
2346 +
2347 + # check patterns
2348 + _python_impl_matches "${impl}" "${@}" || continue
2349 +
2350 + python_export "${impl}" EPYTHON PYTHON
2351 +
2352 + # if python_check_deps() is declared, switch into any-of mode
2353 + if [[ ${has_check_deps} ]]; then
2354 + # first check if the interpreter is installed
2355 + python_is_installed "${impl}" || continue
2356 + # then run python_check_deps
2357 + local PYTHON_USEDEP="python_targets_${impl}(-),python_single_target_${impl}(+)"
2358 + python_check_deps || continue
2359 + fi
2360 +
2361 + found=1
2362 + break
2363 + done
2364 +
2365 + if [[ ! ${found} ]]; then
2366 + eerror "${FUNCNAME}: none of the enabled implementation matched the patterns."
2367 + eerror " patterns: ${@-'(*)'}"
2368 + eerror "Likely a REQUIRED_USE constraint (possibly USE-conditional) is missing."
2369 + eerror " suggested: || ( \$(python_gen_useflags ${@}) )"
2370 + eerror "(remember to quote all the patterns with '')"
2371 + die "${FUNCNAME}: no enabled implementation satisfy requirements"
2372 + fi
2373 +
2374 + python_wrapper_setup
2375 + einfo "Using ${EPYTHON} in global scope"
2376 +}
2377 +
2378 +# @FUNCTION: python_replicate_script
2379 +# @USAGE: <path>...
2380 +# @DESCRIPTION:
2381 +# Copy the given script to variants for all enabled Python
2382 +# implementations, then replace it with a symlink to the wrapper.
2383 +#
2384 +# All specified files must start with a 'python' shebang. A file not
2385 +# having a matching shebang will be refused.
2386 +python_replicate_script() {
2387 + debug-print-function ${FUNCNAME} "${@}"
2388 +
2389 + _python_replicate_script() {
2390 + local _PYTHON_FIX_SHEBANG_QUIET=1
2391 +
2392 + local PYTHON_SCRIPTDIR
2393 + python_export PYTHON_SCRIPTDIR
2394 +
2395 + (
2396 + exeopts -m 0755
2397 + exeinto "${PYTHON_SCRIPTDIR#${EPREFIX}}"
2398 + doexe "${files[@]}"
2399 + )
2400 +
2401 + python_fix_shebang -q \
2402 + "${files[@]/*\//${D%/}/${PYTHON_SCRIPTDIR}/}"
2403 + }
2404 +
2405 + local files=( "${@}" )
2406 + python_foreach_impl _python_replicate_script
2407 + unset -f _python_replicate_script
2408 +
2409 + # install the wrappers
2410 + local f
2411 + for f; do
2412 + _python_ln_rel "${ED%/}/usr/lib/python-exec/python-exec2" "${f}" || die
2413 + done
2414 +}
2415 +
2416 +_PYTHON_R2=1
2417 +fi
2418 diff --git a/eclass/python-single-r2.eclass b/eclass/python-single-r2.eclass
2419 new file mode 100644
2420 index 000000000000..d9d535711252
2421 --- /dev/null
2422 +++ b/eclass/python-single-r2.eclass
2423 @@ -0,0 +1,512 @@
2424 +# Copyright 1999-2020 Gentoo Authors
2425 +# Distributed under the terms of the GNU General Public License v2
2426 +
2427 +# @ECLASS: python-single-r2.eclass
2428 +# @MAINTAINER:
2429 +# Python team <python@g.o>
2430 +# @AUTHOR:
2431 +# Author: Michał Górny <mgorny@g.o>
2432 +# @SUPPORTED_EAPIS: 5 6 7
2433 +# @BLURB: An eclass for Python packages not installed for multiple implementations.
2434 +# @DESCRIPTION:
2435 +# An extension of the python-r2 eclass suite for packages which
2436 +# don't support being installed for multiple Python implementations.
2437 +# This mostly includes tools embedding Python and packages using foreign
2438 +# build systems.
2439 +#
2440 +# This eclass sets correct IUSE. It also provides PYTHON_DEPS
2441 +# and PYTHON_REQUIRED_USE that need to be added to appropriate ebuild
2442 +# metadata variables.
2443 +#
2444 +# The eclass exports PYTHON_SINGLE_USEDEP that is suitable for depending
2445 +# on other packages using the eclass. Dependencies on packages using
2446 +# python-r2 should be created via python_gen_cond_dep() function,
2447 +# using PYTHON_MULTI_USEDEP placeholder.
2448 +#
2449 +# Please note that packages support multiple Python implementations
2450 +# (using python-r2 eclass) can not depend on packages not supporting
2451 +# them (using this eclass).
2452 +#
2453 +# Please note that python-single-r2 will always inherit python-utils-r2
2454 +# as well. Thus, all the functions defined there can be used
2455 +# in the packages using python-single-r2, and there is no need ever
2456 +# to inherit both.
2457 +#
2458 +# For more information, please see the Python Guide:
2459 +# https://dev.gentoo.org/~mgorny/python-guide/
2460 +
2461 +case "${EAPI:-0}" in
2462 + 0|1|2|3|4)
2463 + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
2464 + ;;
2465 + 5|6|7)
2466 + # EAPI=5 is required for sane USE_EXPAND dependencies
2467 + ;;
2468 + *)
2469 + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
2470 + ;;
2471 +esac
2472 +
2473 +if [[ ! ${_PYTHON_SINGLE_R2} ]]; then
2474 +
2475 +if [[ ${_PYTHON_R2} ]]; then
2476 + die 'python-single-r2.eclass can not be used with python-r2.eclass.'
2477 +elif [[ ${_PYTHON_ANY_R2} ]]; then
2478 + die 'python-single-r2.eclass can not be used with python-any-r2.eclass.'
2479 +fi
2480 +
2481 +inherit python-utils-r2
2482 +
2483 +fi
2484 +
2485 +EXPORT_FUNCTIONS pkg_setup
2486 +
2487 +# @ECLASS-VARIABLE: PYTHON_COMPAT
2488 +# @REQUIRED
2489 +# @DESCRIPTION:
2490 +# This variable contains a list of Python implementations the package
2491 +# supports. It must be set before the `inherit' call. It has to be
2492 +# an array.
2493 +#
2494 +# Example:
2495 +# @CODE
2496 +# PYTHON_COMPAT=( python2_7 python3_3 python3_4 )
2497 +# @CODE
2498 +#
2499 +# Please note that you can also use bash brace expansion if you like:
2500 +# @CODE
2501 +# PYTHON_COMPAT=( python2_7 python3_{3,4} )
2502 +# @CODE
2503 +
2504 +# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
2505 +# @INTERNAL
2506 +# @DESCRIPTION:
2507 +# This variable can be used when working with ebuilds to override
2508 +# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
2509 +# which package will be built for. It needs to be specified
2510 +# in the calling environment, and not in ebuilds.
2511 +#
2512 +# It should be noted that in order to preserve metadata immutability,
2513 +# PYTHON_COMPAT_OVERRIDE does not affect IUSE nor dependencies.
2514 +# The state of PYTHON_SINGLE_TARGET is ignored, and the implementation
2515 +# in PYTHON_COMPAT_OVERRIDE is built instead. Dependencies need to be
2516 +# satisfied manually.
2517 +#
2518 +# Example:
2519 +# @CODE
2520 +# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
2521 +# @CODE
2522 +
2523 +# @ECLASS-VARIABLE: PYTHON_REQ_USE
2524 +# @DEFAULT_UNSET
2525 +# @DESCRIPTION:
2526 +# The list of USEflags required to be enabled on the chosen Python
2527 +# implementations, formed as a USE-dependency string. It should be valid
2528 +# for all implementations in PYTHON_COMPAT, so it may be necessary to
2529 +# use USE defaults.
2530 +#
2531 +# This should be set before calling `inherit'.
2532 +#
2533 +# Example:
2534 +# @CODE
2535 +# PYTHON_REQ_USE="gdbm,ncurses(-)?"
2536 +# @CODE
2537 +#
2538 +# It will cause the Python dependencies to look like:
2539 +# @CODE
2540 +# python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?] )
2541 +# @CODE
2542 +
2543 +# @ECLASS-VARIABLE: PYTHON_DEPS
2544 +# @DESCRIPTION:
2545 +# This is an eclass-generated Python dependency string for all
2546 +# implementations listed in PYTHON_COMPAT.
2547 +#
2548 +# The dependency string is conditional on PYTHON_SINGLE_TARGET.
2549 +#
2550 +# Example use:
2551 +# @CODE
2552 +# RDEPEND="${PYTHON_DEPS}
2553 +# dev-foo/mydep"
2554 +# DEPEND="${RDEPEND}"
2555 +# @CODE
2556 +#
2557 +# Example value:
2558 +# @CODE
2559 +# dev-lang/python-exec:=
2560 +# python_single_target_python2_7? ( dev-lang/python:2.7[gdbm] )
2561 +# python_single_target_pypy? ( dev-python/pypy[gdbm] )
2562 +# @CODE
2563 +
2564 +# @ECLASS-VARIABLE: PYTHON_SINGLE_USEDEP
2565 +# @DESCRIPTION:
2566 +# This is an eclass-generated USE-dependency string which can be used to
2567 +# depend on another python-single-r2 package being built for the same
2568 +# Python implementations.
2569 +#
2570 +# If you need to depend on a multi-impl (python-r2) package, use
2571 +# python_gen_cond_dep with PYTHON_MULTI_USEDEP placeholder instead.
2572 +#
2573 +# Example use:
2574 +# @CODE
2575 +# RDEPEND="dev-python/foo[${PYTHON_SINGLE_USEDEP}]"
2576 +# @CODE
2577 +#
2578 +# Example value:
2579 +# @CODE
2580 +# python_single_target_python3_4(-)?
2581 +# @CODE
2582 +
2583 +# @ECLASS-VARIABLE: PYTHON_MULTI_USEDEP
2584 +# @DESCRIPTION:
2585 +# This is a placeholder variable supported by python_gen_cond_dep,
2586 +# in order to depend on python-r2 packages built for the same Python
2587 +# implementations.
2588 +#
2589 +# Example use:
2590 +# @CODE
2591 +# RDEPEND="$(python_gen_cond_dep '
2592 +# dev-python/foo[${PYTHON_MULTI_USEDEP}]
2593 +# ')"
2594 +# @CODE
2595 +#
2596 +# Example value:
2597 +# @CODE
2598 +# python_targets_python3_4(-)
2599 +# @CODE
2600 +
2601 +# @ECLASS-VARIABLE: PYTHON_REQUIRED_USE
2602 +# @DESCRIPTION:
2603 +# This is an eclass-generated required-use expression which ensures
2604 +# that exactly one PYTHON_SINGLE_TARGET value has been enabled.
2605 +#
2606 +# This expression should be utilized in an ebuild by including it in
2607 +# REQUIRED_USE, optionally behind a use flag.
2608 +#
2609 +# Example use:
2610 +# @CODE
2611 +# REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
2612 +# @CODE
2613 +#
2614 +# Example value:
2615 +# @CODE
2616 +# ^^ ( python_single_target_python2_7 python_single_target_python3_3 )
2617 +# @CODE
2618 +
2619 +_python_single_set_globals() {
2620 + _python_set_impls
2621 +
2622 + local flags=( "${_PYTHON_SUPPORTED_IMPLS[@]/#/python_single_target_}" )
2623 +
2624 + if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 1 ]]; then
2625 + # if only one implementation is supported, use IUSE defaults
2626 + # to avoid requesting the user to enable it
2627 + IUSE="+${flags[0]}"
2628 + else
2629 + IUSE="${flags[*]}"
2630 + fi
2631 +
2632 + local requse="^^ ( ${flags[*]} )"
2633 + local single_flags="${flags[@]/%/(-)?}"
2634 + local single_usedep=${single_flags// /,}
2635 +
2636 + local deps= i PYTHON_PKG_DEP
2637 + for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2638 + python_export "${i}" PYTHON_PKG_DEP
2639 + # 1) well, python-exec would suffice as an RDEP
2640 + # but no point in making this overcomplex, BDEP doesn't hurt anyone
2641 + # 2) python-exec should be built with all targets forced anyway
2642 + # but if new targets were added, we may need to force a rebuild
2643 + deps+="python_single_target_${i}? (
2644 + ${PYTHON_PKG_DEP}
2645 + >=dev-lang/python-exec-2:=[python_targets_${i}]
2646 + ) "
2647 + done
2648 +
2649 + if [[ ${PYTHON_DEPS+1} ]]; then
2650 + if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
2651 + eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
2652 + eerror "Before: ${PYTHON_DEPS}"
2653 + eerror "Now : ${deps}"
2654 + die "PYTHON_DEPS integrity check failed"
2655 + fi
2656 +
2657 + # these two are formality -- they depend on PYTHON_COMPAT only
2658 + if [[ ${PYTHON_REQUIRED_USE} != ${requse} ]]; then
2659 + eerror "PYTHON_REQUIRED_USE have changed between inherits!"
2660 + eerror "Before: ${PYTHON_REQUIRED_USE}"
2661 + eerror "Now : ${requse}"
2662 + die "PYTHON_REQUIRED_USE integrity check failed"
2663 + fi
2664 +
2665 + if [[ ${PYTHON_SINGLE_USEDEP} != "${single_usedep}" ]]; then
2666 + eerror "PYTHON_SINGLE_USEDEP have changed between inherits!"
2667 + eerror "Before: ${PYTHON_SINGLE_USEDEP}"
2668 + eerror "Now : ${single_usedep}"
2669 + die "PYTHON_SINGLE_USEDEP integrity check failed"
2670 + fi
2671 + else
2672 + PYTHON_DEPS=${deps}
2673 + PYTHON_REQUIRED_USE=${requse}
2674 + PYTHON_USEDEP='%PYTHON_USEDEP-HAS-BEEN-REMOVED%'
2675 + PYTHON_SINGLE_USEDEP=${single_usedep}
2676 + readonly PYTHON_DEPS PYTHON_REQUIRED_USE PYTHON_SINGLE_USEDEP \
2677 + PYTHON_USEDEP
2678 + fi
2679 +}
2680 +_python_single_set_globals
2681 +unset -f _python_single_set_globals
2682 +
2683 +if [[ ! ${_PYTHON_SINGLE_R2} ]]; then
2684 +
2685 +# @FUNCTION: _python_gen_usedep
2686 +# @INTERNAL
2687 +# @USAGE: [<pattern>...]
2688 +# @DESCRIPTION:
2689 +# Output a USE dependency string for Python implementations which
2690 +# are both in PYTHON_COMPAT and match any of the patterns passed
2691 +# as parameters to the function.
2692 +#
2693 +# The patterns can be either fnmatch-style patterns (matched via bash
2694 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2695 +# appropriately all enabled Python 2/3 implementations (alike
2696 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2697 +# to prevent accidental shell filename expansion.
2698 +#
2699 +# This is an internal function used to implement python_gen_cond_dep.
2700 +_python_gen_usedep() {
2701 + debug-print-function ${FUNCNAME} "${@}"
2702 +
2703 + local impl matches=()
2704 +
2705 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2706 + if _python_impl_matches "${impl}" "${@}"; then
2707 + matches+=(
2708 + "python_single_target_${impl}(-)?"
2709 + )
2710 + fi
2711 + done
2712 +
2713 + [[ ${matches[@]} ]] || die "No supported implementations match python_gen_usedep patterns: ${@}"
2714 +
2715 + local out=${matches[@]}
2716 + echo "${out// /,}"
2717 +}
2718 +
2719 +# @FUNCTION: python_gen_useflags
2720 +# @USAGE: [<pattern>...]
2721 +# @DESCRIPTION:
2722 +# Output a list of USE flags for Python implementations which
2723 +# are both in PYTHON_COMPAT and match any of the patterns passed
2724 +# as parameters to the function.
2725 +#
2726 +# The patterns can be either fnmatch-style patterns (matched via bash
2727 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2728 +# appropriately all enabled Python 2/3 implementations (alike
2729 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2730 +# to prevent accidental shell filename expansion.
2731 +#
2732 +# Example:
2733 +# @CODE
2734 +# PYTHON_COMPAT=( python{2_7,3_4} )
2735 +# REQUIRED_USE="doc? ( ^^ ( $(python_gen_useflags 'python2*') ) )"
2736 +# @CODE
2737 +#
2738 +# It will cause the variable to look like:
2739 +# @CODE
2740 +# REQUIRED_USE="doc? ( ^^ ( python_single_target_python2_7 ) )"
2741 +# @CODE
2742 +python_gen_useflags() {
2743 + debug-print-function ${FUNCNAME} "${@}"
2744 +
2745 + local impl matches=()
2746 +
2747 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2748 + if _python_impl_matches "${impl}" "${@}"; then
2749 + matches+=( "python_single_target_${impl}" )
2750 + fi
2751 + done
2752 +
2753 + echo "${matches[@]}"
2754 +}
2755 +
2756 +# @FUNCTION: python_gen_cond_dep
2757 +# @USAGE: <dependency> [<pattern>...]
2758 +# @DESCRIPTION:
2759 +# Output a list of <dependency>-ies made conditional to USE flags
2760 +# of Python implementations which are both in PYTHON_COMPAT and match
2761 +# any of the patterns passed as the remaining parameters.
2762 +#
2763 +# The patterns can be either fnmatch-style patterns (matched via bash
2764 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2765 +# appropriately all enabled Python 2/3 implementations (alike
2766 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2767 +# to prevent accidental shell filename expansion.
2768 +#
2769 +# In order to enforce USE constraints on the packages, verbatim
2770 +# '${PYTHON_SINGLE_USEDEP}' and '${PYTHON_MULTI_USEDEP}' (quoted!) may
2771 +# be placed in the dependency specification. It will get expanded within
2772 +# the function into a proper USE dependency string.
2773 +#
2774 +# Example:
2775 +# @CODE
2776 +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
2777 +# RDEPEND="$(python_gen_cond_dep \
2778 +# 'dev-python/unittest2[${PYTHON_MULTI_USEDEP}]' python2_7 pypy )"
2779 +# @CODE
2780 +#
2781 +# It will cause the variable to look like:
2782 +# @CODE
2783 +# RDEPEND="python_single_target_python2_7? (
2784 +# dev-python/unittest2[python_targets_python2_7(-)?,...] )
2785 +# python_single_target_pypy? (
2786 +# dev-python/unittest2[python_targets_pypy(-)?,...] )"
2787 +# @CODE
2788 +python_gen_cond_dep() {
2789 + debug-print-function ${FUNCNAME} "${@}"
2790 +
2791 + local impl matches=()
2792 +
2793 + local dep=${1}
2794 + shift
2795 +
2796 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2797 + if _python_impl_matches "${impl}" "${@}"; then
2798 + # substitute ${PYTHON_SINGLE_USEDEP} if used
2799 + # (since python_gen_usedep() will not return
2800 + # ${PYTHON_SINGLE_USEDEP}, the code is run at most once)
2801 + if [[ ${dep} == *'${PYTHON_SINGLE_USEDEP}'* ]]; then
2802 + local usedep=$(_python_gen_usedep "${@}")
2803 + dep=${dep//\$\{PYTHON_SINGLE_USEDEP\}/${usedep}}
2804 + fi
2805 + local multi_usedep="python_targets_${impl}(-)"
2806 +
2807 + matches+=( "python_single_target_${impl}? (
2808 + ${dep//\$\{PYTHON_MULTI_USEDEP\}/${multi_usedep}} )" )
2809 + fi
2810 + done
2811 +
2812 + echo "${matches[@]}"
2813 +}
2814 +
2815 +# @FUNCTION: python_gen_impl_dep
2816 +# @USAGE: [<requested-use-flags> [<impl-pattern>...]]
2817 +# @DESCRIPTION:
2818 +# Output a dependency on Python implementations with the specified USE
2819 +# dependency string appended, or no USE dependency string if called
2820 +# without the argument (or with empty argument). If any implementation
2821 +# patterns are passed, the output dependencies will be generated only
2822 +# for the implementations matching them.
2823 +#
2824 +# The patterns can be either fnmatch-style patterns (matched via bash
2825 +# == operator against PYTHON_COMPAT values) or '-2' / '-3' to indicate
2826 +# appropriately all enabled Python 2/3 implementations (alike
2827 +# python_is_python3). Remember to escape or quote the fnmatch patterns
2828 +# to prevent accidental shell filename expansion.
2829 +#
2830 +# Use this function when you need to request different USE flags
2831 +# on the Python interpreter depending on package's USE flags. If you
2832 +# only need a single set of interpreter USE flags, just set
2833 +# PYTHON_REQ_USE and use ${PYTHON_DEPS} globally.
2834 +#
2835 +# Example:
2836 +# @CODE
2837 +# PYTHON_COMPAT=( python{2_7,3_{3,4}} pypy )
2838 +# RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )"
2839 +# @CODE
2840 +#
2841 +# It will cause the variable to look like:
2842 +# @CODE
2843 +# RDEPEND="foo? (
2844 +# python_single_target_python2_7? (
2845 +# dev-lang/python:2.7[xml(+)] )
2846 +# python_single_target_pypy? (
2847 +# dev-python/pypy[xml(+)] ) )"
2848 +# @CODE
2849 +python_gen_impl_dep() {
2850 + debug-print-function ${FUNCNAME} "${@}"
2851 +
2852 + local impl
2853 + local matches=()
2854 +
2855 + local PYTHON_REQ_USE=${1}
2856 + shift
2857 +
2858 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2859 + if _python_impl_matches "${impl}" "${@}"; then
2860 + local PYTHON_PKG_DEP
2861 + python_export "${impl}" PYTHON_PKG_DEP
2862 + matches+=( "python_single_target_${impl}? ( ${PYTHON_PKG_DEP} )" )
2863 + fi
2864 + done
2865 +
2866 + echo "${matches[@]}"
2867 +}
2868 +
2869 +# @FUNCTION: python_setup
2870 +# @DESCRIPTION:
2871 +# Determine what the selected Python implementation is and set
2872 +# the Python build environment up for it.
2873 +python_setup() {
2874 + debug-print-function ${FUNCNAME} "${@}"
2875 +
2876 + unset EPYTHON
2877 +
2878 + # support developer override
2879 + if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
2880 + local impls=( ${PYTHON_COMPAT_OVERRIDE} )
2881 + [[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-single-r2"
2882 +
2883 + ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
2884 + ewarn "implementation will be used:"
2885 + ewarn
2886 + ewarn " ${PYTHON_COMPAT_OVERRIDE}"
2887 + ewarn
2888 + ewarn "Dependencies won't be satisfied, and PYTHON_SINGLE_TARGET flags will be ignored."
2889 +
2890 + python_export "${impls[0]}" EPYTHON PYTHON
2891 + python_wrapper_setup
2892 + einfo "Using ${EPYTHON} to build"
2893 + return
2894 + fi
2895 +
2896 + local impl
2897 + for impl in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
2898 + if use "python_single_target_${impl}"; then
2899 + if [[ ${EPYTHON} ]]; then
2900 + eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
2901 + eerror "implementation. Please set it to just one value. If you need"
2902 + eerror "to override the value for a single package, please use package.env"
2903 + eerror "or an equivalent solution (man 5 portage)."
2904 + echo
2905 + die "More than one implementation in PYTHON_SINGLE_TARGET."
2906 + fi
2907 +
2908 + python_export "${impl}" EPYTHON PYTHON
2909 + python_wrapper_setup
2910 + einfo "Using ${EPYTHON} to build"
2911 + fi
2912 + done
2913 +
2914 + if [[ ! ${EPYTHON} ]]; then
2915 + eerror "No Python implementation selected for the build. Please set"
2916 + eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
2917 + eerror "of the following values:"
2918 + eerror
2919 + eerror "${_PYTHON_SUPPORTED_IMPLS[@]}"
2920 + echo
2921 + die "No supported Python implementation in PYTHON_SINGLE_TARGET."
2922 + fi
2923 +}
2924 +
2925 +# @FUNCTION: python-single-r2_pkg_setup
2926 +# @DESCRIPTION:
2927 +# Runs python_setup.
2928 +python-single-r2_pkg_setup() {
2929 + debug-print-function ${FUNCNAME} "${@}"
2930 +
2931 + [[ ${MERGE_TYPE} != binary ]] && python_setup
2932 +}
2933 +
2934 +_PYTHON_SINGLE_R2=1
2935 +fi
2936 diff --git a/eclass/python-utils-r2.eclass b/eclass/python-utils-r2.eclass
2937 new file mode 100644
2938 index 000000000000..c28c42493173
2939 --- /dev/null
2940 +++ b/eclass/python-utils-r2.eclass
2941 @@ -0,0 +1,1508 @@
2942 +# Copyright 1999-2020 Gentoo Authors
2943 +# Distributed under the terms of the GNU General Public License v2
2944 +
2945 +# @ECLASS: python-utils-r2.eclass
2946 +# @MAINTAINER:
2947 +# Python team <python@g.o>
2948 +# @AUTHOR:
2949 +# Author: Michał Górny <mgorny@g.o>
2950 +# @SUPPORTED_EAPIS: 5 6 7
2951 +# @BLURB: Utility functions for packages with Python parts.
2952 +# @DESCRIPTION:
2953 +# A utility eclass providing functions to query Python implementations,
2954 +# install Python modules and scripts.
2955 +#
2956 +# This eclass does not set any metadata variables nor export any phase
2957 +# functions. It can be inherited safely.
2958 +#
2959 +# For more information, please see the Python Guide:
2960 +# https://dev.gentoo.org/~mgorny/python-guide/
2961 +
2962 +case "${EAPI:-0}" in
2963 + [0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
2964 + [5-7]) ;;
2965 + *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
2966 +esac
2967 +
2968 +if [[ ${_PYTHON_UTILS_R1} ]]; then
2969 + die 'python-r2 suite eclasses can not be combined with python-r1 suite.'
2970 +fi
2971 +
2972 +if [[ ! ${_PYTHON_UTILS_R2} ]]; then
2973 +
2974 +[[ ${EAPI} == 5 ]] && inherit eutils multilib
2975 +inherit toolchain-funcs
2976 +
2977 +# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
2978 +# @INTERNAL
2979 +# @DESCRIPTION:
2980 +# All supported Python implementations, most preferred last.
2981 +_PYTHON_ALL_IMPLS=(
2982 + pypy3
2983 + python2_7
2984 + python3_6 python3_7 python3_8
2985 +)
2986 +readonly _PYTHON_ALL_IMPLS
2987 +
2988 +# @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
2989 +# @INTERNAL
2990 +# @DESCRIPTION:
2991 +# Set to a non-empty value in order to make eclass tolerate (ignore)
2992 +# unknown implementations in PYTHON_COMPAT.
2993 +#
2994 +# This is intended to be set by the user when using ebuilds that may
2995 +# have unknown (newer) implementations in PYTHON_COMPAT. The assumption
2996 +# is that the ebuilds are intended to be used within multiple contexts
2997 +# which can involve revisions of this eclass that support a different
2998 +# set of Python implementations.
2999 +
3000 +# @FUNCTION: _python_impl_supported
3001 +# @USAGE: <impl>
3002 +# @INTERNAL
3003 +# @DESCRIPTION:
3004 +# Check whether the implementation <impl> (PYTHON_COMPAT-form)
3005 +# is still supported.
3006 +#
3007 +# Returns 0 if the implementation is valid and supported. If it is
3008 +# unsupported, returns 1 -- and the caller should ignore the entry.
3009 +# If it is invalid, dies with an appopriate error messages.
3010 +_python_impl_supported() {
3011 + debug-print-function ${FUNCNAME} "${@}"
3012 +
3013 + [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
3014 +
3015 + local impl=${1}
3016 +
3017 + # keep in sync with _PYTHON_ALL_IMPLS!
3018 + # (not using that list because inline patterns shall be faster)
3019 + case "${impl}" in
3020 + python2_7|python3_[678]|pypy3)
3021 + return 0
3022 + ;;
3023 + jython2_7|pypy|pypy1_[89]|pypy2_0|python2_[56]|python3_[12345])
3024 + return 1
3025 + ;;
3026 + *)
3027 + [[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
3028 + die "Invalid implementation in PYTHON_COMPAT: ${impl}"
3029 + esac
3030 +}
3031 +
3032 +# @FUNCTION: _python_set_impls
3033 +# @INTERNAL
3034 +# @DESCRIPTION:
3035 +# Check PYTHON_COMPAT for well-formedness and validity, then set
3036 +# two global variables:
3037 +#
3038 +# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
3039 +# by the ebuild (PYTHON_COMPAT - dead implementations),
3040 +#
3041 +# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
3042 +# are not supported by the ebuild.
3043 +#
3044 +# Implementations in both variables are ordered using the pre-defined
3045 +# eclass implementation ordering.
3046 +#
3047 +# This function must be called once in global scope by an eclass
3048 +# utilizing PYTHON_COMPAT.
3049 +_python_set_impls() {
3050 + local i
3051 +
3052 + if ! declare -p PYTHON_COMPAT &>/dev/null; then
3053 + die 'PYTHON_COMPAT not declared.'
3054 + fi
3055 + if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
3056 + die 'PYTHON_COMPAT must be an array.'
3057 + fi
3058 + for i in "${PYTHON_COMPAT[@]}"; do
3059 + # trigger validity checks
3060 + _python_impl_supported "${i}"
3061 + done
3062 +
3063 + local supp=() unsupp=()
3064 +
3065 + for i in "${_PYTHON_ALL_IMPLS[@]}"; do
3066 + if has "${i}" "${PYTHON_COMPAT[@]}"; then
3067 + supp+=( "${i}" )
3068 + else
3069 + unsupp+=( "${i}" )
3070 + fi
3071 + done
3072 +
3073 + if [[ ! ${supp[@]} ]]; then
3074 + die "No supported implementation in PYTHON_COMPAT."
3075 + fi
3076 +
3077 + if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
3078 + # set once already, verify integrity
3079 + if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
3080 + eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
3081 + eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
3082 + eerror "Now : ${supp[*]}"
3083 + die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
3084 + fi
3085 + if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
3086 + eerror "Unsupported impls changed between inherits!"
3087 + eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
3088 + eerror "Now : ${unsupp[*]}"
3089 + die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
3090 + fi
3091 + else
3092 + _PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
3093 + _PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
3094 + readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
3095 + fi
3096 +}
3097 +
3098 +# @FUNCTION: _python_impl_matches
3099 +# @USAGE: <impl> [<pattern>...]
3100 +# @INTERNAL
3101 +# @DESCRIPTION:
3102 +# Check whether the specified <impl> matches at least one
3103 +# of the patterns following it. Return 0 if it does, 1 otherwise.
3104 +# Matches if no patterns are provided.
3105 +#
3106 +# <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
3107 +# either:
3108 +# a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
3109 +# b) '-2' to indicate all Python 2 variants (= !python_is_python3)
3110 +# c) '-3' to indicate all Python 3 variants (= python_is_python3)
3111 +_python_impl_matches() {
3112 + [[ ${#} -ge 1 ]] || die "${FUNCNAME}: takes at least 1 parameter"
3113 + [[ ${#} -eq 1 ]] && return 0
3114 +
3115 + local impl=${1} pattern
3116 + shift
3117 +
3118 + for pattern; do
3119 + if [[ ${pattern} == -2 ]]; then
3120 + python_is_python3 "${impl}" || return 0
3121 + elif [[ ${pattern} == -3 ]]; then
3122 + python_is_python3 "${impl}" && return 0
3123 + return
3124 + # unify value style to allow lax matching
3125 + elif [[ ${impl/./_} == ${pattern/./_} ]]; then
3126 + return 0
3127 + fi
3128 + done
3129 +
3130 + return 1
3131 +}
3132 +
3133 +# @ECLASS-VARIABLE: PYTHON
3134 +# @DEFAULT_UNSET
3135 +# @DESCRIPTION:
3136 +# The absolute path to the current Python interpreter.
3137 +#
3138 +# This variable is set automatically in the following contexts:
3139 +#
3140 +# python-r2: Set in functions called by python_foreach_impl() or after
3141 +# calling python_export_best().
3142 +#
3143 +# python-single-r2: Set after calling python-single-r2_pkg_setup().
3144 +#
3145 +# distutils-r2: Set within any of the python sub-phase functions.
3146 +#
3147 +# Example value:
3148 +# @CODE
3149 +# /usr/bin/python2.7
3150 +# @CODE
3151 +
3152 +# @ECLASS-VARIABLE: EPYTHON
3153 +# @DEFAULT_UNSET
3154 +# @DESCRIPTION:
3155 +# The executable name of the current Python interpreter.
3156 +#
3157 +# This variable is set automatically in the following contexts:
3158 +#
3159 +# python-r2: Set in functions called by python_foreach_impl() or after
3160 +# calling python_export_best().
3161 +#
3162 +# python-single-r2: Set after calling python-single-r2_pkg_setup().
3163 +#
3164 +# distutils-r2: Set within any of the python sub-phase functions.
3165 +#
3166 +# Example value:
3167 +# @CODE
3168 +# python2.7
3169 +# @CODE
3170 +
3171 +# @ECLASS-VARIABLE: PYTHON_SITEDIR
3172 +# @DEFAULT_UNSET
3173 +# @DESCRIPTION:
3174 +# The path to Python site-packages directory.
3175 +#
3176 +# Set and exported on request using python_export().
3177 +# Requires a proper build-time dependency on the Python implementation.
3178 +#
3179 +# Example value:
3180 +# @CODE
3181 +# /usr/lib64/python2.7/site-packages
3182 +# @CODE
3183 +
3184 +# @ECLASS-VARIABLE: PYTHON_INCLUDEDIR
3185 +# @DEFAULT_UNSET
3186 +# @DESCRIPTION:
3187 +# The path to Python include directory.
3188 +#
3189 +# Set and exported on request using python_export().
3190 +# Requires a proper build-time dependency on the Python implementation.
3191 +#
3192 +# Example value:
3193 +# @CODE
3194 +# /usr/include/python2.7
3195 +# @CODE
3196 +
3197 +# @ECLASS-VARIABLE: PYTHON_LIBPATH
3198 +# @DEFAULT_UNSET
3199 +# @DESCRIPTION:
3200 +# The path to Python library.
3201 +#
3202 +# Set and exported on request using python_export().
3203 +# Valid only for CPython. Requires a proper build-time dependency
3204 +# on the Python implementation.
3205 +#
3206 +# Example value:
3207 +# @CODE
3208 +# /usr/lib64/libpython2.7.so
3209 +# @CODE
3210 +
3211 +# @ECLASS-VARIABLE: PYTHON_CFLAGS
3212 +# @DEFAULT_UNSET
3213 +# @DESCRIPTION:
3214 +# Proper C compiler flags for building against Python. Obtained from
3215 +# pkg-config or python-config.
3216 +#
3217 +# Set and exported on request using python_export().
3218 +# Valid only for CPython. Requires a proper build-time dependency
3219 +# on the Python implementation and on pkg-config.
3220 +#
3221 +# Example value:
3222 +# @CODE
3223 +# -I/usr/include/python2.7
3224 +# @CODE
3225 +
3226 +# @ECLASS-VARIABLE: PYTHON_LIBS
3227 +# @DEFAULT_UNSET
3228 +# @DESCRIPTION:
3229 +# Proper C compiler flags for linking against Python. Obtained from
3230 +# pkg-config or python-config.
3231 +#
3232 +# Set and exported on request using python_export().
3233 +# Valid only for CPython. Requires a proper build-time dependency
3234 +# on the Python implementation and on pkg-config.
3235 +#
3236 +# Example value:
3237 +# @CODE
3238 +# -lpython2.7
3239 +# @CODE
3240 +
3241 +# @ECLASS-VARIABLE: PYTHON_CONFIG
3242 +# @DEFAULT_UNSET
3243 +# @DESCRIPTION:
3244 +# Path to the python-config executable.
3245 +#
3246 +# Set and exported on request using python_export().
3247 +# Valid only for CPython. Requires a proper build-time dependency
3248 +# on the Python implementation and on pkg-config.
3249 +#
3250 +# Example value:
3251 +# @CODE
3252 +# /usr/bin/python2.7-config
3253 +# @CODE
3254 +
3255 +# @ECLASS-VARIABLE: PYTHON_PKG_DEP
3256 +# @DEFAULT_UNSET
3257 +# @DESCRIPTION:
3258 +# The complete dependency on a particular Python package as a string.
3259 +#
3260 +# Set and exported on request using python_export().
3261 +#
3262 +# Example value:
3263 +# @CODE
3264 +# dev-lang/python:2.7[xml]
3265 +# @CODE
3266 +
3267 +# @ECLASS-VARIABLE: PYTHON_SCRIPTDIR
3268 +# @DEFAULT_UNSET
3269 +# @DESCRIPTION:
3270 +# The location where Python scripts must be installed for current impl.
3271 +#
3272 +# Set and exported on request using python_export().
3273 +#
3274 +# Example value:
3275 +# @CODE
3276 +# /usr/lib/python-exec/python2.7
3277 +# @CODE
3278 +
3279 +# @FUNCTION: python_export
3280 +# @USAGE: [<impl>] <variables>...
3281 +# @DESCRIPTION:
3282 +# Set and export the Python implementation-relevant variables passed
3283 +# as parameters.
3284 +#
3285 +# The optional first parameter may specify the requested Python
3286 +# implementation (either as PYTHON_TARGETS value, e.g. python2_7,
3287 +# or an EPYTHON one, e.g. python2.7). If no implementation passed,
3288 +# the current one will be obtained from ${EPYTHON}.
3289 +#
3290 +# The variables which can be exported are: PYTHON, EPYTHON,
3291 +# PYTHON_SITEDIR. They are described more completely in the eclass
3292 +# variable documentation.
3293 +python_export() {
3294 + debug-print-function ${FUNCNAME} "${@}"
3295 +
3296 + local impl var
3297 +
3298 + case "${1}" in
3299 + python*|jython*)
3300 + impl=${1/_/.}
3301 + shift
3302 + ;;
3303 + pypy|pypy3)
3304 + impl=${1}
3305 + shift
3306 + ;;
3307 + *)
3308 + impl=${EPYTHON}
3309 + if [[ -z ${impl} ]]; then
3310 + die "python_export called without a python implementation and EPYTHON is unset"
3311 + fi
3312 + ;;
3313 + esac
3314 + debug-print "${FUNCNAME}: implementation: ${impl}"
3315 +
3316 + for var; do
3317 + case "${var}" in
3318 + EPYTHON)
3319 + export EPYTHON=${impl}
3320 + debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
3321 + ;;
3322 + PYTHON)
3323 + export PYTHON=${EPREFIX}/usr/bin/${impl}
3324 + debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
3325 + ;;
3326 + PYTHON_SITEDIR)
3327 + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
3328 + # sysconfig can't be used because:
3329 + # 1) pypy doesn't give site-packages but stdlib
3330 + # 2) jython gives paths with wrong case
3331 + PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
3332 + export PYTHON_SITEDIR
3333 + debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
3334 + ;;
3335 + PYTHON_INCLUDEDIR)
3336 + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
3337 + PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
3338 + export PYTHON_INCLUDEDIR
3339 + debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
3340 +
3341 + # Jython gives a non-existing directory
3342 + if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
3343 + die "${impl} does not install any header files!"
3344 + fi
3345 + ;;
3346 + PYTHON_LIBPATH)
3347 + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
3348 + PYTHON_LIBPATH=$("${PYTHON}" -c 'import os.path, sysconfig; print(os.path.join(sysconfig.get_config_var("LIBDIR"), sysconfig.get_config_var("LDLIBRARY")) if sysconfig.get_config_var("LDLIBRARY") else "")') || die
3349 + export PYTHON_LIBPATH
3350 + debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
3351 +
3352 + if [[ ! ${PYTHON_LIBPATH} ]]; then
3353 + die "${impl} lacks a (usable) dynamic library"
3354 + fi
3355 + ;;
3356 + PYTHON_CFLAGS)
3357 + local val
3358 +
3359 + case "${impl}" in
3360 + python*)
3361 + # python-2.7, python-3.2, etc.
3362 + val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
3363 + ;;
3364 + *)
3365 + die "${impl}: obtaining ${var} not supported"
3366 + ;;
3367 + esac
3368 +
3369 + export PYTHON_CFLAGS=${val}
3370 + debug-print "${FUNCNAME}: PYTHON_CFLAGS = ${PYTHON_CFLAGS}"
3371 + ;;
3372 + PYTHON_LIBS)
3373 + local val
3374 +
3375 + case "${impl}" in
3376 + python*)
3377 + # python-2.7, python-3.2, etc.
3378 + val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
3379 + ;;
3380 + *)
3381 + die "${impl}: obtaining ${var} not supported"
3382 + ;;
3383 + esac
3384 +
3385 + export PYTHON_LIBS=${val}
3386 + debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
3387 + ;;
3388 + PYTHON_CONFIG)
3389 + local flags val
3390 +
3391 + case "${impl}" in
3392 + python*)
3393 + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
3394 + flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
3395 + val=${PYTHON}${flags}-config
3396 + ;;
3397 + *)
3398 + die "${impl}: obtaining ${var} not supported"
3399 + ;;
3400 + esac
3401 +
3402 + export PYTHON_CONFIG=${val}
3403 + debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
3404 + ;;
3405 + PYTHON_PKG_DEP)
3406 + local d
3407 + case ${impl} in
3408 + python2.7)
3409 + PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
3410 + python3.3)
3411 + PYTHON_PKG_DEP='>=dev-lang/python-3.3.2-r2:3.3';;
3412 + python*)
3413 + PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
3414 + pypy)
3415 + PYTHON_PKG_DEP='>=dev-python/pypy-5:0=';;
3416 + pypy3)
3417 + PYTHON_PKG_DEP='>=dev-python/pypy3-5:0=';;
3418 + jython2.7)
3419 + PYTHON_PKG_DEP='dev-java/jython:2.7';;
3420 + *)
3421 + die "Invalid implementation: ${impl}"
3422 + esac
3423 +
3424 + # use-dep
3425 + if [[ ${PYTHON_REQ_USE} ]]; then
3426 + PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
3427 + fi
3428 +
3429 + export PYTHON_PKG_DEP
3430 + debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
3431 + ;;
3432 + PYTHON_SCRIPTDIR)
3433 + local dir
3434 + export PYTHON_SCRIPTDIR=${EPREFIX}/usr/lib/python-exec/${impl}
3435 + debug-print "${FUNCNAME}: PYTHON_SCRIPTDIR = ${PYTHON_SCRIPTDIR}"
3436 + ;;
3437 + *)
3438 + die "python_export: unknown variable ${var}"
3439 + esac
3440 + done
3441 +}
3442 +
3443 +# @FUNCTION: python_get_sitedir
3444 +# @USAGE: [<impl>]
3445 +# @DESCRIPTION:
3446 +# Obtain and print the 'site-packages' path for the given
3447 +# implementation. If no implementation is provided, ${EPYTHON} will
3448 +# be used.
3449 +#
3450 +# If you just need to have PYTHON_SITEDIR set (and exported), then it is
3451 +# better to use python_export() directly instead.
3452 +python_get_sitedir() {
3453 + debug-print-function ${FUNCNAME} "${@}"
3454 +
3455 + python_export "${@}" PYTHON_SITEDIR
3456 + echo "${PYTHON_SITEDIR}"
3457 +}
3458 +
3459 +# @FUNCTION: python_get_includedir
3460 +# @USAGE: [<impl>]
3461 +# @DESCRIPTION:
3462 +# Obtain and print the include path for the given implementation. If no
3463 +# implementation is provided, ${EPYTHON} will be used.
3464 +#
3465 +# If you just need to have PYTHON_INCLUDEDIR set (and exported), then it
3466 +# is better to use python_export() directly instead.
3467 +python_get_includedir() {
3468 + debug-print-function ${FUNCNAME} "${@}"
3469 +
3470 + python_export "${@}" PYTHON_INCLUDEDIR
3471 + echo "${PYTHON_INCLUDEDIR}"
3472 +}
3473 +
3474 +# @FUNCTION: python_get_library_path
3475 +# @USAGE: [<impl>]
3476 +# @DESCRIPTION:
3477 +# Obtain and print the Python library path for the given implementation.
3478 +# If no implementation is provided, ${EPYTHON} will be used.
3479 +#
3480 +# Please note that this function can be used with CPython only. Use
3481 +# in another implementation will result in a fatal failure.
3482 +python_get_library_path() {
3483 + debug-print-function ${FUNCNAME} "${@}"
3484 +
3485 + python_export "${@}" PYTHON_LIBPATH
3486 + echo "${PYTHON_LIBPATH}"
3487 +}
3488 +
3489 +# @FUNCTION: python_get_CFLAGS
3490 +# @USAGE: [<impl>]
3491 +# @DESCRIPTION:
3492 +# Obtain and print the compiler flags for building against Python,
3493 +# for the given implementation. If no implementation is provided,
3494 +# ${EPYTHON} will be used.
3495 +#
3496 +# Please note that this function can be used with CPython only.
3497 +# It requires Python and pkg-config installed, and therefore proper
3498 +# build-time dependencies need be added to the ebuild.
3499 +python_get_CFLAGS() {
3500 + debug-print-function ${FUNCNAME} "${@}"
3501 +
3502 + python_export "${@}" PYTHON_CFLAGS
3503 + echo "${PYTHON_CFLAGS}"
3504 +}
3505 +
3506 +# @FUNCTION: python_get_LIBS
3507 +# @USAGE: [<impl>]
3508 +# @DESCRIPTION:
3509 +# Obtain and print the compiler flags for linking against Python,
3510 +# for the given implementation. If no implementation is provided,
3511 +# ${EPYTHON} will be used.
3512 +#
3513 +# Please note that this function can be used with CPython only.
3514 +# It requires Python and pkg-config installed, and therefore proper
3515 +# build-time dependencies need be added to the ebuild.
3516 +python_get_LIBS() {
3517 + debug-print-function ${FUNCNAME} "${@}"
3518 +
3519 + python_export "${@}" PYTHON_LIBS
3520 + echo "${PYTHON_LIBS}"
3521 +}
3522 +
3523 +# @FUNCTION: python_get_PYTHON_CONFIG
3524 +# @USAGE: [<impl>]
3525 +# @DESCRIPTION:
3526 +# Obtain and print the PYTHON_CONFIG location for the given
3527 +# implementation. If no implementation is provided, ${EPYTHON} will be
3528 +# used.
3529 +#
3530 +# Please note that this function can be used with CPython only.
3531 +# It requires Python installed, and therefore proper build-time
3532 +# dependencies need be added to the ebuild.
3533 +python_get_PYTHON_CONFIG() {
3534 + debug-print-function ${FUNCNAME} "${@}"
3535 +
3536 + python_export "${@}" PYTHON_CONFIG
3537 + echo "${PYTHON_CONFIG}"
3538 +}
3539 +
3540 +# @FUNCTION: python_get_scriptdir
3541 +# @USAGE: [<impl>]
3542 +# @DESCRIPTION:
3543 +# Obtain and print the script install path for the given
3544 +# implementation. If no implementation is provided, ${EPYTHON} will
3545 +# be used.
3546 +python_get_scriptdir() {
3547 + debug-print-function ${FUNCNAME} "${@}"
3548 +
3549 + python_export "${@}" PYTHON_SCRIPTDIR
3550 + echo "${PYTHON_SCRIPTDIR}"
3551 +}
3552 +
3553 +# @FUNCTION: _python_ln_rel
3554 +# @USAGE: <from> <to>
3555 +# @INTERNAL
3556 +# @DESCRIPTION:
3557 +# Create a relative symlink.
3558 +_python_ln_rel() {
3559 + debug-print-function ${FUNCNAME} "${@}"
3560 +
3561 + local target=${1}
3562 + local symname=${2}
3563 +
3564 + local tgpath=${target%/*}/
3565 + local sympath=${symname%/*}/
3566 + local rel_target=
3567 +
3568 + while [[ ${sympath} ]]; do
3569 + local tgseg= symseg=
3570 +
3571 + while [[ ! ${tgseg} && ${tgpath} ]]; do
3572 + tgseg=${tgpath%%/*}
3573 + tgpath=${tgpath#${tgseg}/}
3574 + done
3575 +
3576 + while [[ ! ${symseg} && ${sympath} ]]; do
3577 + symseg=${sympath%%/*}
3578 + sympath=${sympath#${symseg}/}
3579 + done
3580 +
3581 + if [[ ${tgseg} != ${symseg} ]]; then
3582 + rel_target=../${rel_target}${tgseg:+${tgseg}/}
3583 + fi
3584 + done
3585 + rel_target+=${tgpath}${target##*/}
3586 +
3587 + debug-print "${FUNCNAME}: ${symname} -> ${target}"
3588 + debug-print "${FUNCNAME}: rel_target = ${rel_target}"
3589 +
3590 + ln -fs "${rel_target}" "${symname}"
3591 +}
3592 +
3593 +# @FUNCTION: python_optimize
3594 +# @USAGE: [<directory>...]
3595 +# @DESCRIPTION:
3596 +# Compile and optimize Python modules in specified directories (absolute
3597 +# paths). If no directories are provided, the default system paths
3598 +# are used (prepended with ${D}).
3599 +python_optimize() {
3600 + debug-print-function ${FUNCNAME} "${@}"
3601 +
3602 + if [[ ${EBUILD_PHASE} == pre* || ${EBUILD_PHASE} == post* ]]; then
3603 + eerror "The new Python eclasses expect the compiled Python files to"
3604 + eerror "be controlled by the Package Manager. For this reason,"
3605 + eerror "the python_optimize function can be used only during src_* phases"
3606 + eerror "(src_install most commonly) and not during pkg_* phases."
3607 + echo
3608 + die "python_optimize is not to be used in pre/post* phases"
3609 + fi
3610 +
3611 + [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
3612 +
3613 + local PYTHON=${PYTHON}
3614 + [[ ${PYTHON} ]] || python_export PYTHON
3615 +
3616 + # default to sys.path
3617 + if [[ ${#} -eq 0 ]]; then
3618 + local f
3619 + while IFS= read -r -d '' f; do
3620 + # 1) accept only absolute paths
3621 + # (i.e. skip '', '.' or anything like that)
3622 + # 2) skip paths which do not exist
3623 + # (python2.6 complains about them verbosely)
3624 +
3625 + if [[ ${f} == /* && -d ${D%/}${f} ]]; then
3626 + set -- "${D%/}${f}" "${@}"
3627 + fi
3628 + done < <("${PYTHON}" -c 'import sys; print("".join(x + "\0" for x in sys.path))' || die)
3629 +
3630 + debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
3631 + fi
3632 +
3633 + local d
3634 + for d; do
3635 + # make sure to get a nice path without //
3636 + local instpath=${d#${D%/}}
3637 + instpath=/${instpath##/}
3638 +
3639 + case "${EPYTHON}" in
3640 + python2.7|python3.[34])
3641 + "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
3642 + "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
3643 + ;;
3644 + python*|pypy3)
3645 + # both levels of optimization are separate since 3.5
3646 + "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
3647 + "${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
3648 + "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
3649 + ;;
3650 + *)
3651 + "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
3652 + ;;
3653 + esac
3654 + done
3655 +}
3656 +
3657 +# @FUNCTION: python_scriptinto
3658 +# @USAGE: <new-path>
3659 +# @DESCRIPTION:
3660 +# Set the directory to which files passed to python_doexe(),
3661 +# python_doscript(), python_newexe() and python_newscript()
3662 +# are going to be installed. The new value needs to be relative
3663 +# to the installation root (${ED}).
3664 +#
3665 +# If not set explicitly, the directory defaults to /usr/bin.
3666 +#
3667 +# Example:
3668 +# @CODE
3669 +# src_install() {
3670 +# python_scriptinto /usr/sbin
3671 +# python_foreach_impl python_doscript foo
3672 +# }
3673 +# @CODE
3674 +python_scriptinto() {
3675 + debug-print-function ${FUNCNAME} "${@}"
3676 +
3677 + python_scriptroot=${1}
3678 +}
3679 +
3680 +# @FUNCTION: python_doexe
3681 +# @USAGE: <files>...
3682 +# @DESCRIPTION:
3683 +# Install the given executables into the executable install directory,
3684 +# for the current Python implementation (${EPYTHON}).
3685 +#
3686 +# The executable will be wrapped properly for the Python implementation,
3687 +# though no shebang mangling will be performed.
3688 +python_doexe() {
3689 + debug-print-function ${FUNCNAME} "${@}"
3690 +
3691 + local f
3692 + for f; do
3693 + python_newexe "${f}" "${f##*/}"
3694 + done
3695 +}
3696 +
3697 +# @FUNCTION: python_newexe
3698 +# @USAGE: <path> <new-name>
3699 +# @DESCRIPTION:
3700 +# Install the given executable into the executable install directory,
3701 +# for the current Python implementation (${EPYTHON}).
3702 +#
3703 +# The executable will be wrapped properly for the Python implementation,
3704 +# though no shebang mangling will be performed. It will be renamed
3705 +# to <new-name>.
3706 +python_newexe() {
3707 + debug-print-function ${FUNCNAME} "${@}"
3708 +
3709 + [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
3710 + [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
3711 +
3712 + local wrapd=${python_scriptroot:-/usr/bin}
3713 +
3714 + local f=${1}
3715 + local newfn=${2}
3716 +
3717 + local PYTHON_SCRIPTDIR d
3718 + python_export PYTHON_SCRIPTDIR
3719 + d=${PYTHON_SCRIPTDIR#${EPREFIX}}
3720 +
3721 + (
3722 + dodir "${wrapd}"
3723 + exeopts -m 0755
3724 + exeinto "${d}"
3725 + newexe "${f}" "${newfn}" || return ${?}
3726 + )
3727 +
3728 + # install the wrapper
3729 + _python_ln_rel "${ED%/}"/usr/lib/python-exec/python-exec2 \
3730 + "${ED%/}/${wrapd}/${newfn}" || die
3731 +
3732 + # don't use this at home, just call python_doscript() instead
3733 + if [[ ${_PYTHON_REWRITE_SHEBANG} ]]; then
3734 + python_fix_shebang -q "${ED%/}/${d}/${newfn}"
3735 + fi
3736 +}
3737 +
3738 +# @FUNCTION: python_doscript
3739 +# @USAGE: <files>...
3740 +# @DESCRIPTION:
3741 +# Install the given scripts into the executable install directory,
3742 +# for the current Python implementation (${EPYTHON}).
3743 +#
3744 +# All specified files must start with a 'python' shebang. The shebang
3745 +# will be converted, and the files will be wrapped properly
3746 +# for the Python implementation.
3747 +#
3748 +# Example:
3749 +# @CODE
3750 +# src_install() {
3751 +# python_foreach_impl python_doscript ${PN}
3752 +# }
3753 +# @CODE
3754 +python_doscript() {
3755 + debug-print-function ${FUNCNAME} "${@}"
3756 +
3757 + local _PYTHON_REWRITE_SHEBANG=1
3758 + python_doexe "${@}"
3759 +}
3760 +
3761 +# @FUNCTION: python_newscript
3762 +# @USAGE: <path> <new-name>
3763 +# @DESCRIPTION:
3764 +# Install the given script into the executable install directory
3765 +# for the current Python implementation (${EPYTHON}), and name it
3766 +# <new-name>.
3767 +#
3768 +# The file must start with a 'python' shebang. The shebang will be
3769 +# converted, and the file will be wrapped properly for the Python
3770 +# implementation. It will be renamed to <new-name>.
3771 +#
3772 +# Example:
3773 +# @CODE
3774 +# src_install() {
3775 +# python_foreach_impl python_newscript foo.py foo
3776 +# }
3777 +# @CODE
3778 +python_newscript() {
3779 + debug-print-function ${FUNCNAME} "${@}"
3780 +
3781 + local _PYTHON_REWRITE_SHEBANG=1
3782 + python_newexe "${@}"
3783 +}
3784 +
3785 +# @FUNCTION: python_moduleinto
3786 +# @USAGE: <new-path>
3787 +# @DESCRIPTION:
3788 +# Set the Python module install directory for python_domodule().
3789 +# The <new-path> can either be an absolute target system path (in which
3790 +# case it needs to start with a slash, and ${ED} will be prepended to
3791 +# it) or relative to the implementation's site-packages directory
3792 +# (then it must not start with a slash). The relative path can be
3793 +# specified either using the Python package notation (separated by dots)
3794 +# or the directory notation (using slashes).
3795 +#
3796 +# When not set explicitly, the modules are installed to the top
3797 +# site-packages directory.
3798 +#
3799 +# In the relative case, the exact path is determined directly
3800 +# by each python_doscript/python_newscript function. Therefore,
3801 +# python_moduleinto can be safely called before establishing the Python
3802 +# interpreter and/or a single call can be used to set the path correctly
3803 +# for multiple implementations, as can be seen in the following example.
3804 +#
3805 +# Example:
3806 +# @CODE
3807 +# src_install() {
3808 +# python_moduleinto bar
3809 +# # installs ${PYTHON_SITEDIR}/bar/baz.py
3810 +# python_foreach_impl python_domodule baz.py
3811 +# }
3812 +# @CODE
3813 +python_moduleinto() {
3814 + debug-print-function ${FUNCNAME} "${@}"
3815 +
3816 + python_moduleroot=${1}
3817 +}
3818 +
3819 +# @FUNCTION: python_domodule
3820 +# @USAGE: <files>...
3821 +# @DESCRIPTION:
3822 +# Install the given modules (or packages) into the current Python module
3823 +# installation directory. The list can mention both modules (files)
3824 +# and packages (directories). All listed files will be installed
3825 +# for all enabled implementations, and compiled afterwards.
3826 +#
3827 +# Example:
3828 +# @CODE
3829 +# src_install() {
3830 +# # (${PN} being a directory)
3831 +# python_foreach_impl python_domodule ${PN}
3832 +# }
3833 +# @CODE
3834 +python_domodule() {
3835 + debug-print-function ${FUNCNAME} "${@}"
3836 +
3837 + [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
3838 +
3839 + local d
3840 + if [[ ${python_moduleroot} == /* ]]; then
3841 + # absolute path
3842 + d=${python_moduleroot}
3843 + else
3844 + # relative to site-packages
3845 + local PYTHON_SITEDIR=${PYTHON_SITEDIR}
3846 + [[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
3847 +
3848 + d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot//.//}
3849 + fi
3850 +
3851 + (
3852 + insopts -m 0644
3853 + insinto "${d}"
3854 + doins -r "${@}" || return ${?}
3855 + )
3856 +
3857 + python_optimize "${ED%/}/${d}"
3858 +}
3859 +
3860 +# @FUNCTION: python_doheader
3861 +# @USAGE: <files>...
3862 +# @DESCRIPTION:
3863 +# Install the given headers into the implementation-specific include
3864 +# directory. This function is unconditionally recursive, i.e. you can
3865 +# pass directories instead of files.
3866 +#
3867 +# Example:
3868 +# @CODE
3869 +# src_install() {
3870 +# python_foreach_impl python_doheader foo.h bar.h
3871 +# }
3872 +# @CODE
3873 +python_doheader() {
3874 + debug-print-function ${FUNCNAME} "${@}"
3875 +
3876 + [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
3877 +
3878 + local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
3879 + [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
3880 +
3881 + d=${PYTHON_INCLUDEDIR#${EPREFIX}}
3882 +
3883 + (
3884 + insopts -m 0644
3885 + insinto "${d}"
3886 + doins -r "${@}" || return ${?}
3887 + )
3888 +}
3889 +
3890 +# @FUNCTION: python_wrapper_setup
3891 +# @USAGE: [<path> [<impl>]]
3892 +# @DESCRIPTION:
3893 +# Create proper 'python' executable and pkg-config wrappers
3894 +# (if available) in the directory named by <path>. Set up PATH
3895 +# and PKG_CONFIG_PATH appropriately. <path> defaults to ${T}/${EPYTHON}.
3896 +#
3897 +# The wrappers will be created for implementation named by <impl>,
3898 +# or for one named by ${EPYTHON} if no <impl> passed.
3899 +#
3900 +# If the named directory contains a python symlink already, it will
3901 +# be assumed to contain proper wrappers already and only environment
3902 +# setup will be done. If wrapper update is requested, the directory
3903 +# shall be removed first.
3904 +python_wrapper_setup() {
3905 + debug-print-function ${FUNCNAME} "${@}"
3906 +
3907 + local workdir=${1:-${T}/${EPYTHON}}
3908 + local impl=${2:-${EPYTHON}}
3909 +
3910 + [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
3911 + [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON specified."
3912 +
3913 + if [[ ! -x ${workdir}/bin/python ]]; then
3914 + _python_check_dead_variables
3915 +
3916 + mkdir -p "${workdir}"/{bin,pkgconfig} || die
3917 +
3918 + # Clean up, in case we were supposed to do a cheap update.
3919 + rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
3920 + rm -f "${workdir}"/bin/2to3 || die
3921 + rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
3922 +
3923 + local EPYTHON PYTHON
3924 + python_export "${impl}" EPYTHON PYTHON
3925 +
3926 + local pyver pyother
3927 + if python_is_python3; then
3928 + pyver=3
3929 + pyother=2
3930 + else
3931 + pyver=2
3932 + pyother=3
3933 + fi
3934 +
3935 + # Python interpreter
3936 + # note: we don't use symlinks because python likes to do some
3937 + # symlink reading magic that breaks stuff
3938 + # https://bugs.gentoo.org/show_bug.cgi?id=555752
3939 + cat > "${workdir}/bin/python" <<-_EOF_ || die
3940 + #!/bin/sh
3941 + exec "${PYTHON}" "\${@}"
3942 + _EOF_
3943 + cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
3944 + chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
3945 +
3946 + local nonsupp=( "python${pyother}" "python${pyother}-config" )
3947 +
3948 + # CPython-specific
3949 + if [[ ${EPYTHON} == python* ]]; then
3950 + cat > "${workdir}/bin/python-config" <<-_EOF_ || die
3951 + #!/bin/sh
3952 + exec "${PYTHON}-config" "\${@}"
3953 + _EOF_
3954 + cp "${workdir}/bin/python-config" \
3955 + "${workdir}/bin/python${pyver}-config" || die
3956 + chmod +x "${workdir}/bin/python-config" \
3957 + "${workdir}/bin/python${pyver}-config" || die
3958 +
3959 + # Python 2.6+.
3960 + ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
3961 +
3962 + # Python 2.7+.
3963 + ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}.pc \
3964 + "${workdir}"/pkgconfig/python.pc || die
3965 + ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die
3966 + else
3967 + nonsupp+=( 2to3 python-config "python${pyver}-config" )
3968 + fi
3969 +
3970 + local x
3971 + for x in "${nonsupp[@]}"; do
3972 + cat >"${workdir}"/bin/${x} <<-_EOF_ || die
3973 + #!/bin/sh
3974 + echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
3975 + exit 127
3976 + _EOF_
3977 + chmod +x "${workdir}"/bin/${x} || die
3978 + done
3979 + fi
3980 +
3981 + # Now, set the environment.
3982 + # But note that ${workdir} may be shared with something else,
3983 + # and thus already on top of PATH.
3984 + if [[ ${PATH##:*} != ${workdir}/bin ]]; then
3985 + PATH=${workdir}/bin${PATH:+:${PATH}}
3986 + fi
3987 + if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
3988 + PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
3989 + fi
3990 + export PATH PKG_CONFIG_PATH
3991 +}
3992 +
3993 +# @FUNCTION: python_is_python3
3994 +# @USAGE: [<impl>]
3995 +# @DESCRIPTION:
3996 +# Check whether <impl> (or ${EPYTHON}) is a Python3k variant
3997 +# (i.e. uses syntax and stdlib of Python 3.*).
3998 +#
3999 +# Returns 0 (true) if it is, 1 (false) otherwise.
4000 +python_is_python3() {
4001 + local impl=${1:-${EPYTHON}}
4002 + [[ ${impl} ]] || die "python_is_python3: no impl nor EPYTHON"
4003 +
4004 + [[ ${impl} == python3* || ${impl} == pypy3 ]]
4005 +}
4006 +
4007 +# @FUNCTION: python_is_installed
4008 +# @USAGE: [<impl>]
4009 +# @DESCRIPTION:
4010 +# Check whether the interpreter for <impl> (or ${EPYTHON}) is installed.
4011 +# Uses has_version with a proper dependency string.
4012 +#
4013 +# Returns 0 (true) if it is, 1 (false) otherwise.
4014 +python_is_installed() {
4015 + local impl=${1:-${EPYTHON}}
4016 + [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
4017 + local hasv_args=()
4018 +
4019 + case ${EAPI} in
4020 + 5|6)
4021 + hasv_args+=( --host-root )
4022 + ;;
4023 + *)
4024 + hasv_args+=( -b )
4025 + ;;
4026 + esac
4027 +
4028 + local PYTHON_PKG_DEP
4029 + python_export "${impl}" PYTHON_PKG_DEP
4030 + has_version "${hasv_args[@]}" "${PYTHON_PKG_DEP}"
4031 +}
4032 +
4033 +# @FUNCTION: python_fix_shebang
4034 +# @USAGE: [-f|--force] [-q|--quiet] <path>...
4035 +# @DESCRIPTION:
4036 +# Replace the shebang in Python scripts with the current Python
4037 +# implementation (EPYTHON). If a directory is passed, works recursively
4038 +# on all Python scripts.
4039 +#
4040 +# Only files having a 'python*' shebang will be modified. Files with
4041 +# other shebang will either be skipped when working recursively
4042 +# on a directory or treated as error when specified explicitly.
4043 +#
4044 +# Shebangs matching explicitly current Python version will be left
4045 +# unmodified. Shebangs requesting another Python version will be treated
4046 +# as fatal error, unless --force is given.
4047 +#
4048 +# --force causes the function to replace even shebangs that require
4049 +# incompatible Python version. --quiet causes the function not to list
4050 +# modified files verbosely.
4051 +python_fix_shebang() {
4052 + debug-print-function ${FUNCNAME} "${@}"
4053 +
4054 + [[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)"
4055 +
4056 + local force quiet
4057 + while [[ ${@} ]]; do
4058 + case "${1}" in
4059 + -f|--force) force=1; shift;;
4060 + -q|--quiet) quiet=1; shift;;
4061 + --) shift; break;;
4062 + *) break;;
4063 + esac
4064 + done
4065 +
4066 + [[ ${1} ]] || die "${FUNCNAME}: no paths given"
4067 +
4068 + local path f
4069 + for path; do
4070 + local any_correct any_fixed is_recursive
4071 +
4072 + [[ -d ${path} ]] && is_recursive=1
4073 +
4074 + while IFS= read -r -d '' f; do
4075 + local shebang i
4076 + local error= from=
4077 +
4078 + # note: we can't ||die here since read will fail if file
4079 + # has no newline characters
4080 + IFS= read -r shebang <"${f}"
4081 +
4082 + # First, check if it's shebang at all...
4083 + if [[ ${shebang} == '#!'* ]]; then
4084 + local split_shebang=()
4085 + read -r -a split_shebang <<<${shebang} || die
4086 +
4087 + # Match left-to-right in a loop, to avoid matching random
4088 + # repetitions like 'python2.7 python2'.
4089 + for i in "${split_shebang[@]}"; do
4090 + case "${i}" in
4091 + *"${EPYTHON}")
4092 + debug-print "${FUNCNAME}: in file ${f#${D%/}}"
4093 + debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
4094 +
4095 + # Nothing to do, move along.
4096 + any_correct=1
4097 + from=${EPYTHON}
4098 + break
4099 + ;;
4100 + *python|*python[23])
4101 + debug-print "${FUNCNAME}: in file ${f#${D%/}}"
4102 + debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"
4103 +
4104 + if [[ ${i} == *python2 ]]; then
4105 + from=python2
4106 + if [[ ! ${force} ]]; then
4107 + python_is_python3 "${EPYTHON}" && error=1
4108 + fi
4109 + elif [[ ${i} == *python3 ]]; then
4110 + from=python3
4111 + if [[ ! ${force} ]]; then
4112 + python_is_python3 "${EPYTHON}" || error=1
4113 + fi
4114 + else
4115 + from=python
4116 + fi
4117 + break
4118 + ;;
4119 + *python[23].[0123456789]|*pypy|*pypy3|*jython[23].[0123456789])
4120 + # Explicit mismatch.
4121 + if [[ ! ${force} ]]; then
4122 + error=1
4123 + else
4124 + case "${i}" in
4125 + *python[23].[0123456789])
4126 + from="python[23].[0123456789]";;
4127 + *pypy)
4128 + from="pypy";;
4129 + *pypy3)
4130 + from="pypy3";;
4131 + *jython[23].[0123456789])
4132 + from="jython[23].[0123456789]";;
4133 + *)
4134 + die "${FUNCNAME}: internal error in 2nd pattern match";;
4135 + esac
4136 + fi
4137 + break
4138 + ;;
4139 + esac
4140 + done
4141 + fi
4142 +
4143 + if [[ ! ${error} && ! ${from} ]]; then
4144 + # Non-Python shebang. Allowed in recursive mode,
4145 + # disallowed when specifying file explicitly.
4146 + [[ ${is_recursive} ]] && continue
4147 + error=1
4148 + fi
4149 +
4150 + if [[ ! ${quiet} ]]; then
4151 + einfo "Fixing shebang in ${f#${D%/}}."
4152 + fi
4153 +
4154 + if [[ ! ${error} ]]; then
4155 + # We either want to match ${from} followed by space
4156 + # or at end-of-string.
4157 + if [[ ${shebang} == *${from}" "* ]]; then
4158 + sed -i -e "1s:${from} :${EPYTHON} :" "${f}" || die
4159 + else
4160 + sed -i -e "1s:${from}$:${EPYTHON}:" "${f}" || die
4161 + fi
4162 + any_fixed=1
4163 + else
4164 + eerror "The file has incompatible shebang:"
4165 + eerror " file: ${f#${D%/}}"
4166 + eerror " current shebang: ${shebang}"
4167 + eerror " requested impl: ${EPYTHON}"
4168 + die "${FUNCNAME}: conversion of incompatible shebang requested"
4169 + fi
4170 + done < <(find -H "${path}" -type f -print0 || die)
4171 +
4172 + if [[ ! ${any_fixed} ]]; then
4173 + local cmd=eerror
4174 + [[ ${EAPI} == 5 ]] && cmd=eqawarn
4175 +
4176 + "${cmd}" "QA warning: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files."
4177 + if [[ ${any_correct} ]]; then
4178 + "${cmd}" "All files have ${EPYTHON} shebang already."
4179 + else
4180 + "${cmd}" "There are no Python files in specified directory."
4181 + fi
4182 +
4183 + [[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})"
4184 + fi
4185 + done
4186 +}
4187 +
4188 +# @FUNCTION: _python_check_locale_sanity
4189 +# @USAGE: <locale>
4190 +# @INTERNAL
4191 +# @RETURN: 0 if sane, 1 otherwise
4192 +# @DESCRIPTION:
4193 +# Check whether the specified locale sanely maps between lowercase
4194 +# and uppercase ASCII characters.
4195 +_python_check_locale_sanity() {
4196 + local -x LC_ALL=${1}
4197 + local IFS=
4198 +
4199 + local lc=( {a..z} )
4200 + local uc=( {A..Z} )
4201 + local input="${lc[*]}${uc[*]}"
4202 +
4203 + local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}")
4204 + [[ ${output} == "${uc[*]}${lc[*]}" ]]
4205 +}
4206 +
4207 +# @FUNCTION: python_export_utf8_locale
4208 +# @RETURN: 0 on success, 1 on failure.
4209 +# @DESCRIPTION:
4210 +# Attempts to export a usable UTF-8 locale in the LC_CTYPE variable. Does
4211 +# nothing if LC_ALL is defined, or if the current locale uses a UTF-8 charmap.
4212 +# This may be used to work around the quirky open() behavior of python3.
4213 +python_export_utf8_locale() {
4214 + debug-print-function ${FUNCNAME} "${@}"
4215 +
4216 + # If the locale program isn't available, just return.
4217 + type locale >/dev/null || return 0
4218 +
4219 + if [[ $(locale charmap) != UTF-8 ]]; then
4220 + # Try English first, then everything else.
4221 + local lang locales="C.UTF-8 en_US.UTF-8 en_GB.UTF-8 $(locale -a)"
4222 +
4223 + for lang in ${locales}; do
4224 + if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
4225 + if _python_check_locale_sanity "${lang}"; then
4226 + export LC_CTYPE=${lang}
4227 + if [[ -n ${LC_ALL} ]]; then
4228 + export LC_NUMERIC=${LC_ALL}
4229 + export LC_TIME=${LC_ALL}
4230 + export LC_COLLATE=${LC_ALL}
4231 + export LC_MONETARY=${LC_ALL}
4232 + export LC_MESSAGES=${LC_ALL}
4233 + export LC_PAPER=${LC_ALL}
4234 + export LC_NAME=${LC_ALL}
4235 + export LC_ADDRESS=${LC_ALL}
4236 + export LC_TELEPHONE=${LC_ALL}
4237 + export LC_MEASUREMENT=${LC_ALL}
4238 + export LC_IDENTIFICATION=${LC_ALL}
4239 + export LC_ALL=
4240 + fi
4241 + return 0
4242 + fi
4243 + fi
4244 + done
4245 +
4246 + ewarn "Could not find a UTF-8 locale. This may trigger build failures in"
4247 + ewarn "some python packages. Please ensure that a UTF-8 locale is listed in"
4248 + ewarn "/etc/locale.gen and run locale-gen."
4249 + return 1
4250 + fi
4251 +
4252 + return 0
4253 +}
4254 +
4255 +# @FUNCTION: build_sphinx
4256 +# @USAGE: <directory>
4257 +# @DESCRIPTION:
4258 +# Build HTML documentation using dev-python/sphinx in the specified
4259 +# <directory>. Takes care of disabling Intersphinx and appending
4260 +# to HTML_DOCS.
4261 +#
4262 +# If <directory> is relative to the current directory, care needs
4263 +# to be taken to run einstalldocs from the same directory
4264 +# (usually ${S}).
4265 +build_sphinx() {
4266 + debug-print-function ${FUNCNAME} "${@}"
4267 + [[ ${#} -eq 1 ]] || die "${FUNCNAME} takes 1 arg: <directory>"
4268 +
4269 + local dir=${1}
4270 +
4271 + sed -i -e 's:^intersphinx_mapping:disabled_&:' \
4272 + "${dir}"/conf.py || die
4273 + # not all packages include the Makefile in pypi tarball
4274 + sphinx-build -b html -d "${dir}"/_build/doctrees "${dir}" \
4275 + "${dir}"/_build/html || die
4276 +
4277 + HTML_DOCS+=( "${dir}/_build/html/." )
4278 +}
4279 +
4280 +# -- python.eclass functions --
4281 +
4282 +_python_check_dead_variables() {
4283 + local v
4284 +
4285 + for v in PYTHON_DEPEND PYTHON_USE_WITH{,_OR,_OPT} {RESTRICT,SUPPORT}_PYTHON_ABIS
4286 + do
4287 + if [[ ${!v} ]]; then
4288 + die "${v} is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Ebuild_head"
4289 + fi
4290 + done
4291 +
4292 + for v in PYTHON_{CPPFLAGS,CFLAGS,CXXFLAGS,LDFLAGS}
4293 + do
4294 + if [[ ${!v} ]]; then
4295 + die "${v} is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#PYTHON_CFLAGS"
4296 + fi
4297 + done
4298 +
4299 + for v in PYTHON_TESTS_RESTRICTED_ABIS PYTHON_EXPORT_PHASE_FUNCTIONS \
4300 + PYTHON_VERSIONED_{SCRIPTS,EXECUTABLES} PYTHON_NONVERSIONED_EXECUTABLES
4301 + do
4302 + if [[ ${!v} ]]; then
4303 + die "${v} is invalid for python-r2 suite"
4304 + fi
4305 + done
4306 +
4307 + for v in DISTUTILS_USE_SEPARATE_SOURCE_DIRECTORIES DISTUTILS_SETUP_FILES \
4308 + DISTUTILS_GLOBAL_OPTIONS DISTUTILS_SRC_TEST PYTHON_MODNAME
4309 + do
4310 + if [[ ${!v} ]]; then
4311 + die "${v} is invalid for distutils-r2, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#${v}"
4312 + fi
4313 + done
4314 +
4315 + if [[ ${DISTUTILS_DISABLE_TEST_DEPENDENCY} ]]; then
4316 + die "${v} is invalid for distutils-r2, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#DISTUTILS_SRC_TEST"
4317 + fi
4318 +
4319 + # python.eclass::progress
4320 + for v in PYTHON_BDEPEND PYTHON_MULTIPLE_ABIS PYTHON_ABI_TYPE \
4321 + PYTHON_RESTRICTED_ABIS PYTHON_TESTS_FAILURES_TOLERANT_ABIS \
4322 + PYTHON_CFFI_MODULES_GENERATION_COMMANDS
4323 + do
4324 + if [[ ${!v} ]]; then
4325 + die "${v} is invalid for python-r2 suite"
4326 + fi
4327 + done
4328 +}
4329 +
4330 +python_pkg_setup() {
4331 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
4332 +}
4333 +
4334 +python_convert_shebangs() {
4335 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_convert_shebangs"
4336 +}
4337 +
4338 +python_clean_py-compile_files() {
4339 + die "${FUNCNAME}() is invalid for python-r2 suite"
4340 +}
4341 +
4342 +python_clean_installation_image() {
4343 + die "${FUNCNAME}() is invalid for python-r2 suite"
4344 +}
4345 +
4346 +python_execute_function() {
4347 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_execute_function"
4348 +}
4349 +
4350 +python_generate_wrapper_scripts() {
4351 + die "${FUNCNAME}() is invalid for python-r2 suite"
4352 +}
4353 +
4354 +python_merge_intermediate_installation_images() {
4355 + die "${FUNCNAME}() is invalid for python-r2 suite"
4356 +}
4357 +
4358 +python_set_active_version() {
4359 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
4360 +}
4361 +
4362 +python_need_rebuild() {
4363 + die "${FUNCNAME}() is invalid for python-r2 suite"
4364 +}
4365 +
4366 +PYTHON() {
4367 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#.24.28PYTHON.29.2C_.24.7BEPYTHON.7D"
4368 +}
4369 +
4370 +python_get_implementation() {
4371 + die "${FUNCNAME}() is invalid for python-r2 suite"
4372 +}
4373 +
4374 +python_get_implementational_package() {
4375 + die "${FUNCNAME}() is invalid for python-r2 suite"
4376 +}
4377 +
4378 +python_get_libdir() {
4379 + die "${FUNCNAME}() is invalid for python-r2 suite"
4380 +}
4381 +
4382 +python_get_library() {
4383 + die "${FUNCNAME}() is invalid for python-r2 suite"
4384 +}
4385 +
4386 +python_get_version() {
4387 + die "${FUNCNAME}() is invalid for python-r2 suite"
4388 +}
4389 +
4390 +python_get_implementation_and_version() {
4391 + die "${FUNCNAME}() is invalid for python-r2 suite"
4392 +}
4393 +
4394 +python_execute_nosetests() {
4395 + die "${FUNCNAME}() is invalid for python-r2 suite"
4396 +}
4397 +
4398 +python_execute_py.test() {
4399 + die "${FUNCNAME}() is invalid for python-r2 suite"
4400 +}
4401 +
4402 +python_execute_trial() {
4403 + die "${FUNCNAME}() is invalid for python-r2 suite"
4404 +}
4405 +
4406 +python_enable_pyc() {
4407 + die "${FUNCNAME}() is invalid for python-r2 suite"
4408 +}
4409 +
4410 +python_disable_pyc() {
4411 + die "${FUNCNAME}() is invalid for python-r2 suite"
4412 +}
4413 +
4414 +python_mod_optimize() {
4415 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
4416 +}
4417 +
4418 +python_mod_cleanup() {
4419 + die "${FUNCNAME}() is invalid for python-r2 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
4420 +}
4421 +
4422 +# python.eclass::progress
4423 +
4424 +python_abi_depend() {
4425 + die "${FUNCNAME}() is invalid for python-r2 suite"
4426 +}
4427 +
4428 +python_install_executables() {
4429 + die "${FUNCNAME}() is invalid for python-r2 suite"
4430 +}
4431 +
4432 +python_get_extension_module_suffix() {
4433 + die "${FUNCNAME}() is invalid for python-r2 suite"
4434 +}
4435 +
4436 +python_byte-compile_modules() {
4437 + die "${FUNCNAME}() is invalid for python-r2 suite"
4438 +}
4439 +
4440 +python_clean_byte-compiled_modules() {
4441 + die "${FUNCNAME}() is invalid for python-r2 suite"
4442 +}
4443 +
4444 +python_generate_cffi_modules() {
4445 + die "${FUNCNAME}() is invalid for python-r2 suite"
4446 +}
4447 +
4448 +_PYTHON_UTILS_R2=1
4449 +fi
4450 diff --git a/eclass/tests/distutils-r2.sh b/eclass/tests/distutils-r2.sh
4451 new file mode 100755
4452 index 000000000000..15f59bcd7d48
4453 --- /dev/null
4454 +++ b/eclass/tests/distutils-r2.sh
4455 @@ -0,0 +1,98 @@
4456 +#!/bin/bash
4457 +# Copyright 1999-2015 Gentoo Foundation
4458 +# Distributed under the terms of the GNU General Public License v2
4459 +
4460 +EAPI=5
4461 +PYTHON_COMPAT=( python2_7 )
4462 +source tests-common.sh
4463 +
4464 +test-phase_name_free() {
4465 + local ph=${1}
4466 +
4467 + if declare -f "${ph}"; then
4468 + die "${ph} function declared while name reserved for phase!"
4469 + fi
4470 + if declare -f "${ph}_all"; then
4471 + die "${ph}_all function declared while name reserved for phase!"
4472 + fi
4473 +}
4474 +
4475 +test-distutils_enable_tests() {
4476 + local runner=${1}
4477 + local exp_IUSE=${2}
4478 + local exp_RESTRICT=${3}
4479 + local exp_DEPEND=${4}
4480 +
4481 + local IUSE=${IUSE}
4482 + local RESTRICT=${RESTRICT}
4483 + local DEPEND=${DEPEND}
4484 +
4485 + tbegin "${runner}"
4486 +
4487 + distutils_enable_tests "${runner}"
4488 +
4489 + local ret var
4490 + for var in IUSE RESTRICT DEPEND; do
4491 + local exp_var=exp_${var}
4492 + if [[ ${!var} != "${!exp_var}" ]]; then
4493 + eindent
4494 + eerror "${var} expected: ${!exp_var}"
4495 + eerror "${var} actual: ${!var}"
4496 + eoutdent
4497 + ret=1
4498 + tret=1
4499 + fi
4500 + done
4501 +
4502 + tend ${ret}
4503 +}
4504 +
4505 +DISTUTILS_USE_SETUPTOOLS=no
4506 +inherit distutils-r2
4507 +
4508 +tbegin "sane function names"
4509 +
4510 +test-phase_name_free python_prepare
4511 +test-phase_name_free python_configure
4512 +test-phase_name_free python_compile
4513 +test-phase_name_free python_test
4514 +test-phase_name_free python_install
4515 +
4516 +tend
4517 +
4518 +einfo distutils_enable_tests
4519 +eindent
4520 +BASE_IUSE="python_targets_python2_7"
4521 +BASE_DEPS="python_targets_python2_7? ( >=dev-lang/python-2.7.5-r2:2.7 ) >=dev-lang/python-exec-2:=[python_targets_python2_7(-)?,-python_single_target_python2_7(-)]"
4522 +TEST_RESTRICT=" !test? ( test )"
4523 +
4524 +einfo "empty RDEPEND"
4525 +eindent
4526 +RDEPEND=""
4527 +test-distutils_enable_tests pytest \
4528 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( dev-python/pytest[${PYTHON_USEDEP}] )"
4529 +test-distutils_enable_tests nose \
4530 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( dev-python/nose[${PYTHON_USEDEP}] )"
4531 +test-distutils_enable_tests unittest \
4532 + "${BASE_IUSE}" "" "${BASE_DEPS}"
4533 +test-distutils_enable_tests setup.py \
4534 + "${BASE_IUSE}" "" "${BASE_DEPS}"
4535 +eoutdent
4536 +
4537 +einfo "non-empty RDEPEND"
4538 +eindent
4539 +BASE_RDEPEND="dev-python/foo[${PYTHON_USEDEP}]"
4540 +RDEPEND=${BASE_RDEPEND}
4541 +test-distutils_enable_tests pytest \
4542 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( ${BASE_RDEPEND} dev-python/pytest[${PYTHON_USEDEP}] )"
4543 +test-distutils_enable_tests nose \
4544 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( ${BASE_RDEPEND} dev-python/nose[${PYTHON_USEDEP}] )"
4545 +test-distutils_enable_tests unittest \
4546 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( ${BASE_RDEPEND} )"
4547 +test-distutils_enable_tests setup.py \
4548 + "${BASE_IUSE} test" "${TEST_RESTRICT}" "${BASE_DEPS} test? ( ${BASE_RDEPEND} )"
4549 +eoutdent
4550 +
4551 +eoutdent
4552 +
4553 +texit
4554 diff --git a/eclass/tests/python-utils-r2.sh b/eclass/tests/python-utils-r2.sh
4555 new file mode 100755
4556 index 000000000000..64490cb0d24a
4557 --- /dev/null
4558 +++ b/eclass/tests/python-utils-r2.sh
4559 @@ -0,0 +1,237 @@
4560 +#!/bin/bash
4561 +# Copyright 1999-2019 Gentoo Authors
4562 +# Distributed under the terms of the GNU General Public License v2
4563 +
4564 +EAPI=7
4565 +source tests-common.sh
4566 +
4567 +test_var() {
4568 + local var=${1}
4569 + local impl=${2}
4570 + local expect=${3}
4571 +
4572 + tbegin "${var} for ${impl}"
4573 +
4574 + local ${var}
4575 + python_export ${impl} PYTHON ${var}
4576 + [[ ${!var} == ${expect} ]] || eerror "(${impl}: ${var}: ${!var} != ${expect}"
4577 +
4578 + tend ${?}
4579 +}
4580 +
4581 +test_is() {
4582 + local func=${1}
4583 + local expect=${2}
4584 +
4585 + tbegin "${func} (expecting: ${expect})"
4586 +
4587 + ${func}
4588 + [[ ${?} == ${expect} ]]
4589 +
4590 + tend ${?}
4591 +}
4592 +
4593 +test_fix_shebang() {
4594 + local from=${1}
4595 + local to=${2}
4596 + local expect=${3}
4597 + local args=( "${@:4}" )
4598 +
4599 + tbegin "python_fix_shebang${args[@]+ ${args[*]}} from ${from} to ${to} (exp: ${expect})"
4600 +
4601 + echo "${from}" > "${tmpfile}"
4602 + output=$( EPYTHON=${to} python_fix_shebang "${args[@]}" -q "${tmpfile}" 2>&1 )
4603 +
4604 + if [[ ${?} != 0 ]]; then
4605 + if [[ ${expect} != FAIL ]]; then
4606 + echo "${output}"
4607 + tend 1
4608 + else
4609 + tend 0
4610 + fi
4611 + else
4612 + [[ $(<"${tmpfile}") == ${expect} ]] \
4613 + || eerror "${from} -> ${to}: $(<"${tmpfile}") != ${expect}"
4614 + tend ${?}
4615 + fi
4616 +}
4617 +
4618 +tmpfile=$(mktemp)
4619 +
4620 +inherit python-utils-r2
4621 +
4622 +test_var EPYTHON python2_7 python2.7
4623 +test_var PYTHON python2_7 /usr/bin/python2.7
4624 +if [[ -x /usr/bin/python2.7 ]]; then
4625 + test_var PYTHON_SITEDIR python2_7 "/usr/lib*/python2.7/site-packages"
4626 + test_var PYTHON_INCLUDEDIR python2_7 /usr/include/python2.7
4627 + test_var PYTHON_LIBPATH python2_7 "/usr/lib*/libpython2.7$(get_libname)"
4628 + test_var PYTHON_CONFIG python2_7 /usr/bin/python2.7-config
4629 + test_var PYTHON_CFLAGS python2_7 "*-I/usr/include/python2.7*"
4630 + test_var PYTHON_LIBS python2_7 "*-lpython2.7*"
4631 +fi
4632 +test_var PYTHON_PKG_DEP python2_7 '*dev-lang/python*:2.7'
4633 +test_var PYTHON_SCRIPTDIR python2_7 /usr/lib/python-exec/python2.7
4634 +
4635 +test_var EPYTHON python3_6 python3.6
4636 +test_var PYTHON python3_6 /usr/bin/python3.6
4637 +if [[ -x /usr/bin/python3.6 ]]; then
4638 + abiflags=$(/usr/bin/python3.6 -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS"))')
4639 + test_var PYTHON_SITEDIR python3_6 "/usr/lib*/python3.6/site-packages"
4640 + test_var PYTHON_INCLUDEDIR python3_6 "/usr/include/python3.6${abiflags}"
4641 + test_var PYTHON_LIBPATH python3_6 "/usr/lib*/libpython3.6${abiflags}$(get_libname)"
4642 + test_var PYTHON_CONFIG python3_6 "/usr/bin/python3.6${abiflags}-config"
4643 + test_var PYTHON_CFLAGS python3_6 "*-I/usr/include/python3.6*"
4644 + test_var PYTHON_LIBS python3_6 "*-lpython3.6*"
4645 +fi
4646 +test_var PYTHON_PKG_DEP python3_6 '*dev-lang/python*:3.6'
4647 +test_var PYTHON_SCRIPTDIR python3_6 /usr/lib/python-exec/python3.6
4648 +
4649 +test_var EPYTHON python3_7 python3.7
4650 +test_var PYTHON python3_7 /usr/bin/python3.7
4651 +if [[ -x /usr/bin/python3.7 ]]; then
4652 + abiflags=$(/usr/bin/python3.7 -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS"))')
4653 + test_var PYTHON_SITEDIR python3_7 "/usr/lib/python3.7/site-packages"
4654 + test_var PYTHON_INCLUDEDIR python3_7 "/usr/include/python3.7${abiflags}"
4655 + test_var PYTHON_LIBPATH python3_7 "/usr/lib*/libpython3.7${abiflags}$(get_libname)"
4656 + test_var PYTHON_CONFIG python3_7 "/usr/bin/python3.7${abiflags}-config"
4657 + test_var PYTHON_CFLAGS python3_7 "*-I/usr/include/python3.7*"
4658 + test_var PYTHON_LIBS python3_7 "*-lpython3.7*"
4659 +fi
4660 +test_var PYTHON_PKG_DEP python3_7 '*dev-lang/python*:3.7'
4661 +test_var PYTHON_SCRIPTDIR python3_7 /usr/lib/python-exec/python3.7
4662 +
4663 +test_var EPYTHON jython2_7 jython2.7
4664 +test_var PYTHON jython2_7 /usr/bin/jython2.7
4665 +if [[ -x /usr/bin/jython2.7 ]]; then
4666 + test_var PYTHON_SITEDIR jython2_7 /usr/share/jython-2.7/Lib/site-packages
4667 +fi
4668 +test_var PYTHON_PKG_DEP jython2_7 '*dev-java/jython*:2.7'
4669 +test_var PYTHON_SCRIPTDIR jython2_7 /usr/lib/python-exec/jython2.7
4670 +
4671 +test_var EPYTHON pypy pypy
4672 +test_var PYTHON pypy /usr/bin/pypy
4673 +if [[ -x /usr/bin/pypy ]]; then
4674 + test_var PYTHON_SITEDIR pypy "/usr/lib*/pypy2.7/site-packages"
4675 + test_var PYTHON_INCLUDEDIR pypy "/usr/lib*/pypy2.7/include"
4676 +fi
4677 +test_var PYTHON_PKG_DEP pypy '*dev-python/pypy*:0='
4678 +test_var PYTHON_SCRIPTDIR pypy /usr/lib/python-exec/pypy
4679 +
4680 +test_var EPYTHON pypy3 pypy3
4681 +test_var PYTHON pypy3 /usr/bin/pypy3
4682 +if [[ -x /usr/bin/pypy3 ]]; then
4683 + test_var PYTHON_SITEDIR pypy3 "/usr/lib*/pypy3.?/site-packages"
4684 + test_var PYTHON_INCLUDEDIR pypy3 "/usr/lib*/pypy3.?/include"
4685 +fi
4686 +test_var PYTHON_PKG_DEP pypy3 '*dev-python/pypy3*:0='
4687 +test_var PYTHON_SCRIPTDIR pypy3 /usr/lib/python-exec/pypy3
4688 +
4689 +test_is "python_is_python3 python2.7" 1
4690 +test_is "python_is_python3 python3.2" 0
4691 +test_is "python_is_python3 jython2.7" 1
4692 +test_is "python_is_python3 pypy" 1
4693 +test_is "python_is_python3 pypy3" 0
4694 +
4695 +# generic shebangs
4696 +test_fix_shebang '#!/usr/bin/python' python2.7 '#!/usr/bin/python2.7'
4697 +test_fix_shebang '#!/usr/bin/python' python3.6 '#!/usr/bin/python3.6'
4698 +test_fix_shebang '#!/usr/bin/python' pypy '#!/usr/bin/pypy'
4699 +test_fix_shebang '#!/usr/bin/python' pypy3 '#!/usr/bin/pypy3'
4700 +test_fix_shebang '#!/usr/bin/python' jython2.7 '#!/usr/bin/jython2.7'
4701 +
4702 +# python2/python3 matching
4703 +test_fix_shebang '#!/usr/bin/python2' python2.7 '#!/usr/bin/python2.7'
4704 +test_fix_shebang '#!/usr/bin/python3' python2.7 FAIL
4705 +test_fix_shebang '#!/usr/bin/python3' python2.7 '#!/usr/bin/python2.7' --force
4706 +test_fix_shebang '#!/usr/bin/python3' python3.6 '#!/usr/bin/python3.6'
4707 +test_fix_shebang '#!/usr/bin/python2' python3.6 FAIL
4708 +test_fix_shebang '#!/usr/bin/python2' python3.6 '#!/usr/bin/python3.6' --force
4709 +
4710 +# pythonX.Y matching (those mostly test the patterns)
4711 +test_fix_shebang '#!/usr/bin/python2.7' python2.7 '#!/usr/bin/python2.7'
4712 +test_fix_shebang '#!/usr/bin/python2.7' python3.2 FAIL
4713 +test_fix_shebang '#!/usr/bin/python2.7' python3.2 '#!/usr/bin/python3.2' --force
4714 +test_fix_shebang '#!/usr/bin/python3.2' python3.2 '#!/usr/bin/python3.2'
4715 +test_fix_shebang '#!/usr/bin/python3.2' python2.7 FAIL
4716 +test_fix_shebang '#!/usr/bin/python3.2' python2.7 '#!/usr/bin/python2.7' --force
4717 +test_fix_shebang '#!/usr/bin/pypy' pypy '#!/usr/bin/pypy'
4718 +test_fix_shebang '#!/usr/bin/pypy' python2.7 FAIL
4719 +test_fix_shebang '#!/usr/bin/pypy' python2.7 '#!/usr/bin/python2.7' --force
4720 +test_fix_shebang '#!/usr/bin/jython2.7' jython2.7 '#!/usr/bin/jython2.7'
4721 +test_fix_shebang '#!/usr/bin/jython2.7' jython3.2 FAIL
4722 +test_fix_shebang '#!/usr/bin/jython2.7' jython3.2 '#!/usr/bin/jython3.2' --force
4723 +
4724 +# fancy path handling
4725 +test_fix_shebang '#!/mnt/python2/usr/bin/python' python3.6 \
4726 + '#!/mnt/python2/usr/bin/python3.6'
4727 +test_fix_shebang '#!/mnt/python2/usr/bin/python2' python2.7 \
4728 + '#!/mnt/python2/usr/bin/python2.7'
4729 +test_fix_shebang '#!/mnt/python2/usr/bin/env python' python2.7 \
4730 + '#!/mnt/python2/usr/bin/env python2.7'
4731 +test_fix_shebang '#!/mnt/python2/usr/bin/python2 python2' python2.7 \
4732 + '#!/mnt/python2/usr/bin/python2.7 python2'
4733 +test_fix_shebang '#!/mnt/python2/usr/bin/python3 python2' python2.7 FAIL
4734 +test_fix_shebang '#!/mnt/python2/usr/bin/python3 python2' python2.7 \
4735 + '#!/mnt/python2/usr/bin/python2.7 python2' --force
4736 +test_fix_shebang '#!/usr/bin/foo' python2.7 FAIL
4737 +
4738 +# regression test for bug #522080
4739 +test_fix_shebang '#!/usr/bin/python ' python2.7 '#!/usr/bin/python2.7 '
4740 +
4741 +# make sure we don't break pattern matching
4742 +test_is "_python_impl_supported python2_5" 1
4743 +test_is "_python_impl_supported python2_6" 1
4744 +test_is "_python_impl_supported python2_7" 0
4745 +test_is "_python_impl_supported python3_1" 1
4746 +test_is "_python_impl_supported python3_2" 1
4747 +test_is "_python_impl_supported python3_3" 1
4748 +test_is "_python_impl_supported python3_4" 1
4749 +test_is "_python_impl_supported python3_5" 1
4750 +test_is "_python_impl_supported python3_6" 0
4751 +test_is "_python_impl_supported python3_7" 0
4752 +test_is "_python_impl_supported python3_8" 0
4753 +test_is "_python_impl_supported pypy1_8" 1
4754 +test_is "_python_impl_supported pypy1_9" 1
4755 +test_is "_python_impl_supported pypy2_0" 1
4756 +test_is "_python_impl_supported pypy" 1
4757 +test_is "_python_impl_supported pypy3" 0
4758 +test_is "_python_impl_supported jython2_7" 1
4759 +
4760 +# check _python_impl_matches behavior
4761 +test_is "_python_impl_matches python2_7 -2" 0
4762 +test_is "_python_impl_matches python3_6 -2" 1
4763 +test_is "_python_impl_matches python3_7 -2" 1
4764 +test_is "_python_impl_matches pypy -2" 0
4765 +test_is "_python_impl_matches pypy3 -2" 1
4766 +test_is "_python_impl_matches python2_7 -3" 1
4767 +test_is "_python_impl_matches python3_6 -3" 0
4768 +test_is "_python_impl_matches python3_7 -3" 0
4769 +test_is "_python_impl_matches pypy -3" 1
4770 +test_is "_python_impl_matches pypy3 -3" 0
4771 +test_is "_python_impl_matches python2_7 -2 python3_6" 0
4772 +test_is "_python_impl_matches python3_6 -2 python3_6" 0
4773 +test_is "_python_impl_matches python3_7 -2 python3_6" 1
4774 +test_is "_python_impl_matches pypy -2 python3_6" 0
4775 +test_is "_python_impl_matches pypy3 -2 python3_6" 1
4776 +test_is "_python_impl_matches python2_7 pypy3 -2 python3_6" 0
4777 +test_is "_python_impl_matches python3_6 pypy3 -2 python3_6" 0
4778 +test_is "_python_impl_matches python3_7 pypy3 -2 python3_6" 1
4779 +test_is "_python_impl_matches pypy pypy3 -2 python3_6" 0
4780 +test_is "_python_impl_matches pypy3 pypy3 -2 python3_6" 0
4781 +set -f
4782 +test_is "_python_impl_matches python2_7 pypy*" 1
4783 +test_is "_python_impl_matches python3_6 pypy*" 1
4784 +test_is "_python_impl_matches python3_7 pypy*" 1
4785 +test_is "_python_impl_matches pypy pypy*" 0
4786 +test_is "_python_impl_matches pypy3 pypy*" 0
4787 +test_is "_python_impl_matches python2_7 python*" 0
4788 +test_is "_python_impl_matches python3_6 python*" 0
4789 +test_is "_python_impl_matches python3_7 python*" 0
4790 +test_is "_python_impl_matches pypy python*" 1
4791 +test_is "_python_impl_matches pypy3 python*" 1
4792 +set +f
4793 +
4794 +rm "${tmpfile}"
4795 +
4796 +texit
4797 --
4798 2.25.1