Browse code

add eclass

Hanno Böck authored on 31/01/2021 08:46:01
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,395 @@
1
+# Copyright 1999-2020 Gentoo Authors
2
+# Distributed under the terms of the GNU General Public License v2
3
+
4
+# @ECLASS: python-any-r1.eclass
5
+# @MAINTAINER:
6
+# Python team <python@gentoo.org>
7
+# @AUTHOR:
8
+# Author: Michał Górny <mgorny@gentoo.org>
9
+# Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10
+# @SUPPORTED_EAPIS: 5 6 7
11
+# @BLURB: An eclass for packages having build-time dependency on Python.
12
+# @DESCRIPTION:
13
+# A minimal eclass for packages which need any Python interpreter
14
+# installed without a need for explicit choice and invariability.
15
+# This usually involves packages requiring Python at build-time
16
+# but having no other relevance to it.
17
+#
18
+# This eclass provides a minimal PYTHON_DEPS variable with a dependency
19
+# string on any of the supported Python implementations. It also exports
20
+# pkg_setup() which finds the best supported implementation and sets it
21
+# as the active one.
22
+#
23
+# Optionally, you can define a python_check_deps() function. It will
24
+# be called by the eclass with EPYTHON set to each matching Python
25
+# implementation and it is expected to check whether the implementation
26
+# fulfills the package requirements. You can use the locally exported
27
+# PYTHON_USEDEP or PYTHON_SINGLE_USEDEP to check USE-dependencies
28
+# of relevant packages. It should return a true value (0) if the Python
29
+# implementation fulfills the requirements, a false value (non-zero)
30
+# otherwise.
31
+#
32
+# Please note that python-any-r1 will always inherit python-utils-r1
33
+# as well. Thus, all the functions defined there can be used in the
34
+# packages using python-any-r1, and there is no need ever to inherit
35
+# both.
36
+#
37
+# For more information, please see the Python Guide:
38
+# https://dev.gentoo.org/~mgorny/python-guide/
39
+
40
+case "${EAPI:-0}" in
41
+	[0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
42
+	[5-7]) ;;
43
+	*)     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
44
+esac
45
+
46
+if [[ ! ${_PYTHON_ANY_R1} ]]; then
47
+
48
+if [[ ${_PYTHON_R1} ]]; then
49
+	die 'python-any-r1.eclass can not be used with python-r1.eclass.'
50
+elif [[ ${_PYTHON_SINGLE_R1} ]]; then
51
+	die 'python-any-r1.eclass can not be used with python-single-r1.eclass.'
52
+fi
53
+
54
+inherit python-utils-r1
55
+
56
+fi
57
+
58
+EXPORT_FUNCTIONS pkg_setup
59
+
60
+# @ECLASS-VARIABLE: PYTHON_COMPAT
61
+# @REQUIRED
62
+# @DESCRIPTION:
63
+# This variable contains a list of Python implementations the package
64
+# supports. It must be set before the `inherit' call. It has to be
65
+# an array.
66
+#
67
+# Example:
68
+# @CODE
69
+# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
70
+# @CODE
71
+
72
+# @ECLASS-VARIABLE: PYTHON_COMPAT_OVERRIDE
73
+# @USER_VARIABLE
74
+# @DEFAULT_UNSET
75
+# @DESCRIPTION:
76
+# This variable can be used when working with ebuilds to override
77
+# the in-ebuild PYTHON_COMPAT. It is a string naming the implementation
78
+# which will be used to build the package. It needs to be specified
79
+# in the calling environment, and not in ebuilds.
80
+#
81
+# It should be noted that in order to preserve metadata immutability,
82
+# PYTHON_COMPAT_OVERRIDE does not affect dependencies. The value of
83
+# EPYTHON and eselect-python preferences are ignored. Dependencies need
84
+# to be satisfied manually.
85
+#
86
+# Example:
87
+# @CODE
88
+# PYTHON_COMPAT_OVERRIDE='pypy' emerge -1v dev-python/bar
89
+# @CODE
90
+
91
+# @ECLASS-VARIABLE: PYTHON_REQ_USE
92
+# @DEFAULT_UNSET
93
+# @DESCRIPTION:
94
+# The list of USEflags required to be enabled on the Python
95
+# implementations, formed as a USE-dependency string. It should be valid
96
+# for all implementations in PYTHON_COMPAT, so it may be necessary to
97
+# use USE defaults.
98
+#
99
+# Example:
100
+# @CODE
101
+# PYTHON_REQ_USE="gdbm,ncurses(-)?"
102
+# @CODE
103
+#
104
+# It will cause the Python dependencies to look like:
105
+# @CODE
106
+# || ( dev-lang/python:X.Y[gdbm,ncurses(-)?] ... )
107
+# @CODE
108
+
109
+# @ECLASS-VARIABLE: PYTHON_DEPS
110
+# @OUTPUT_VARIABLE
111
+# @DESCRIPTION:
112
+# This is an eclass-generated Python dependency string for all
113
+# implementations listed in PYTHON_COMPAT.
114
+#
115
+# Any of the supported interpreters will satisfy the dependency.
116
+#
117
+# Example use:
118
+# @CODE
119
+# DEPEND="${RDEPEND}
120
+#	${PYTHON_DEPS}"
121
+# @CODE
122
+#
123
+# Example value:
124
+# @CODE
125
+# || ( dev-lang/python:2.7[gdbm]
126
+# 	dev-lang/python:2.6[gdbm] )
127
+# @CODE
128
+
129
+# @ECLASS-VARIABLE: PYTHON_USEDEP
130
+# @OUTPUT_VARIABLE
131
+# @DESCRIPTION:
132
+# An eclass-generated USE-dependency string for the currently tested
133
+# implementation. It is set locally for python_check_deps() call.
134
+#
135
+# The generated USE-flag list is compatible with packages using
136
+# python-r1 eclass. For python-single-r1 dependencies,
137
+# use PYTHON_SINGLE_USEDEP.
138
+#
139
+# Example use:
140
+# @CODE
141
+# python_check_deps() {
142
+# 	has_version "dev-python/foo[${PYTHON_USEDEP}]"
143
+# }
144
+# @CODE
145
+#
146
+# Example value:
147
+# @CODE
148
+# python_targets_python3_7(-),-python_single_target_python3_7(-)
149
+# @CODE
150
+
151
+# @ECLASS-VARIABLE: PYTHON_SINGLE_USEDEP
152
+# @OUTPUT_VARIABLE
153
+# @DESCRIPTION:
154
+# An eclass-generated USE-dependency string for the currently tested
155
+# implementation. It is set locally for python_check_deps() call.
156
+#
157
+# The generated USE-flag list is compatible with packages using
158
+# python-single-r1 eclass. For python-r1 dependencies,
159
+# use PYTHON_USEDEP.
160
+#
161
+# Example use:
162
+# @CODE
163
+# python_check_deps() {
164
+# 	has_version "dev-python/bar[${PYTHON_SINGLE_USEDEP}]"
165
+# }
166
+# @CODE
167
+#
168
+# Example value:
169
+# @CODE
170
+# python_single_target_python3_7(-)
171
+# @CODE
172
+
173
+_python_any_set_globals() {
174
+	local usestr deps i PYTHON_PKG_DEP
175
+	[[ ${PYTHON_REQ_USE} ]] && usestr="[${PYTHON_REQ_USE}]"
176
+
177
+	_python_set_impls
178
+
179
+	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
180
+		_python_export "${i}" PYTHON_PKG_DEP
181
+
182
+		# note: need to strip '=' slot operator for || deps
183
+		deps="${PYTHON_PKG_DEP/:0=/:0} ${deps}"
184
+	done
185
+	deps="|| ( ${deps})"
186
+
187
+	if [[ ${PYTHON_DEPS+1} ]]; then
188
+		if [[ ${PYTHON_DEPS} != "${deps}" ]]; then
189
+			eerror "PYTHON_DEPS have changed between inherits (PYTHON_REQ_USE?)!"
190
+			eerror "Before: ${PYTHON_DEPS}"
191
+			eerror "Now   : ${deps}"
192
+			die "PYTHON_DEPS integrity check failed"
193
+		fi
194
+	else
195
+		PYTHON_DEPS=${deps}
196
+		readonly PYTHON_DEPS
197
+	fi
198
+
199
+	if [[ ! ${PYTHON_REQUIRED_USE+1} ]]; then
200
+		# fake var to catch mistaken usage
201
+		PYTHON_REQUIRED_USE='I-DO-NOT-EXIST-IN-PYTHON-ANY-R1'
202
+		readonly PYTHON_REQUIRED_USE
203
+	fi
204
+}
205
+_python_any_set_globals
206
+unset -f _python_any_set_globals
207
+
208
+if [[ ! ${_PYTHON_ANY_R1} ]]; then
209
+
210
+# @FUNCTION: python_gen_any_dep
211
+# @USAGE: <dependency-block>
212
+# @DESCRIPTION:
213
+# Generate an any-of dependency that enforces a version match between
214
+# the Python interpreter and Python packages. <dependency-block> needs
215
+# to list one or more dependencies with verbatim '${PYTHON_USEDEP}'
216
+# or '${PYTHON_SINGLE_USEDEP}' references (quoted!) that will get
217
+# expanded inside the function.
218
+#
219
+# This should be used along with an appropriate python_check_deps()
220
+# that checks which of the any-of blocks were matched.
221
+#
222
+# Example use:
223
+# @CODE
224
+# DEPEND="$(python_gen_any_dep '
225
+#	dev-python/foo[${PYTHON_SINGLE_USEDEP}]
226
+#	|| ( dev-python/bar[${PYTHON_USEDEP}]
227
+#		dev-python/baz[${PYTHON_USEDEP}] )')"
228
+#
229
+# python_check_deps() {
230
+#	has_version "dev-python/foo[${PYTHON_SINGLE_USEDEP}]" \
231
+#		&& { has_version "dev-python/bar[${PYTHON_USEDEP}]" \
232
+#			|| has_version "dev-python/baz[${PYTHON_USEDEP}]"; }
233
+# }
234
+# @CODE
235
+#
236
+# Example value:
237
+# @CODE
238
+# || (
239
+#	(
240
+#		dev-lang/python:3.7
241
+#		dev-python/foo[python_single_target_python3_7(-)]
242
+#		|| ( dev-python/bar[python_targets_python3_7(-),-python_single_target_python3_7(-)]
243
+#			dev-python/baz[python_targets_python3_7(-),-python_single_target_python3_7(-)] )
244
+#	)
245
+#	(
246
+#		dev-lang/python:3.8
247
+#		dev-python/foo[python_single_target_python3_8(-)]
248
+#		|| ( dev-python/bar[python_targets_python3_8(-),-python_single_target_python3_8(-)]
249
+#			dev-python/baz[python_targets_python3_8(-),-python_single_target_python3_8(-)] )
250
+#	)
251
+# )
252
+# @CODE
253
+python_gen_any_dep() {
254
+	debug-print-function ${FUNCNAME} "${@}"
255
+
256
+	local depstr=${1}
257
+	[[ ${depstr} ]] || die "No dependency string provided"
258
+
259
+	local i PYTHON_PKG_DEP out=
260
+	for i in "${_PYTHON_SUPPORTED_IMPLS[@]}"; do
261
+		local PYTHON_USEDEP="python_targets_${i}(-),-python_single_target_${i}(-)"
262
+		local PYTHON_SINGLE_USEDEP="python_single_target_${i}(-)"
263
+		_python_export "${i}" PYTHON_PKG_DEP
264
+
265
+		local i_depstr=${depstr//\$\{PYTHON_USEDEP\}/${PYTHON_USEDEP}}
266
+		i_depstr=${i_depstr//\$\{PYTHON_SINGLE_USEDEP\}/${PYTHON_SINGLE_USEDEP}}
267
+		# note: need to strip '=' slot operator for || deps
268
+		out="( ${PYTHON_PKG_DEP%=} ${i_depstr} ) ${out}"
269
+	done
270
+	echo "|| ( ${out})"
271
+}
272
+
273
+# @FUNCTION: _python_EPYTHON_supported
274
+# @USAGE: <epython>
275
+# @INTERNAL
276
+# @DESCRIPTION:
277
+# Check whether the specified implementation is supported by package
278
+# (specified in PYTHON_COMPAT). Calls python_check_deps() if declared.
279
+_python_EPYTHON_supported() {
280
+	debug-print-function ${FUNCNAME} "${@}"
281
+
282
+	local EPYTHON=${1}
283
+	local i=${EPYTHON/./_}
284
+
285
+	case "${i}" in
286
+		python*|jython*|pypy*)
287
+			;;
288
+		*)
289
+			ewarn "Invalid EPYTHON: ${EPYTHON}"
290
+			return 1
291
+			;;
292
+	esac
293
+
294
+	if has "${i}" "${_PYTHON_SUPPORTED_IMPLS[@]}"; then
295
+		if python_is_installed "${i}"; then
296
+			if declare -f python_check_deps >/dev/null; then
297
+				local PYTHON_USEDEP="python_targets_${i}(-),-python_single_target_${i}(-)"
298
+				local PYTHON_SINGLE_USEDEP="python_single_target_${i}(-)"
299
+				python_check_deps
300
+				return ${?}
301
+			fi
302
+
303
+			return 0
304
+		fi
305
+	elif ! has "${i}" "${_PYTHON_ALL_IMPLS[@]}"; then
306
+		ewarn "Invalid EPYTHON: ${EPYTHON}"
307
+	fi
308
+	return 1
309
+}
310
+
311
+# @FUNCTION: python_setup
312
+# @DESCRIPTION:
313
+# Determine what the best installed (and supported) Python
314
+# implementation is, and set the Python build environment up for it.
315
+#
316
+# This function will call python_check_deps() if defined.
317
+python_setup() {
318
+	debug-print-function ${FUNCNAME} "${@}"
319
+
320
+	# support developer override
321
+	if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then
322
+		local impls=( ${PYTHON_COMPAT_OVERRIDE} )
323
+		[[ ${#impls[@]} -eq 1 ]] || die "PYTHON_COMPAT_OVERRIDE must name exactly one implementation for python-any-r1"
324
+
325
+		ewarn "WARNING: PYTHON_COMPAT_OVERRIDE in effect. The following Python"
326
+		ewarn "implementation will be used:"
327
+		ewarn
328
+		ewarn "	${PYTHON_COMPAT_OVERRIDE}"
329
+		ewarn
330
+		ewarn "Dependencies won't be satisfied, and EPYTHON/eselect-python will be ignored."
331
+
332
+		_python_export "${impls[0]}" EPYTHON PYTHON
333
+		_python_wrapper_setup
334
+		einfo "Using ${EPYTHON} to build"
335
+		return
336
+	fi
337
+
338
+	# first, try ${EPYTHON}... maybe it's good enough for us.
339
+	if [[ ${EPYTHON} ]]; then
340
+		if _python_EPYTHON_supported "${EPYTHON}"; then
341
+			_python_export EPYTHON PYTHON
342
+			_python_wrapper_setup
343
+			einfo "Using ${EPYTHON} to build"
344
+			return
345
+		fi
346
+	fi
347
+
348
+	# then, try eselect-python
349
+	local variant i
350
+	for variant in '' '--python2' '--python3'; do
351
+		i=$(eselect python --show ${variant} 2>/dev/null)
352
+
353
+		if [[ ! ${i} ]]; then
354
+			# no eselect-python?
355
+			break
356
+		elif _python_EPYTHON_supported "${i}"; then
357
+			_python_export "${i}" EPYTHON PYTHON
358
+			_python_wrapper_setup
359
+			einfo "Using ${EPYTHON} to build"
360
+			return
361
+		fi
362
+	done
363
+
364
+	# fallback to best installed impl.
365
+	# (reverse iteration over _PYTHON_SUPPORTED_IMPLS)
366
+	for (( i = ${#_PYTHON_SUPPORTED_IMPLS[@]} - 1; i >= 0; i-- )); do
367
+		_python_export "${_PYTHON_SUPPORTED_IMPLS[i]}" EPYTHON PYTHON
368
+		if _python_EPYTHON_supported "${EPYTHON}"; then
369
+			_python_wrapper_setup
370
+			einfo "Using ${EPYTHON} to build"
371
+			return
372
+		fi
373
+	done
374
+
375
+	eerror "No Python implementation found for the build. This is usually"
376
+	eerror "a bug in the ebuild. Please report it to bugs.gentoo.org"
377
+	eerror "along with the build log."
378
+	echo
379
+	die "No supported Python implementation installed."
380
+}
381
+
382
+# @FUNCTION: python-any-r1_pkg_setup
383
+# @DESCRIPTION:
384
+# Runs python_setup during from-source installs.
385
+#
386
+# In a binary package installs is a no-op. If you need Python in pkg_*
387
+# phases of a binary package, call python_setup directly.
388
+python-any-r1_pkg_setup() {
389
+	debug-print-function ${FUNCNAME} "${@}"
390
+
391
+	[[ ${MERGE_TYPE} != binary ]] && python_setup
392
+}
393
+
394
+_PYTHON_ANY_R1=1
395
+fi
0 396
new file mode 100644
... ...
@@ -0,0 +1,1445 @@
1
+# Copyright 1999-2021 Gentoo Authors
2
+# Distributed under the terms of the GNU General Public License v2
3
+
4
+# @ECLASS: python-utils-r1.eclass
5
+# @MAINTAINER:
6
+# Python team <python@gentoo.org>
7
+# @AUTHOR:
8
+# Author: Michał Górny <mgorny@gentoo.org>
9
+# Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
10
+# @SUPPORTED_EAPIS: 5 6 7
11
+# @BLURB: Utility functions for packages with Python parts.
12
+# @DESCRIPTION:
13
+# A utility eclass providing functions to query Python implementations,
14
+# install Python modules and scripts.
15
+#
16
+# This eclass does not set any metadata variables nor export any phase
17
+# functions. It can be inherited safely.
18
+#
19
+# For more information, please see the Python Guide:
20
+# https://dev.gentoo.org/~mgorny/python-guide/
21
+
22
+case "${EAPI:-0}" in
23
+	[0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
24
+	[5-7]) ;;
25
+	*)     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
26
+esac
27
+
28
+if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
29
+	die 'python-r1 suite eclasses can not be used with python.eclass.'
30
+fi
31
+
32
+if [[ ! ${_PYTHON_UTILS_R1} ]]; then
33
+
34
+[[ ${EAPI} == 5 ]] && inherit eutils multilib
35
+inherit toolchain-funcs
36
+
37
+# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
38
+# @INTERNAL
39
+# @DESCRIPTION:
40
+# All supported Python implementations, most preferred last.
41
+_PYTHON_ALL_IMPLS=(
42
+	pypy3
43
+	python2_7
44
+	python3_7 python3_8 python3_9
45
+)
46
+readonly _PYTHON_ALL_IMPLS
47
+
48
+# @ECLASS-VARIABLE: _PYTHON_HISTORICAL_IMPLS
49
+# @INTERNAL
50
+# @DESCRIPTION:
51
+# All historical Python implementations that are no longer supported.
52
+_PYTHON_HISTORICAL_IMPLS=(
53
+	jython2_7
54
+	pypy pypy1_{8,9} pypy2_0
55
+	python2_{5,6}
56
+	python3_{1..6}
57
+)
58
+readonly _PYTHON_HISTORICAL_IMPLS
59
+
60
+# @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
61
+# @INTERNAL
62
+# @DESCRIPTION:
63
+# Set to a non-empty value in order to make eclass tolerate (ignore)
64
+# unknown implementations in PYTHON_COMPAT.
65
+#
66
+# This is intended to be set by the user when using ebuilds that may
67
+# have unknown (newer) implementations in PYTHON_COMPAT. The assumption
68
+# is that the ebuilds are intended to be used within multiple contexts
69
+# which can involve revisions of this eclass that support a different
70
+# set of Python implementations.
71
+
72
+# @FUNCTION: _python_verify_patterns
73
+# @USAGE: <pattern>...
74
+# @INTERNAL
75
+# @DESCRIPTION:
76
+# Verify whether the patterns passed to the eclass function are correct
77
+# (i.e. can match any valid implementation).  Dies on wrong pattern.
78
+_python_verify_patterns() {
79
+	debug-print-function ${FUNCNAME} "${@}"
80
+
81
+	local impl pattern
82
+	for pattern; do
83
+		[[ ${pattern} == -[23] ]] && continue
84
+
85
+		for impl in "${_PYTHON_ALL_IMPLS[@]}" "${_PYTHON_HISTORICAL_IMPLS[@]}"
86
+		do
87
+			[[ ${impl} == ${pattern/./_} ]] && continue 2
88
+		done
89
+
90
+		die "Invalid implementation pattern: ${pattern}"
91
+	done
92
+}
93
+
94
+# @FUNCTION: _python_set_impls
95
+# @INTERNAL
96
+# @DESCRIPTION:
97
+# Check PYTHON_COMPAT for well-formedness and validity, then set
98
+# two global variables:
99
+#
100
+# - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
101
+#   by the ebuild (PYTHON_COMPAT - dead implementations),
102
+#
103
+# - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
104
+#   are not supported by the ebuild.
105
+#
106
+# Implementations in both variables are ordered using the pre-defined
107
+# eclass implementation ordering.
108
+#
109
+# This function must be called once in global scope by an eclass
110
+# utilizing PYTHON_COMPAT.
111
+_python_set_impls() {
112
+	local i
113
+
114
+	if ! declare -p PYTHON_COMPAT &>/dev/null; then
115
+		die 'PYTHON_COMPAT not declared.'
116
+	fi
117
+	if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
118
+		die 'PYTHON_COMPAT must be an array.'
119
+	fi
120
+	if [[ ! ${PYTHON_COMPAT_NO_STRICT} ]]; then
121
+		for i in "${PYTHON_COMPAT[@]}"; do
122
+			# check for incorrect implementations
123
+			# we're using pattern matching as an optimization
124
+			# please keep them in sync with _PYTHON_ALL_IMPLS
125
+			# and _PYTHON_HISTORICAL_IMPLS
126
+			case ${i} in
127
+				jython2_7|pypy|pypy1_[89]|pypy2_0|pypy3|python2_[5-7]|python3_[1-9])
128
+					;;
129
+				*)
130
+					if has "${i}" "${_PYTHON_ALL_IMPLS[@]}" \
131
+						"${_PYTHON_HISTORICAL_IMPLS[@]}"
132
+					then
133
+						die "Mis-synced patterns in _python_set_impls: missing ${i}"
134
+					else
135
+						die "Invalid implementation in PYTHON_COMPAT: ${i}"
136
+					fi
137
+			esac
138
+		done
139
+	fi
140
+
141
+	local supp=() unsupp=()
142
+
143
+	for i in "${_PYTHON_ALL_IMPLS[@]}"; do
144
+		if has "${i}" "${PYTHON_COMPAT[@]}"; then
145
+			supp+=( "${i}" )
146
+		else
147
+			unsupp+=( "${i}" )
148
+		fi
149
+	done
150
+
151
+	if [[ ! ${supp[@]} ]]; then
152
+		die "No supported implementation in PYTHON_COMPAT."
153
+	fi
154
+
155
+	if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
156
+		# set once already, verify integrity
157
+		if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
158
+			eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
159
+			eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
160
+			eerror "Now   : ${supp[*]}"
161
+			die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
162
+		fi
163
+		if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
164
+			eerror "Unsupported impls changed between inherits!"
165
+			eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
166
+			eerror "Now   : ${unsupp[*]}"
167
+			die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
168
+		fi
169
+	else
170
+		_PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
171
+		_PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
172
+		readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
173
+	fi
174
+}
175
+
176
+# @FUNCTION: _python_impl_matches
177
+# @USAGE: <impl> [<pattern>...]
178
+# @INTERNAL
179
+# @DESCRIPTION:
180
+# Check whether the specified <impl> matches at least one
181
+# of the patterns following it. Return 0 if it does, 1 otherwise.
182
+# Matches if no patterns are provided.
183
+#
184
+# <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
185
+# either:
186
+# a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
187
+# b) '-2' to indicate all Python 2 variants (= !python_is_python3)
188
+# c) '-3' to indicate all Python 3 variants (= python_is_python3)
189
+_python_impl_matches() {
190
+	[[ ${#} -ge 1 ]] || die "${FUNCNAME}: takes at least 1 parameter"
191
+	[[ ${#} -eq 1 ]] && return 0
192
+
193
+	local impl=${1} pattern
194
+	shift
195
+
196
+	for pattern; do
197
+		if [[ ${pattern} == -2 ]]; then
198
+			python_is_python3 "${impl}" || return 0
199
+		elif [[ ${pattern} == -3 ]]; then
200
+			python_is_python3 "${impl}" && return 0
201
+			return
202
+		# unify value style to allow lax matching
203
+		elif [[ ${impl/./_} == ${pattern/./_} ]]; then
204
+			return 0
205
+		fi
206
+	done
207
+
208
+	return 1
209
+}
210
+
211
+# @ECLASS-VARIABLE: PYTHON
212
+# @DEFAULT_UNSET
213
+# @DESCRIPTION:
214
+# The absolute path to the current Python interpreter.
215
+#
216
+# This variable is set automatically in the following contexts:
217
+#
218
+# python-r1: Set in functions called by python_foreach_impl() or after
219
+# calling python_setup().
220
+#
221
+# python-single-r1: Set after calling python-single-r1_pkg_setup().
222
+#
223
+# distutils-r1: Set within any of the python sub-phase functions.
224
+#
225
+# Example value:
226
+# @CODE
227
+# /usr/bin/python2.7
228
+# @CODE
229
+
230
+# @ECLASS-VARIABLE: EPYTHON
231
+# @DEFAULT_UNSET
232
+# @DESCRIPTION:
233
+# The executable name of the current Python interpreter.
234
+#
235
+# This variable is set automatically in the following contexts:
236
+#
237
+# python-r1: Set in functions called by python_foreach_impl() or after
238
+# calling python_setup().
239
+#
240
+# python-single-r1: Set after calling python-single-r1_pkg_setup().
241
+#
242
+# distutils-r1: Set within any of the python sub-phase functions.
243
+#
244
+# Example value:
245
+# @CODE
246
+# python2.7
247
+# @CODE
248
+
249
+# @FUNCTION: python_export
250
+# @USAGE: [<impl>] <variables>...
251
+# @INTERNAL
252
+# @DESCRIPTION:
253
+# Backwards compatibility function.  The relevant API is now considered
254
+# private, please use python_get* instead.
255
+python_export() {
256
+	debug-print-function ${FUNCNAME} "${@}"
257
+
258
+	eqawarn "python_export() is part of private eclass API."
259
+	eqawarn "Please call python_get*() instead."
260
+
261
+	_python_export "${@}"
262
+}
263
+
264
+# @FUNCTION: _python_export
265
+# @USAGE: [<impl>] <variables>...
266
+# @INTERNAL
267
+# @DESCRIPTION:
268
+# Set and export the Python implementation-relevant variables passed
269
+# as parameters.
270
+#
271
+# The optional first parameter may specify the requested Python
272
+# implementation (either as PYTHON_TARGETS value, e.g. python2_7,
273
+# or an EPYTHON one, e.g. python2.7). If no implementation passed,
274
+# the current one will be obtained from ${EPYTHON}.
275
+#
276
+# The variables which can be exported are: PYTHON, EPYTHON,
277
+# PYTHON_SITEDIR. They are described more completely in the eclass
278
+# variable documentation.
279
+_python_export() {
280
+	debug-print-function ${FUNCNAME} "${@}"
281
+
282
+	local impl var
283
+
284
+	case "${1}" in
285
+		python*|jython*)
286
+			impl=${1/_/.}
287
+			shift
288
+			;;
289
+		pypy|pypy3)
290
+			impl=${1}
291
+			shift
292
+			;;
293
+		*)
294
+			impl=${EPYTHON}
295
+			if [[ -z ${impl} ]]; then
296
+				die "_python_export called without a python implementation and EPYTHON is unset"
297
+			fi
298
+			;;
299
+	esac
300
+	debug-print "${FUNCNAME}: implementation: ${impl}"
301
+
302
+	for var; do
303
+		case "${var}" in
304
+			EPYTHON)
305
+				export EPYTHON=${impl}
306
+				debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
307
+				;;
308
+			PYTHON)
309
+				export PYTHON=${EPREFIX}/usr/bin/${impl}
310
+				debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
311
+				;;
312
+			PYTHON_SITEDIR)
313
+				[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
314
+				# sysconfig can't be used because:
315
+				# 1) pypy doesn't give site-packages but stdlib
316
+				# 2) jython gives paths with wrong case
317
+				PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
318
+				export PYTHON_SITEDIR
319
+				debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
320
+				;;
321
+			PYTHON_INCLUDEDIR)
322
+				[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
323
+				PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
324
+				export PYTHON_INCLUDEDIR
325
+				debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
326
+
327
+				# Jython gives a non-existing directory
328
+				if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
329
+					die "${impl} does not install any header files!"
330
+				fi
331
+				;;
332
+			PYTHON_LIBPATH)
333
+				[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
334
+				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
335
+				export PYTHON_LIBPATH
336
+				debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
337
+
338
+				if [[ ! ${PYTHON_LIBPATH} ]]; then
339
+					die "${impl} lacks a (usable) dynamic library"
340
+				fi
341
+				;;
342
+			PYTHON_CFLAGS)
343
+				local val
344
+
345
+				case "${impl}" in
346
+					python*)
347
+						# python-2.7, python-3.2, etc.
348
+						val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
349
+						;;
350
+					*)
351
+						die "${impl}: obtaining ${var} not supported"
352
+						;;
353
+				esac
354
+
355
+				export PYTHON_CFLAGS=${val}
356
+				debug-print "${FUNCNAME}: PYTHON_CFLAGS = ${PYTHON_CFLAGS}"
357
+				;;
358
+			PYTHON_LIBS)
359
+				local val
360
+
361
+				case "${impl}" in
362
+					python2*|python3.6|python3.7*)
363
+						# python* up to 3.7
364
+						val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
365
+						;;
366
+					python*)
367
+						# python3.8+
368
+						val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}-embed) || die
369
+						;;
370
+					*)
371
+						die "${impl}: obtaining ${var} not supported"
372
+						;;
373
+				esac
374
+
375
+				export PYTHON_LIBS=${val}
376
+				debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
377
+				;;
378
+			PYTHON_CONFIG)
379
+				local flags val
380
+
381
+				case "${impl}" in
382
+					python*)
383
+						[[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
384
+						flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
385
+						val=${PYTHON}${flags}-config
386
+						;;
387
+					*)
388
+						die "${impl}: obtaining ${var} not supported"
389
+						;;
390
+				esac
391
+
392
+				export PYTHON_CONFIG=${val}
393
+				debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
394
+				;;
395
+			PYTHON_PKG_DEP)
396
+				local d
397
+				case ${impl} in
398
+					python2.7)
399
+						PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
400
+					python*)
401
+						PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
402
+					pypy)
403
+						PYTHON_PKG_DEP='>=dev-python/pypy-7.3.0:0=';;
404
+					pypy3)
405
+						PYTHON_PKG_DEP='>=dev-python/pypy3-7.3.0:0=';;
406
+					*)
407
+						die "Invalid implementation: ${impl}"
408
+				esac
409
+
410
+				# use-dep
411
+				if [[ ${PYTHON_REQ_USE} ]]; then
412
+					PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
413
+				fi
414
+
415
+				export PYTHON_PKG_DEP
416
+				debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
417
+				;;
418
+			PYTHON_SCRIPTDIR)
419
+				local dir
420
+				export PYTHON_SCRIPTDIR=${EPREFIX}/usr/lib/python-exec/${impl}
421
+				debug-print "${FUNCNAME}: PYTHON_SCRIPTDIR = ${PYTHON_SCRIPTDIR}"
422
+				;;
423
+			*)
424
+				die "_python_export: unknown variable ${var}"
425
+		esac
426
+	done
427
+}
428
+
429
+# @FUNCTION: python_get_sitedir
430
+# @USAGE: [<impl>]
431
+# @DESCRIPTION:
432
+# Obtain and print the 'site-packages' path for the given
433
+# implementation. If no implementation is provided, ${EPYTHON} will
434
+# be used.
435
+python_get_sitedir() {
436
+	debug-print-function ${FUNCNAME} "${@}"
437
+
438
+	_python_export "${@}" PYTHON_SITEDIR
439
+	echo "${PYTHON_SITEDIR}"
440
+}
441
+
442
+# @FUNCTION: python_get_includedir
443
+# @USAGE: [<impl>]
444
+# @DESCRIPTION:
445
+# Obtain and print the include path for the given implementation. If no
446
+# implementation is provided, ${EPYTHON} will be used.
447
+python_get_includedir() {
448
+	debug-print-function ${FUNCNAME} "${@}"
449
+
450
+	_python_export "${@}" PYTHON_INCLUDEDIR
451
+	echo "${PYTHON_INCLUDEDIR}"
452
+}
453
+
454
+# @FUNCTION: python_get_library_path
455
+# @USAGE: [<impl>]
456
+# @DESCRIPTION:
457
+# Obtain and print the Python library path for the given implementation.
458
+# If no implementation is provided, ${EPYTHON} will be used.
459
+#
460
+# Please note that this function can be used with CPython only. Use
461
+# in another implementation will result in a fatal failure.
462
+python_get_library_path() {
463
+	debug-print-function ${FUNCNAME} "${@}"
464
+
465
+	_python_export "${@}" PYTHON_LIBPATH
466
+	echo "${PYTHON_LIBPATH}"
467
+}
468
+
469
+# @FUNCTION: python_get_CFLAGS
470
+# @USAGE: [<impl>]
471
+# @DESCRIPTION:
472
+# Obtain and print the compiler flags for building against Python,
473
+# for the given implementation. If no implementation is provided,
474
+# ${EPYTHON} will be used.
475
+#
476
+# Please note that this function can be used with CPython only.
477
+# It requires Python and pkg-config installed, and therefore proper
478
+# build-time dependencies need be added to the ebuild.
479
+python_get_CFLAGS() {
480
+	debug-print-function ${FUNCNAME} "${@}"
481
+
482
+	_python_export "${@}" PYTHON_CFLAGS
483
+	echo "${PYTHON_CFLAGS}"
484
+}
485
+
486
+# @FUNCTION: python_get_LIBS
487
+# @USAGE: [<impl>]
488
+# @DESCRIPTION:
489
+# Obtain and print the compiler flags for linking against Python,
490
+# for the given implementation. If no implementation is provided,
491
+# ${EPYTHON} will be used.
492
+#
493
+# Please note that this function can be used with CPython only.
494
+# It requires Python and pkg-config installed, and therefore proper
495
+# build-time dependencies need be added to the ebuild.
496
+python_get_LIBS() {
497
+	debug-print-function ${FUNCNAME} "${@}"
498
+
499
+	_python_export "${@}" PYTHON_LIBS
500
+	echo "${PYTHON_LIBS}"
501
+}
502
+
503
+# @FUNCTION: python_get_PYTHON_CONFIG
504
+# @USAGE: [<impl>]
505
+# @DESCRIPTION:
506
+# Obtain and print the PYTHON_CONFIG location for the given
507
+# implementation. If no implementation is provided, ${EPYTHON} will be
508
+# used.
509
+#
510
+# Please note that this function can be used with CPython only.
511
+# It requires Python installed, and therefore proper build-time
512
+# dependencies need be added to the ebuild.
513
+python_get_PYTHON_CONFIG() {
514
+	debug-print-function ${FUNCNAME} "${@}"
515
+
516
+	_python_export "${@}" PYTHON_CONFIG
517
+	echo "${PYTHON_CONFIG}"
518
+}
519
+
520
+# @FUNCTION: python_get_scriptdir
521
+# @USAGE: [<impl>]
522
+# @DESCRIPTION:
523
+# Obtain and print the script install path for the given
524
+# implementation. If no implementation is provided, ${EPYTHON} will
525
+# be used.
526
+python_get_scriptdir() {
527
+	debug-print-function ${FUNCNAME} "${@}"
528
+
529
+	_python_export "${@}" PYTHON_SCRIPTDIR
530
+	echo "${PYTHON_SCRIPTDIR}"
531
+}
532
+
533
+# @FUNCTION: _python_ln_rel
534
+# @USAGE: <from> <to>
535
+# @INTERNAL
536
+# @DESCRIPTION:
537
+# Create a relative symlink.
538
+_python_ln_rel() {
539
+	debug-print-function ${FUNCNAME} "${@}"
540
+
541
+	local target=${1}
542
+	local symname=${2}
543
+
544
+	local tgpath=${target%/*}/
545
+	local sympath=${symname%/*}/
546
+	local rel_target=
547
+
548
+	while [[ ${sympath} ]]; do
549
+		local tgseg= symseg=
550
+
551
+		while [[ ! ${tgseg} && ${tgpath} ]]; do
552
+			tgseg=${tgpath%%/*}
553
+			tgpath=${tgpath#${tgseg}/}
554
+		done
555
+
556
+		while [[ ! ${symseg} && ${sympath} ]]; do
557
+			symseg=${sympath%%/*}
558
+			sympath=${sympath#${symseg}/}
559
+		done
560
+
561
+		if [[ ${tgseg} != ${symseg} ]]; then
562
+			rel_target=../${rel_target}${tgseg:+${tgseg}/}
563
+		fi
564
+	done
565
+	rel_target+=${tgpath}${target##*/}
566
+
567
+	debug-print "${FUNCNAME}: ${symname} -> ${target}"
568
+	debug-print "${FUNCNAME}: rel_target = ${rel_target}"
569
+
570
+	ln -fs "${rel_target}" "${symname}"
571
+}
572
+
573
+# @FUNCTION: python_optimize
574
+# @USAGE: [<directory>...]
575
+# @DESCRIPTION:
576
+# Compile and optimize Python modules in specified directories (absolute
577
+# paths). If no directories are provided, the default system paths
578
+# are used (prepended with ${D}).
579
+python_optimize() {
580
+	debug-print-function ${FUNCNAME} "${@}"
581
+
582
+	if [[ ${EBUILD_PHASE} == pre* || ${EBUILD_PHASE} == post* ]]; then
583
+		eerror "The new Python eclasses expect the compiled Python files to"
584
+		eerror "be controlled by the Package Manager. For this reason,"
585
+		eerror "the python_optimize function can be used only during src_* phases"
586
+		eerror "(src_install most commonly) and not during pkg_* phases."
587
+		echo
588
+		die "python_optimize is not to be used in pre/post* phases"
589
+	fi
590
+
591
+	[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
592
+
593
+	local PYTHON=${PYTHON}
594
+	[[ ${PYTHON} ]] || _python_export PYTHON
595
+	[[ -x ${PYTHON} ]] || die "PYTHON (${PYTHON}) is not executable"
596
+
597
+	# default to sys.path
598
+	if [[ ${#} -eq 0 ]]; then
599
+		local f
600
+		while IFS= read -r -d '' f; do
601
+			# 1) accept only absolute paths
602
+			#    (i.e. skip '', '.' or anything like that)
603
+			# 2) skip paths which do not exist
604
+			#    (python2.6 complains about them verbosely)
605
+
606
+			if [[ ${f} == /* && -d ${D%/}${f} ]]; then
607
+				set -- "${D%/}${f}" "${@}"
608
+			fi
609
+		done < <("${PYTHON}" -c 'import sys; print("".join(x + "\0" for x in sys.path))' || die)
610
+
611
+		debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
612
+	fi
613
+
614
+	local d
615
+	for d; do
616
+		# make sure to get a nice path without //
617
+		local instpath=${d#${D%/}}
618
+		instpath=/${instpath##/}
619
+
620
+		case "${EPYTHON}" in
621
+			python2.7|python3.[34])
622
+				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
623
+				"${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
624
+				;;
625
+			python*|pypy3)
626
+				# both levels of optimization are separate since 3.5
627
+				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
628
+				"${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
629
+				"${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
630
+				;;
631
+			*)
632
+				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
633
+				;;
634
+		esac
635
+	done
636
+}
637
+
638
+# @FUNCTION: python_scriptinto
639
+# @USAGE: <new-path>
640
+# @DESCRIPTION:
641
+# Set the directory to which files passed to python_doexe(),
642
+# python_doscript(), python_newexe() and python_newscript()
643
+# are going to be installed. The new value needs to be relative
644
+# to the installation root (${ED}).
645
+#
646
+# If not set explicitly, the directory defaults to /usr/bin.
647
+#
648
+# Example:
649
+# @CODE
650
+# src_install() {
651
+#   python_scriptinto /usr/sbin
652
+#   python_foreach_impl python_doscript foo
653
+# }
654
+# @CODE
655
+python_scriptinto() {
656
+	debug-print-function ${FUNCNAME} "${@}"
657
+
658
+	python_scriptroot=${1}
659
+}
660
+
661
+# @FUNCTION: python_doexe
662
+# @USAGE: <files>...
663
+# @DESCRIPTION:
664
+# Install the given executables into the executable install directory,
665
+# for the current Python implementation (${EPYTHON}).
666
+#
667
+# The executable will be wrapped properly for the Python implementation,
668
+# though no shebang mangling will be performed.
669
+python_doexe() {
670
+	debug-print-function ${FUNCNAME} "${@}"
671
+
672
+	local f
673
+	for f; do
674
+		python_newexe "${f}" "${f##*/}"
675
+	done
676
+}
677
+
678
+# @FUNCTION: python_newexe
679
+# @USAGE: <path> <new-name>
680
+# @DESCRIPTION:
681
+# Install the given executable into the executable install directory,
682
+# for the current Python implementation (${EPYTHON}).
683
+#
684
+# The executable will be wrapped properly for the Python implementation,
685
+# though no shebang mangling will be performed. It will be renamed
686
+# to <new-name>.
687
+python_newexe() {
688
+	debug-print-function ${FUNCNAME} "${@}"
689
+
690
+	[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
691
+	[[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
692
+
693
+	local wrapd=${python_scriptroot:-/usr/bin}
694
+
695
+	local f=${1}
696
+	local newfn=${2}
697
+
698
+	local scriptdir=$(python_get_scriptdir)
699
+	local d=${scriptdir#${EPREFIX}}
700
+
701
+	(
702
+		dodir "${wrapd}"
703
+		exeopts -m 0755
704
+		exeinto "${d}"
705
+		newexe "${f}" "${newfn}" || return ${?}
706
+	)
707
+
708
+	# install the wrapper
709
+	_python_ln_rel "${ED%/}"/usr/lib/python-exec/python-exec2 \
710
+		"${ED%/}/${wrapd}/${newfn}" || die
711
+
712
+	# don't use this at home, just call python_doscript() instead
713
+	if [[ ${_PYTHON_REWRITE_SHEBANG} ]]; then
714
+		python_fix_shebang -q "${ED%/}/${d}/${newfn}"
715
+	fi
716
+}
717
+
718
+# @FUNCTION: python_doscript
719
+# @USAGE: <files>...
720
+# @DESCRIPTION:
721
+# Install the given scripts into the executable install directory,
722
+# for the current Python implementation (${EPYTHON}).
723
+#
724
+# All specified files must start with a 'python' shebang. The shebang
725
+# will be converted, and the files will be wrapped properly
726
+# for the Python implementation.
727
+#
728
+# Example:
729
+# @CODE
730
+# src_install() {
731
+#   python_foreach_impl python_doscript ${PN}
732
+# }
733
+# @CODE
734
+python_doscript() {
735
+	debug-print-function ${FUNCNAME} "${@}"
736
+
737
+	local _PYTHON_REWRITE_SHEBANG=1
738
+	python_doexe "${@}"
739
+}
740
+
741
+# @FUNCTION: python_newscript
742
+# @USAGE: <path> <new-name>
743
+# @DESCRIPTION:
744
+# Install the given script into the executable install directory
745
+# for the current Python implementation (${EPYTHON}), and name it
746
+# <new-name>.
747
+#
748
+# The file must start with a 'python' shebang. The shebang will be
749
+# converted, and the file will be wrapped properly for the Python
750
+# implementation. It will be renamed to <new-name>.
751
+#
752
+# Example:
753
+# @CODE
754
+# src_install() {
755
+#   python_foreach_impl python_newscript foo.py foo
756
+# }
757
+# @CODE
758
+python_newscript() {
759
+	debug-print-function ${FUNCNAME} "${@}"
760
+
761
+	local _PYTHON_REWRITE_SHEBANG=1
762
+	python_newexe "${@}"
763
+}
764
+
765
+# @FUNCTION: python_moduleinto
766
+# @USAGE: <new-path>
767
+# @DESCRIPTION:
768
+# Set the Python module install directory for python_domodule().
769
+# The <new-path> can either be an absolute target system path (in which
770
+# case it needs to start with a slash, and ${ED} will be prepended to
771
+# it) or relative to the implementation's site-packages directory
772
+# (then it must not start with a slash). The relative path can be
773
+# specified either using the Python package notation (separated by dots)
774
+# or the directory notation (using slashes).
775
+#
776
+# When not set explicitly, the modules are installed to the top
777
+# site-packages directory.
778
+#
779
+# In the relative case, the exact path is determined directly
780
+# by each python_doscript/python_newscript function. Therefore,
781
+# python_moduleinto can be safely called before establishing the Python
782
+# interpreter and/or a single call can be used to set the path correctly
783
+# for multiple implementations, as can be seen in the following example.
784
+#
785
+# Example:
786
+# @CODE
787
+# src_install() {
788
+#   python_moduleinto bar
789
+#   # installs ${PYTHON_SITEDIR}/bar/baz.py
790
+#   python_foreach_impl python_domodule baz.py
791
+# }
792
+# @CODE
793
+python_moduleinto() {
794
+	debug-print-function ${FUNCNAME} "${@}"
795
+
796
+	python_moduleroot=${1}
797
+}
798
+
799
+# @FUNCTION: python_domodule
800
+# @USAGE: <files>...
801
+# @DESCRIPTION:
802
+# Install the given modules (or packages) into the current Python module
803
+# installation directory. The list can mention both modules (files)
804
+# and packages (directories). All listed files will be installed
805
+# for all enabled implementations, and compiled afterwards.
806
+#
807
+# Example:
808
+# @CODE
809
+# src_install() {
810
+#   # (${PN} being a directory)
811
+#   python_foreach_impl python_domodule ${PN}
812
+# }
813
+# @CODE
814
+python_domodule() {
815
+	debug-print-function ${FUNCNAME} "${@}"
816
+
817
+	[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
818
+
819
+	local d
820
+	if [[ ${python_moduleroot} == /* ]]; then
821
+		# absolute path
822
+		d=${python_moduleroot}
823
+	else
824
+		# relative to site-packages
825
+		local sitedir=$(python_get_sitedir)
826
+		d=${sitedir#${EPREFIX}}/${python_moduleroot//.//}
827
+	fi
828
+
829
+	(
830
+		insopts -m 0644
831
+		insinto "${d}"
832
+		doins -r "${@}" || return ${?}
833
+	)
834
+
835
+	python_optimize "${ED%/}/${d}"
836
+}
837
+
838
+# @FUNCTION: python_doheader
839
+# @USAGE: <files>...
840
+# @DESCRIPTION:
841
+# Install the given headers into the implementation-specific include
842
+# directory. This function is unconditionally recursive, i.e. you can
843
+# pass directories instead of files.
844
+#
845
+# Example:
846
+# @CODE
847
+# src_install() {
848
+#   python_foreach_impl python_doheader foo.h bar.h
849
+# }
850
+# @CODE
851
+python_doheader() {
852
+	debug-print-function ${FUNCNAME} "${@}"
853
+
854
+	[[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
855
+
856
+	local includedir=$(python_get_includedir)
857
+	local d=${includedir#${EPREFIX}}
858
+
859
+	(
860
+		insopts -m 0644
861
+		insinto "${d}"
862
+		doins -r "${@}" || return ${?}
863
+	)
864
+}
865
+
866
+# @FUNCTION: python_wrapper_setup
867
+# @USAGE: [<path> [<impl>]]
868
+# @DESCRIPTION:
869
+# Backwards compatibility function.  The relevant API is now considered
870
+# private, please use python_setup instead.
871
+python_wrapper_setup() {
872
+	debug-print-function ${FUNCNAME} "${@}"
873
+
874
+	eqawarn "python_wrapper_setup() is part of private eclass API."
875
+	eqawarn "Please call python_setup() instead."
876
+
877
+	_python_wrapper_setup "${@}"
878
+}
879
+
880
+# @FUNCTION: _python_wrapper_setup
881
+# @USAGE: [<path> [<impl>]]
882
+# @INTERNAL
883
+# @DESCRIPTION:
884
+# Create proper 'python' executable and pkg-config wrappers
885
+# (if available) in the directory named by <path>. Set up PATH
886
+# and PKG_CONFIG_PATH appropriately. <path> defaults to ${T}/${EPYTHON}.
887
+#
888
+# The wrappers will be created for implementation named by <impl>,
889
+# or for one named by ${EPYTHON} if no <impl> passed.
890
+#
891
+# If the named directory contains a python symlink already, it will
892
+# be assumed to contain proper wrappers already and only environment
893
+# setup will be done. If wrapper update is requested, the directory
894
+# shall be removed first.
895
+_python_wrapper_setup() {
896
+	debug-print-function ${FUNCNAME} "${@}"
897
+
898
+	local workdir=${1:-${T}/${EPYTHON}}
899
+	local impl=${2:-${EPYTHON}}
900
+
901
+	[[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
902
+	[[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON specified."
903
+
904
+	if [[ ! -x ${workdir}/bin/python ]]; then
905
+		_python_check_dead_variables
906
+
907
+		mkdir -p "${workdir}"/{bin,pkgconfig} || die
908
+
909
+		# Clean up, in case we were supposed to do a cheap update.
910
+		rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
911
+		rm -f "${workdir}"/bin/2to3 || die
912
+		rm -f "${workdir}"/pkgconfig/python{2,3}{,-embed}.pc || die
913
+
914
+		local EPYTHON PYTHON
915
+		_python_export "${impl}" EPYTHON PYTHON
916
+
917
+		local pyver pyother
918
+		if python_is_python3; then
919
+			pyver=3
920
+			pyother=2
921
+		else
922
+			pyver=2
923
+			pyother=3
924
+		fi
925
+
926
+		# Python interpreter
927
+		# note: we don't use symlinks because python likes to do some
928
+		# symlink reading magic that breaks stuff
929
+		# https://bugs.gentoo.org/show_bug.cgi?id=555752
930
+		cat > "${workdir}/bin/python" <<-_EOF_ || die
931
+			#!/bin/sh
932
+			exec "${PYTHON}" "\${@}"
933
+		_EOF_
934
+		cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
935
+		chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
936
+
937
+		local nonsupp=( "python${pyother}" "python${pyother}-config" )
938
+
939
+		# CPython-specific
940
+		if [[ ${EPYTHON} == python* ]]; then
941
+			cat > "${workdir}/bin/python-config" <<-_EOF_ || die
942
+				#!/bin/sh
943
+				exec "${PYTHON}-config" "\${@}"
944
+			_EOF_
945
+			cp "${workdir}/bin/python-config" \
946
+				"${workdir}/bin/python${pyver}-config" || die
947
+			chmod +x "${workdir}/bin/python-config" \
948
+				"${workdir}/bin/python${pyver}-config" || die
949
+
950
+			# Python 2.6+.
951
+			ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
952
+
953
+			# Python 2.7+.
954
+			ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}.pc \
955
+				"${workdir}"/pkgconfig/python${pyver}.pc || die
956
+
957
+			# Python 3.8+.
958
+			if [[ ${EPYTHON} != python[23].[67] ]]; then
959
+				ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}-embed.pc \
960
+					"${workdir}"/pkgconfig/python${pyver}-embed.pc || die
961
+			fi
962
+		else
963
+			nonsupp+=( 2to3 python-config "python${pyver}-config" )
964
+		fi
965
+
966
+		local x
967
+		for x in "${nonsupp[@]}"; do
968
+			cat >"${workdir}"/bin/${x} <<-_EOF_ || die
969
+				#!/bin/sh
970
+				echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
971
+				exit 127
972
+			_EOF_
973
+			chmod +x "${workdir}"/bin/${x} || die
974
+		done
975
+	fi
976
+
977
+	# Now, set the environment.
978
+	# But note that ${workdir} may be shared with something else,
979
+	# and thus already on top of PATH.
980
+	if [[ ${PATH##:*} != ${workdir}/bin ]]; then
981
+		PATH=${workdir}/bin${PATH:+:${PATH}}
982
+	fi
983
+	if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
984
+		PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
985
+	fi
986
+	export PATH PKG_CONFIG_PATH
987
+}
988
+
989
+# @FUNCTION: python_is_python3
990
+# @USAGE: [<impl>]
991
+# @DESCRIPTION:
992
+# Check whether <impl> (or ${EPYTHON}) is a Python3k variant
993
+# (i.e. uses syntax and stdlib of Python 3.*).
994
+#
995
+# Returns 0 (true) if it is, 1 (false) otherwise.
996
+python_is_python3() {
997
+	local impl=${1:-${EPYTHON}}
998
+	[[ ${impl} ]] || die "python_is_python3: no impl nor EPYTHON"
999
+
1000
+	[[ ${impl} == python3* || ${impl} == pypy3 ]]
1001
+}
1002
+
1003
+# @FUNCTION: python_is_installed
1004
+# @USAGE: [<impl>]
1005
+# @DESCRIPTION:
1006
+# Check whether the interpreter for <impl> (or ${EPYTHON}) is installed.
1007
+# Uses has_version with a proper dependency string.
1008
+#
1009
+# Returns 0 (true) if it is, 1 (false) otherwise.
1010
+python_is_installed() {
1011
+	local impl=${1:-${EPYTHON}}
1012
+	[[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
1013
+	local hasv_args=()