aboutsummaryrefslogtreecommitdiff
blob: a1d620f85fa6e611bb20b7259dc4a3a323652cab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

# @ECLASS: python-multilib-single-r1
# @MAINTAINER:
# Python team <python@gentoo.org>
# @AUTHOR:
# Greg Turner <gmt@be-evil.net>
# Based on work of: Michał Górny <mgorny@gentoo.org>
# Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
# @BLURB: An eclass for Python packages not installed for multiple implementations.
# @DESCRIPTION:
# Multilib reimplementation of python-single-r1.
#
# This eclass extends the IUSE and REQUIRED_USE set by python-r1
# to request correct PYTHON_SINGLE_TARGET. It also provides
# PYTHON_MULTILIB_USEDEP and PYTHON_MULTILIB_DEPS in a suitable form.
#
# Please note that packages support multiple Python implementations
# (using python-r1 eclass or python-multilib-r1 eclass) can not depend
# on packages not supporting them (using this eclass).
#
# Please note that python-multilib-single-r1 will always
# inherit python-multilib-utils-r1 as well. Thus, all the functions defined
# there can be used in the packages using python-single-r1, and there is no
# need ever to inherit both.
#
# For more information, please see the python-r1 Developer's Guide:
# http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml

case "${EAPI:-0}" in
	0|1|2|3)
		die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
		;;
	4|5)
		# EAPI=4 is required for USE default deps on USE_EXPAND flags
		;;
	*)
		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
		;;
esac

# @ECLASS-VARIABLE: PYTHON_COMPAT
# @DESCRIPTION:
# This variable contains a list of Python implementations the package
# supports. It must be set before the `inherit' call. It has to be
# an array.
#
# Example:
# @CODE
# PYTHON_COMPAT=( python{2_5,2_6,2_7} )
# @CODE

# @ECLASS-VARIABLE: PYTHON_REQ_USE_MULTILIB
# @DEFAULT_UNSET
# @DESCRIPTION:
# The list of USEflags required to be enabled on the chosen Python
# implementations, formed as a USE-dependency string. It should be valid
# for all implementations in PYTHON_COMPAT_MULTILIB, so it may be necessary to
# use USE defaults.
#
# This should be set before calling `inherit'.
#
# Example:
# @CODE
# PYTHON_REQ_USE_MULTILIB="gdbm,ncurses(-)?"
# @CODE
#
# It will cause the Python dependencies to look like:
# @CODE
# python_single_target_pythonX_Y? ( dev-lang/python:X.Y[gdbm,ncurses(-)?,${PYTHON_MULTILIB_USEDEP}] )
# @CODE

# @ECLASS-VARIABLE: PYTHON_MULTILIB_DEPS
# @DESCRIPTION:
# This is an framework-generated Python dependency string for all
# implementations listed in PYTHON_COMPAT_MULTILIB.
#
# The dependency string is conditional on PYTHON_SINGLE_TARGET
# and MULTILIB_USEDEP.
#
# Example use:
# @CODE
# RDEPEND="${PYTHON_MULTILIB_DEPS}
#	dev-foo/mydep"
# DEPEND="${RDEPEND}"
# @CODE
#
# Example value:
# @CODE
# FIXME
# @CODE

# @ECLASS-VARIABLE: PYTHON_MULTILIB_SINGLE_MODE
# @DEFAULT_UNSET
# @DESCRIPTION:
# It is rather awkward for a descendant of python-single-r1 to support
# multiple python ABIs as this will not make for trivial porting.
# Rather than attempt a one-size-fits all solution, the python-multilib-r1
# version offers the following modes.  Each of them may be activated by
# placing its name into the PYTHON_MULTILIB_SINGLE_MODE variable before
# inheriting pythong-multilib-single-r1.  For example:
#
# @CODE@
# PYTHON_MULTILIB_SINGLE_MODE=flexible
# inherit python-multilib-single-r1
# @CODE@
#
# The supported modes and their descriptions follow:
#
# default: This mode is selected if the PYTHON_MULTILIB_SINGLE_MODE
# variable is not set.  In this mode, python-multilib-single-r1 acts
# as similarly as possible to the python-single-r1 eclass in that,
# really and truly, only a single no-multilib target may be selected,
# and, if any corresponding multilib targets are enabled corresponding
# to that target, one and only one of them must be selected as well.
# The effective result of this arrangement is that literally a single
# multilib or no-multilib python target will be active.  In this mode,
# the pkg_depend phase function is exported and the python environment
# is established automatically there.  This should minimize the pain
# of porting existing python-multilib-single-r1 ebuilds, but it 
# will maximize the pain for multilib users who will be often pointlessly
# prevented from enabling multiple multilib ABIs in a long chain of
# interdependent ebuilds.  In this mode, the requirement that multilib
# abis match python-multilib abis is not enforced.
#
# flexible: although it will require a greater porting effort, this is
# the most user-friendly mode.  The requirement that multilib abis
# match python ABIs is not enforced; in this mode, for example, it is
# possible for the python_multilib_single_python2_7_x86_x32 use flag to
# be enabled even when the abi_x86_x32 use flag is not enabled for the
# same ebuid.  This does not excuse the ebuild author or the user from
# ensuring that correct dependencies are enforced; it simply divorces the
# multilib ABI of the package from the multilib ABI of python.  This
# can be hard to do correctly so it's not recommended unless you're
# sure you're able to get everything right.  It only makes sense in cases
# where the python interpreter is invoked by the package as an executable
# and not linked to as a library, or when the python build flag may
# be turned off on a per-multilib-ABI basis at configure time.
# To use this mode, you will probably want to invoke python_foreach_impl
# or python_parallel_foreach_impl, or to consume an eclass which invokes
# those for you, in order to get all of the python ABIs correctly
# be iterated through, activated, and worked with correctly.
#
# simple: This is the recommended setting for most ebuilds, even though
# it is not the default since it is easier to port to the default mode
# as a starting point.  In this mode, a complete agreement between the
# multilib-build multilib ABIs and the enabled multilib python ABIs is
# enforced.  In other words, if abi_x86_32 is enabled, and "python2_7"
# is in PYTHON_TARGETS, then PYTHON_MULTILIB_SINGLE_TARGETS_PYTHON2_7_X86
# must contain "32", and, if PYTHON_MULTILIB_SINGLE_TARGETS_PYTHON2_7_X86
# contains "32", then ABI_X86 must contain 32 as well, and
# PYTHON_TARGETS must contain "python2_7".

# @ECLASS-VARIABLE: PYTHON_MULTILIB_USEDEP
# @DESCRIPTION:
# This is an eclass-generated USE-dependency string which can be used to
# depend on another multilib Python package being built for the same Python
# implementations.
#
# The generate USE-flag dependency specifier specification suitable for
# use in dependency atoms for python dependencies.
#
# python-multilib-single-r1 (and maybe later, python-multilib-distutils-ng)
# eclasses. It must not be used on packages using python.eclass.
#
# Example:
#
# @CODE
# RDEPEND="dev-python/foo[${PYTHON_MULTILIB_USEDEP}]"
# @CODE
#
# Example value:
# @CODE
# FIXME
# @CODE

# @ECLASS-VARIABLE: PYTHON_MULTILIB_REQUIRED_USE
# @DESCRIPTION:
# This is an eclass-generated required-use expression which ensures the following:
# 1. Exactly one PYTHON_SINGLE_TARGET value has been enabled.
# 2. The selected PYTHON_SINGLE_TARGET value is enabled in PYTHON_TARGETS.
# 3. No PYTHON_MULTILIB_SINGLE_TARGETS target may be enabled which
#    does not corespond to the selected PYTHON_SINGLE_TARGET
# 4. Each enabled PYTHON_MULTILIB_SINGLE_TARGETS value is enabled in
#    PYTHON_MULTILIB_TARGETS
# 5. Each enabled multilib ABI target requires the corresponding
#    PYTHON_MULTILIB_SINGLE_TARGETS target to be enabled
#    if its corresponding PYTHON_SINGLE_TARGET is enabled.
# 6. At least one PYTHON_MULTILIB_SINGLE_TARGET is enabed.
# 7. Each enabled PYTHON_MULTILIB_SINGLE_TARGET requires
#    the corresponding multilib ABI target to be enabled.
#
# This expression should be utilized in an ebuild by including it in
# REQUIRED_USE, optionally behind a use flag.
#
# Example use:
# @CODE
# REQUIRED_USE="python? ( ${PYTHON_MULTILIB_REQUIRED_USE} )"
# @CODE
#
# Example value:
# @CODE
# <tl;dr>
# @CODE

if [[ ! ${_PYTHON_MULTILIB_SINGLE_R1} ]] ; then
	if [[ ${_PYTHON_ANY_R1} ]]; then
		die 'python-multilib-single-r1.eclass can not be used with python-any-r1.eclass.'
	elif [[ ${_PYTHON_UTILS_R1} ]]; then
		die 'python-multilib-single-r1.eclass cannot be used with python-*-r1 no-multilib eclasses.'
	fi
	
	declare -p PYTHON_COMPAT &>/dev/null || \
		die 'PYTHON_COMPAT not declared.'

	[[ ${_PYTHON_MULTILIB_R1} ]] || \
		inherit python-multilib-r1

_python_single_multilib_set_globals() {
	debug-print-function ${FUNCNAME} "$@"

	local impls=()
	local i si abi uf PYTHON_MULTILIB_PKG_DEP i2 i3

	: ${PYTHON_MULTILIB_SINGLE_MODE:=default}

	PYTHON_MULTILIB_DEPS=
	debug-print "${FUNCNAME}: ----------- nomultilib ----------"

	for i in "${PYTHON_COMPAT[@]}"; do
		_python_nomultilib_impl_supported "${i}" || continue

		# The chosen targets need to be in PYTHON_TARGETS as well.
		# This is in order to enforce correct dependencies on packages
		# supporting multiple implementations.
		PYTHON_MULTILIB_REQUIRED_USE+=" python_single_target_${i}? ( python_targets_${i}" 

		# They are also incompatible with any multilib targets not corresponding
		# to this no-multilib target.  Meanwhile, build composite deps requirements
		# specifying that simultaneously enabled multilib abis and no-multilib single
		# targets require the corresponding multilib single target to be enabled.
		for i2 in "${_CACHED_MULTILIB_FLAGS[@]}" ; do
			[[ ${PYTHON_MULTILIB_SINGLE_MODE} != flexible ]] && \
				PYTHON_MULTILIB_REQUIRED_USE+=" abi_${i2}? ( python_multilib_single_targets_${i}_${i2} )"
			for i3 in "${PYTHON_COMPAT[@]}" ; do
				[[ ${i3} == ${i} ]] && continue
				PYTHON_MULTILIB_REQUIRED_USE+=" !python_multilib_single_targets_${i3}_${i2}"
			done
		done
		
		PYTHON_MULTILIB_REQUIRED_USE+=" ) "
		debug-print "${FUNCNAME}: (after no-multi) PYTHON_MULTILIB_REQUIRED_USE=\"${PYTHON_MULTILIB_REQUIRED_USE}\""

		python_export "${i}" PYTHON_MULTILIB_PKG_DEP
		PYTHON_MULTILIB_DEPS+="python_single_target_${i}? ( ${PYTHON_MULTILIB_PKG_DEP} ) "

		impls+=( "${i}" )
	done

	if [[ ${#impls[@]} -eq 0 ]]; then
		die "No supported implementation in PYTHON_COMPAT."
	fi
	debug-print "${FUNCNAME}: impls=(${impls[*]})"

	local flags_mt=( "${impls[@]/#/python_targets_}" )
	debug-print "${FUNCNAME}: flags_mt=(${flags_mt[*]})"

	local flags=( "${impls[@]/#/python_single_target_}" )
	debug-print "${FUNCNAME}: flags=(${flags[*]})"

	local optflags=${flags_mt[@]/%/(-)?}
	optflags+=,${flags[@]/%/(+)?}
	debug-print "${FUNCNAME}: optflags=(${optflags[*]})"

	IUSE="${flags_mt[*]} ${flags[*]}"
	debug-print "${FUNCNAME}: IUSE=\"${IUSE}\""

	PYTHON_REQUIRED_USE+=" ^^ ( ${flags[*]} )"
	debug-print "${FUNCNAME}: PYTHON_REQUIRED_USE=\"${PYTHON_REQUIRED_USE}\""

	PYTHON_MULTILIB_USEDEP=${optflags// /,}
	debug-print "${FUNCNAME}: PYTHON_MULTILIB_USEDEP=\"${PYTHON_MULTILIB_USEDEP}\""

	PYTHON_MULTILIB_DEPS+=" dev-lang/python-exec:=[${PYTHON_MULTILIB_USEDEP}]"
	debug-print "${FUNCNAME}: PYTHON_MULTILIB_DEPS=\"${PYTHON_MULTILIB_DEPS}\""

	# now do the multilib variables
	debug-print "${FUNCNAME}: ------------ multilib -----------"

	impls=()
	for i in "${PYTHON_COMPAT_MULTILIB[@]}"; do
		_python_multilib_impl_supported "${i}" || continue

		si=$(_python_strip_multilib_impl_abi "${i}")
		uf="abi${i#${si}}"
		i2=$(epythonize "${i}")

		# this will always work during the depend phase but some irrelevant stuff will
		# go missing during the others, due to ABIs disabled in portage.
		# FIXME: probably a pms violation
		if [[ ${i2} ]] ; then
			# The chosen targets need to be in PYTHON_TARGETS and
			# PYTHON_MULTILIB_TARGETS as well.
			#
			# This is in order to enforce correct dependencies on packages
			# supporting multiple implementations.
			PYTHON_MULTILIB_REQUIRED_USE+=" python_multilib_single_targets_${i}? (
				python_multilib_targets_${i}
				python_single_target_${si} "
			# in flexible mode the multilib abi needn't match the python multilib abi
			[[ ${PYTHON_MULTILIB_SINGLE_MODE} != flexible ]] &&
				PYTHON_MULTILIB_REQUIRED_USE+="${uf} "
			PYTHON_MULTILIB_REQUIRED_USE+=") "
	
			python_export "${i2}" PYTHON_MULTILIB_PKG_DEP
			PYTHON_MULTILIB_DEPS+=" python_multilib_single_targets_${i}? ( ${PYTHON_MULTILIB_PKG_DEP} ) "
			impls+=( "${i}" )
		fi
	done

	if [[ ${#impls[@]} -eq 0 ]]; then
		die "No supported implementation in PYTHON_COMPAT_MULTILIB."
	fi

	debug-print "${FUNCNAME}: impls=(${impls[*]})"

	flags_mt=( "${impls[@]/#/python_multilib_targets_}" )
	debug-print "${FUNCNAME}: flags_mt=(${flags_mt[*]})"
	flags=( "${impls[@]/#/python_multilib_single_targets_}" )
	debug-print "${FUNCNAME}: flags=(${flags[*]})"

	optflags=${flags_mt[@]/%/(-)?}
	optflags+=,${flags[@]/%/(+)?}
	debug-print "${FUNCNAME}: optflags=(${optflags[*]})"

	IUSE+=" ${flags_mt[*]} ${flags[*]}"
	debug-print "${FUNCNAME}: final value: IUSE=\"${IUSE}\""

	# in default mode, at most a single multilib useflag is allowed to be selected
	[[ ${PYTHON_MULTILIB_SINGLE_MODE} == default ]] &&
		PYTHON_MULTILIB_REQUIRED_USE+=" || ( ^^ ( ${flags[*]} ) ( ${flags[*]/#/!} ) )"
	debug-print "${FUNCNAME}: final value: PYTHON_MULTILIB_REQUIRED_USE=\"${PYTHON_MULTILIB_REQUIRED_USE}\""

	PYTHON_MULTILIB_USEDEP+="${PYTHON_MULTILIB_USEDEP:+,}${optflags// /,}"
	debug-print "${FUNCNAME}: PYTHON_MULTILIB_USEDEP=\"${PYTHON_MULTILIB_USEDEP}\""

	# 1) well, python-exec would suffice as an RDEP
	# but no point in making this overcomplex, BDEP doesn't hurt anyone
	PYTHON_MULTILIB_DEPS+=" dev-lang/python-exec:=[${PYTHON_MULTILIB_USEDEP}]"
	debug-print "${FUNCNAME}: final result: PYTHON_MULTILIB_DEPS=\"${PYTHON_MULTILIB_DEPS}\""
}
_python_single_multilib_set_globals

# @FUNCTION: python_setup
# @DESCRIPTION:
# There's such thing here.  Don't call this.
python_setup() {
	die "\"${FUNCNAME}\"?  Don't know him.  Try the eclass a few inodes down the dirent, maybe."
}

# @FUNCTION: python_multilib_single_foreach_python
# @DESCRIPTION:
# Determine what the selected Python implementation is, specializing for
# any active multilib-build ABI.  Set the Python build environment up; then,
# run whatever was passed in as an argument.  Then, put things roughly back
# the way they were before.
#python_multilib_single_foreach_python() {
#	debug-print-function ${FUNCNAME} "${@}"
#
#	local EPYTHON PYTHON
#
#	local impl nomulti_impl=
#
#	for impl in "${_PYTHON_ALL_IMPLS_NOMULTILIB[@]}"; do
#		if has "${impl}" "${PYTHON_COMPAT[@]}" \
#			&& use "python_single_target_${impl}"
#		then
#			if [[ ${EPYTHON} ]]; then
#				eerror "Your PYTHON_SINGLE_TARGET setting lists more than a single Python"
#				eerror "implementation. Please set it to just one value. If you need"
#				eerror "to override the value for a single package, please use package.env"
#				eerror "or an equivalent solution (man 5 portage)."
#				echo
#				die "More than one implementation in PYTHON_SINGLE_TARGET."
#			fi
#
#			if ! use "python_targets_${impl}"; then
#				eerror "The implementation chosen as PYTHON_SINGLE_TARGET must be added"
#				eerror "to PYTHON_TARGETS as well. This is in order to ensure that"
#				eerror "dependencies are satisfied correctly. We're sorry"
#				eerror "for the inconvenience."
#				echo
#				die "Build target (${impl}) not in PYTHON_TARGETS."
#			fi
#			EPYTHON=$(epythonize ${impl})
#			nomulti_impl="${impl}"
#			debug-print "${FUNCNAME}: Found matching no-multilib impl \"${impl}\""
#		fi
#	done
#
#	if [[ ! ${EPYTHON} ]]; then
#		eerror "No Python implementation selected for the build. Please set"
#		eerror "the PYTHON_SINGLE_TARGET variable in your make.conf to one"
#		eerror "of the following values:"
#		eerror
#		eerror "${PYTHON_COMPAT[@]}"
#		echo
#		die "No supported Python implementation in PYTHON_SINGLE_TARGET."
#	fi
#
#	# great, we're GTG for no-multilib.  Anything better out in multilib-land?
#	if [[ "${MULTILIB_BUILD_ABI}" ]] ; then 
#		local other_epython other_impl abi_flag=$(multilib_abi_flag "${MULTILIB_BUILD_ABI}")
#		abi_flag="${abi_flag#abi_}"
#		if [[ ${abi_flag} ]] ; then
#			other_impl="${nomulti_impl}_${abi_flag}"
#			if has "${other_impl}" "${PYTHON_COMPAT_MULTILIB[@]}" \
#			&& use "python_multilib_single_targets_${other_impl}"
#			then
#				other_epython=$(epythonize "${other_impl}")
#				if [[ ${other_epython} != ${EPYTHON} ]]; then
#					debug-print "${FUNCNAME}: \"${EPYTHON}\" (nomulti) vs \"${other_epython}\" (multi)?"
#
#					# a wee sanity check
#					local sother_epython=$(_python_strip_epython_abi "${other_epython}")
#					if [[ ${EPYTHON} != ${sother_epython} ]] ; then
#						eerror "The python implementation \"${other_impl}\" appears in your"
#						eerror "PYTHON_MULTILIB_SINGLE_TARGETS_... and seems to correspond to"
#						eerror "the value \"${nomulti_impl}\" in PYTHON_SINGLE_TARGET.  However,"
#						eerror "the epython's don't seem to have the same relationship:"
#						eerror "EPYTHON=\"${EPYTHON}\";other_epython=\"${other_epython}\";sother_epython=\"${sother_epython}\"."
#						eerror "That's not even supposed to be possible!"
#						echo
#						die "${FUNCNAME}: Some kinda bug in the framework, it seems."
#					fi
#				fi
#			fi
#			debug-print "${FUNCNAME}: Yay, declaring multilib victory:"
#			debug-print "${FUNCNAME}: EPYTHON multilib-abi-adjusted from \"${EPYTHON}\" to \"${other_epython}\""
#			EPYTHON=${other_epython}
#		fi
#	fi
#
#	# multilib or not, doesn't matter from here on out.
#	local PATH="${PATH}" PKG_CONFIG_PATH="${PKG_CONFIG_PATH}"
#	export PATH PKG_CONFIG_PATH
#	python_export EPYTHON PYTHON
#	python_wrapper_setup
#	"$@"
#}

# @FUNCTION: python_fix_shebang
# @USAGE: <path>...
# @DESCRIPTION:
# Replace the shebang in Python scripts with the current Python
# implementation (EPYTHON). If a directory is passed, works recursively
# on all Python scripts.
#
# Only files having a 'python' shebang will be modified; other files
# will be skipped. If a script has a complete shebang matching
# the chosen interpreter version, it is left unmodified. If a script has
# a complete shebang matching other version, the command dies.
python_fix_shebang() {
	debug-print-function ${FUNCNAME} "${@}"

	[[ ${1} ]] || die "${FUNCNAME}: no paths given"
	[[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)"

	local path f
	for path; do
		while IFS= read -r -d '' f; do
			local shebang=$(head -n 1 "${f}")

			case "${shebang}" in
				'#!'*${EPYTHON}*)
					debug-print "${FUNCNAME}: in file ${f#${D}}"
					debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
					;;
				'#!'*python[23].[0123456789]*|'#!'*pypy-c*|'#!'*jython*)
					debug-print "${FUNCNAME}: in file ${f#${D}}"
					debug-print "${FUNCNAME}: incorrect specific shebang: ${shebang}"

					die "${f#${D}} has a specific Python shebang not matching EPYTHON"
					;;
				'#!'*python*)
					debug-print "${FUNCNAME}: in file ${f#${D}}"
					debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"

					einfo "Fixing shebang in ${f#${D}}"
					python_rewrite_shebang_multilib "${f}"
			esac
		done < <(find "${path}" -type f -print0)
	done
}

python_multilib_single_with_abi_python() {
	# obtain the abis list
	_python_cache_active_impls
	_python_check_USE_PYTHON
	local impl mp_impl
	for impl in "${_PYTHON_ACTIVE_NOMULTILIB_IMPL_CACHE}" ; do
		for ml_impl in "${_PYTHON_ACTIVE_MULTILIB_IMPL_CACHE}" ; do
			debug-print "${FUNCNAME}: checking impl=\"${impl}\" ml_impl=\"${ml_impl}\" strip_impl_abi -> \"$(_python_strip_multilib_impl_abi ${ml_impl})\" impl_abi -> \"$(_python_impl_abi ${ml_impl})\""
			if [[ $(_python_strip_multilib_impl_abi ${ml_impl}) == ${impl} ]] ; then
				if [[ $(_python_impl_abi ${ml_impl}) == ${ABI:-${DEFAULT_ABI:-default}} ]] ; then
					if [[ $(_python_impl_abi ${ml_impl}) == ${DEFAULT_ABI:-${ABI:-default}} ]] ; then
						debug-print "${FUNCNAME}: got it: invoking python_multilib_automagic_wrapper \"\${impl}\" \"\$@\""
						python_multilib_automagic_wrapper "${impl}" "$@"
					else
						debug-print "${FUNCNAME}: got it: invoking python_multilib_automagic_wrapper \"\${ml_impl}\" \"\$@\""
						python_multilib_automagic_wrapper "${ml_impl}" "$@"
					fi
					return $?
				fi
			fi
		done
		debug-print "${FUNCNAME}: got it (no-ml): invoking python_multilib_automagic_wrapper \"\${impl}\" \"\$@\""
		if [[ $(_python_impl_abi ${impl}) == ${ABI:-${DEFAULT_ABI:-default}} ]] ; then
			python_multilib_automagic_wrapper "${impl}" "$@"
			return $?
		fi
	done
	die "${FUNCNAME}: cant figure out correct impl"
}

_PYTHON_MULTILIB_SINGLE_R1=1
fi