1 # Copyright 1999-2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: python-utils-r1.eclass
6 # Python team <python@gentoo.org>
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.
13 # A utility eclass providing functions to query Python implementations,
14 # install Python modules and scripts.
16 # This eclass does not set any metadata variables nor export any phase
17 # functions. It can be inherited safely.
19 # For more information, please see the wiki:
20 # https://wiki.gentoo.org/wiki/Project:Python/python-utils-r1
23 [0-4]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
25 *) die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
28 if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
29 die 'python-r1 suite eclasses can not be used with python.eclass.'
32 if [[ ! ${_PYTHON_UTILS_R1} ]]; then
34 [[ ${EAPI} == 5 ]] && inherit eutils multilib
35 inherit toolchain-funcs
37 # @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
40 # All supported Python implementations, most preferred last.
44 python3_6 python3_7 python3_8
46 readonly _PYTHON_ALL_IMPLS
48 # @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
51 # Set to a non-empty value in order to make eclass tolerate (ignore)
52 # unknown implementations in PYTHON_COMPAT.
54 # This is intended to be set by the user when using ebuilds that may
55 # have unknown (newer) implementations in PYTHON_COMPAT. The assumption
56 # is that the ebuilds are intended to be used within multiple contexts
57 # which can involve revisions of this eclass that support a different
58 # set of Python implementations.
60 # @FUNCTION: _python_impl_supported
64 # Check whether the implementation <impl> (PYTHON_COMPAT-form)
67 # Returns 0 if the implementation is valid and supported. If it is
68 # unsupported, returns 1 -- and the caller should ignore the entry.
69 # If it is invalid, dies with an appopriate error messages.
70 _python_impl_supported() {
71 debug-print-function ${FUNCNAME} "${@}"
73 [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
77 # keep in sync with _PYTHON_ALL_IMPLS!
78 # (not using that list because inline patterns shall be faster)
80 python2_7|python3_[678]|pypy3)
83 jython2_7|pypy|pypy1_[89]|pypy2_0|python2_[56]|python3_[12345])
87 [[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
88 die "Invalid implementation in PYTHON_COMPAT: ${impl}"
92 # @FUNCTION: _python_set_impls
95 # Check PYTHON_COMPAT for well-formedness and validity, then set
96 # two global variables:
98 # - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
99 # by the ebuild (PYTHON_COMPAT - dead implementations),
101 # - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
102 # are not supported by the ebuild.
104 # Implementations in both variables are ordered using the pre-defined
105 # eclass implementation ordering.
107 # This function must be called once in global scope by an eclass
108 # utilizing PYTHON_COMPAT.
109 _python_set_impls() {
112 if ! declare -p PYTHON_COMPAT &>/dev/null; then
113 die 'PYTHON_COMPAT not declared.'
115 if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
116 die 'PYTHON_COMPAT must be an array.'
118 for i in "${PYTHON_COMPAT[@]}"; do
119 # trigger validity checks
120 _python_impl_supported "${i}"
123 local supp=() unsupp=()
125 for i in "${_PYTHON_ALL_IMPLS[@]}"; do
126 if has "${i}" "${PYTHON_COMPAT[@]}"; then
133 if [[ ! ${supp[@]} ]]; then
134 die "No supported implementation in PYTHON_COMPAT."
137 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
138 # set once already, verify integrity
139 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
140 eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
141 eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
142 eerror "Now : ${supp[*]}"
143 die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
145 if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
146 eerror "Unsupported impls changed between inherits!"
147 eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
148 eerror "Now : ${unsupp[*]}"
149 die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
152 _PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
153 _PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
154 readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
158 # @FUNCTION: _python_impl_matches
159 # @USAGE: <impl> [<pattern>...]
162 # Check whether the specified <impl> matches at least one
163 # of the patterns following it. Return 0 if it does, 1 otherwise.
164 # Matches if no patterns are provided.
166 # <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
168 # a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
169 # b) '-2' to indicate all Python 2 variants (= !python_is_python3)
170 # c) '-3' to indicate all Python 3 variants (= python_is_python3)
171 _python_impl_matches() {
172 [[ ${#} -ge 1 ]] || die "${FUNCNAME}: takes at least 1 parameter"
173 [[ ${#} -eq 1 ]] && return 0
175 local impl=${1} pattern
179 if [[ ${pattern} == -2 ]]; then
180 python_is_python3 "${impl}" || return 0
181 elif [[ ${pattern} == -3 ]]; then
182 python_is_python3 "${impl}" && return 0
184 # unify value style to allow lax matching
185 elif [[ ${impl/./_} == ${pattern/./_} ]]; then
193 # @ECLASS-VARIABLE: PYTHON
196 # The absolute path to the current Python interpreter.
198 # This variable is set automatically in the following contexts:
200 # python-r1: Set in functions called by python_foreach_impl() or after
201 # calling python_export_best().
203 # python-single-r1: Set after calling python-single-r1_pkg_setup().
205 # distutils-r1: Set within any of the python sub-phase functions.
212 # @ECLASS-VARIABLE: EPYTHON
215 # The executable name of the current Python interpreter.
217 # This variable is set automatically in the following contexts:
219 # python-r1: Set in functions called by python_foreach_impl() or after
220 # calling python_export_best().
222 # python-single-r1: Set after calling python-single-r1_pkg_setup().
224 # distutils-r1: Set within any of the python sub-phase functions.
231 # @ECLASS-VARIABLE: PYTHON_SITEDIR
234 # The path to Python site-packages directory.
236 # Set and exported on request using python_export().
237 # Requires a proper build-time dependency on the Python implementation.
241 # /usr/lib64/python2.7/site-packages
244 # @ECLASS-VARIABLE: PYTHON_INCLUDEDIR
247 # The path to Python include directory.
249 # Set and exported on request using python_export().
250 # Requires a proper build-time dependency on the Python implementation.
254 # /usr/include/python2.7
257 # @ECLASS-VARIABLE: PYTHON_LIBPATH
260 # The path to Python library.
262 # Set and exported on request using python_export().
263 # Valid only for CPython. Requires a proper build-time dependency
264 # on the Python implementation.
268 # /usr/lib64/libpython2.7.so
271 # @ECLASS-VARIABLE: PYTHON_CFLAGS
274 # Proper C compiler flags for building against Python. Obtained from
275 # pkg-config or python-config.
277 # Set and exported on request using python_export().
278 # Valid only for CPython. Requires a proper build-time dependency
279 # on the Python implementation and on pkg-config.
283 # -I/usr/include/python2.7
286 # @ECLASS-VARIABLE: PYTHON_LIBS
289 # Proper C compiler flags for linking against Python. Obtained from
290 # pkg-config or python-config.
292 # Set and exported on request using python_export().
293 # Valid only for CPython. Requires a proper build-time dependency
294 # on the Python implementation and on pkg-config.
301 # @ECLASS-VARIABLE: PYTHON_CONFIG
304 # Path to the python-config executable.
306 # Set and exported on request using python_export().
307 # Valid only for CPython. Requires a proper build-time dependency
308 # on the Python implementation and on pkg-config.
312 # /usr/bin/python2.7-config
315 # @ECLASS-VARIABLE: PYTHON_PKG_DEP
318 # The complete dependency on a particular Python package as a string.
320 # Set and exported on request using python_export().
324 # dev-lang/python:2.7[xml]
327 # @ECLASS-VARIABLE: PYTHON_SCRIPTDIR
330 # The location where Python scripts must be installed for current impl.
332 # Set and exported on request using python_export().
336 # /usr/lib/python-exec/python2.7
339 # @FUNCTION: python_export
340 # @USAGE: [<impl>] <variables>...
342 # Set and export the Python implementation-relevant variables passed
345 # The optional first parameter may specify the requested Python
346 # implementation (either as PYTHON_TARGETS value, e.g. python2_7,
347 # or an EPYTHON one, e.g. python2.7). If no implementation passed,
348 # the current one will be obtained from ${EPYTHON}.
350 # The variables which can be exported are: PYTHON, EPYTHON,
351 # PYTHON_SITEDIR. They are described more completely in the eclass
352 # variable documentation.
354 debug-print-function ${FUNCNAME} "${@}"
369 if [[ -z ${impl} ]]; then
370 die "python_export called without a python implementation and EPYTHON is unset"
374 debug-print "${FUNCNAME}: implementation: ${impl}"
379 export EPYTHON=${impl}
380 debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
383 export PYTHON=${EPREFIX}/usr/bin/${impl}
384 debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
387 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
388 # sysconfig can't be used because:
389 # 1) pypy doesn't give site-packages but stdlib
390 # 2) jython gives paths with wrong case
391 PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
392 export PYTHON_SITEDIR
393 debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
396 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
397 PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
398 export PYTHON_INCLUDEDIR
399 debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
401 # Jython gives a non-existing directory
402 if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
403 die "${impl} does not install any header files!"
407 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
408 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
409 export PYTHON_LIBPATH
410 debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
412 if [[ ! ${PYTHON_LIBPATH} ]]; then
413 die "${impl} lacks a (usable) dynamic library"
421 # python-2.7, python-3.2, etc.
422 val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
425 die "${impl}: obtaining ${var} not supported"
429 export PYTHON_CFLAGS=${val}
430 debug-print "${FUNCNAME}: PYTHON_CFLAGS = ${PYTHON_CFLAGS}"
437 # python-2.7, python-3.2, etc.
438 val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
441 die "${impl}: obtaining ${var} not supported"
445 export PYTHON_LIBS=${val}
446 debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
453 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
454 flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
455 val=${PYTHON}${flags}-config
458 die "${impl}: obtaining ${var} not supported"
462 export PYTHON_CONFIG=${val}
463 debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
469 PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
471 PYTHON_PKG_DEP='>=dev-lang/python-3.3.2-r2:3.3';;
473 PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
475 PYTHON_PKG_DEP='>=dev-python/pypy-5:0=';;
477 PYTHON_PKG_DEP='>=dev-python/pypy3-5:0=';;
479 PYTHON_PKG_DEP='dev-java/jython:2.7';;
481 die "Invalid implementation: ${impl}"
485 if [[ ${PYTHON_REQ_USE} ]]; then
486 PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
489 export PYTHON_PKG_DEP
490 debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
494 export PYTHON_SCRIPTDIR=${EPREFIX}/usr/lib/python-exec/${impl}
495 debug-print "${FUNCNAME}: PYTHON_SCRIPTDIR = ${PYTHON_SCRIPTDIR}"
498 die "python_export: unknown variable ${var}"
503 # @FUNCTION: python_get_sitedir
506 # Obtain and print the 'site-packages' path for the given
507 # implementation. If no implementation is provided, ${EPYTHON} will
510 # If you just need to have PYTHON_SITEDIR set (and exported), then it is
511 # better to use python_export() directly instead.
512 python_get_sitedir() {
513 debug-print-function ${FUNCNAME} "${@}"
515 python_export "${@}" PYTHON_SITEDIR
516 echo "${PYTHON_SITEDIR}"
519 # @FUNCTION: python_get_includedir
522 # Obtain and print the include path for the given implementation. If no
523 # implementation is provided, ${EPYTHON} will be used.
525 # If you just need to have PYTHON_INCLUDEDIR set (and exported), then it
526 # is better to use python_export() directly instead.
527 python_get_includedir() {
528 debug-print-function ${FUNCNAME} "${@}"
530 python_export "${@}" PYTHON_INCLUDEDIR
531 echo "${PYTHON_INCLUDEDIR}"
534 # @FUNCTION: python_get_library_path
537 # Obtain and print the Python library path for the given implementation.
538 # If no implementation is provided, ${EPYTHON} will be used.
540 # Please note that this function can be used with CPython only. Use
541 # in another implementation will result in a fatal failure.
542 python_get_library_path() {
543 debug-print-function ${FUNCNAME} "${@}"
545 python_export "${@}" PYTHON_LIBPATH
546 echo "${PYTHON_LIBPATH}"
549 # @FUNCTION: python_get_CFLAGS
552 # Obtain and print the compiler flags for building against Python,
553 # for the given implementation. If no implementation is provided,
554 # ${EPYTHON} will be used.
556 # Please note that this function can be used with CPython only.
557 # It requires Python and pkg-config installed, and therefore proper
558 # build-time dependencies need be added to the ebuild.
559 python_get_CFLAGS() {
560 debug-print-function ${FUNCNAME} "${@}"
562 python_export "${@}" PYTHON_CFLAGS
563 echo "${PYTHON_CFLAGS}"
566 # @FUNCTION: python_get_LIBS
569 # Obtain and print the compiler flags for linking against Python,
570 # for the given implementation. If no implementation is provided,
571 # ${EPYTHON} will be used.
573 # Please note that this function can be used with CPython only.
574 # It requires Python and pkg-config installed, and therefore proper
575 # build-time dependencies need be added to the ebuild.
577 debug-print-function ${FUNCNAME} "${@}"
579 python_export "${@}" PYTHON_LIBS
580 echo "${PYTHON_LIBS}"
583 # @FUNCTION: python_get_PYTHON_CONFIG
586 # Obtain and print the PYTHON_CONFIG location for the given
587 # implementation. If no implementation is provided, ${EPYTHON} will be
590 # Please note that this function can be used with CPython only.
591 # It requires Python installed, and therefore proper build-time
592 # dependencies need be added to the ebuild.
593 python_get_PYTHON_CONFIG() {
594 debug-print-function ${FUNCNAME} "${@}"
596 python_export "${@}" PYTHON_CONFIG
597 echo "${PYTHON_CONFIG}"
600 # @FUNCTION: python_get_scriptdir
603 # Obtain and print the script install path for the given
604 # implementation. If no implementation is provided, ${EPYTHON} will
606 python_get_scriptdir() {
607 debug-print-function ${FUNCNAME} "${@}"
609 python_export "${@}" PYTHON_SCRIPTDIR
610 echo "${PYTHON_SCRIPTDIR}"
613 # @FUNCTION: _python_ln_rel
614 # @USAGE: <from> <to>
617 # Create a relative symlink.
619 debug-print-function ${FUNCNAME} "${@}"
624 local tgpath=${target%/*}/
625 local sympath=${symname%/*}/
628 while [[ ${sympath} ]]; do
631 while [[ ! ${tgseg} && ${tgpath} ]]; do
633 tgpath=${tgpath#${tgseg}/}
636 while [[ ! ${symseg} && ${sympath} ]]; do
637 symseg=${sympath%%/*}
638 sympath=${sympath#${symseg}/}
641 if [[ ${tgseg} != ${symseg} ]]; then
642 rel_target=../${rel_target}${tgseg:+${tgseg}/}
645 rel_target+=${tgpath}${target##*/}
647 debug-print "${FUNCNAME}: ${symname} -> ${target}"
648 debug-print "${FUNCNAME}: rel_target = ${rel_target}"
650 ln -fs "${rel_target}" "${symname}"
653 # @FUNCTION: python_optimize
654 # @USAGE: [<directory>...]
656 # Compile and optimize Python modules in specified directories (absolute
657 # paths). If no directories are provided, the default system paths
658 # are used (prepended with ${D}).
660 debug-print-function ${FUNCNAME} "${@}"
662 if [[ ${EBUILD_PHASE} == pre* || ${EBUILD_PHASE} == post* ]]; then
663 eerror "The new Python eclasses expect the compiled Python files to"
664 eerror "be controlled by the Package Manager. For this reason,"
665 eerror "the python_optimize function can be used only during src_* phases"
666 eerror "(src_install most commonly) and not during pkg_* phases."
668 die "python_optimize is not to be used in pre/post* phases"
671 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
673 local PYTHON=${PYTHON}
674 [[ ${PYTHON} ]] || python_export PYTHON
676 # default to sys.path
677 if [[ ${#} -eq 0 ]]; then
679 while IFS= read -r -d '' f; do
680 # 1) accept only absolute paths
681 # (i.e. skip '', '.' or anything like that)
682 # 2) skip paths which do not exist
683 # (python2.6 complains about them verbosely)
685 if [[ ${f} == /* && -d ${D%/}${f} ]]; then
686 set -- "${D%/}${f}" "${@}"
688 done < <("${PYTHON}" -c 'import sys; print("".join(x + "\0" for x in sys.path))' || die)
690 debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
695 # make sure to get a nice path without //
696 local instpath=${d#${D%/}}
697 instpath=/${instpath##/}
700 python2.7|python3.[34])
701 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
702 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
705 # both levels of optimization are separate since 3.5
706 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
707 "${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
708 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
711 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
717 # @FUNCTION: python_scriptinto
720 # Set the directory to which files passed to python_doexe(),
721 # python_doscript(), python_newexe() and python_newscript()
722 # are going to be installed. The new value needs to be relative
723 # to the installation root (${ED}).
725 # If not set explicitly, the directory defaults to /usr/bin.
730 # python_scriptinto /usr/sbin
731 # python_foreach_impl python_doscript foo
734 python_scriptinto() {
735 debug-print-function ${FUNCNAME} "${@}"
737 python_scriptroot=${1}
740 # @FUNCTION: python_doexe
743 # Install the given executables into the executable install directory,
744 # for the current Python implementation (${EPYTHON}).
746 # The executable will be wrapped properly for the Python implementation,
747 # though no shebang mangling will be performed.
749 debug-print-function ${FUNCNAME} "${@}"
753 python_newexe "${f}" "${f##*/}"
757 # @FUNCTION: python_newexe
758 # @USAGE: <path> <new-name>
760 # Install the given executable into the executable install directory,
761 # for the current Python implementation (${EPYTHON}).
763 # The executable will be wrapped properly for the Python implementation,
764 # though no shebang mangling will be performed. It will be renamed
767 debug-print-function ${FUNCNAME} "${@}"
769 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
770 [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
772 local wrapd=${python_scriptroot:-/usr/bin}
777 local PYTHON_SCRIPTDIR d
778 python_export PYTHON_SCRIPTDIR
779 d=${PYTHON_SCRIPTDIR#${EPREFIX}}
785 newexe "${f}" "${newfn}" || return ${?}
788 # install the wrapper
789 _python_ln_rel "${ED%/}"/usr/lib/python-exec/python-exec2 \
790 "${ED%/}/${wrapd}/${newfn}" || die
792 # don't use this at home, just call python_doscript() instead
793 if [[ ${_PYTHON_REWRITE_SHEBANG} ]]; then
794 python_fix_shebang -q "${ED%/}/${d}/${newfn}"
798 # @FUNCTION: python_doscript
801 # Install the given scripts into the executable install directory,
802 # for the current Python implementation (${EPYTHON}).
804 # All specified files must start with a 'python' shebang. The shebang
805 # will be converted, and the files will be wrapped properly
806 # for the Python implementation.
811 # python_foreach_impl python_doscript ${PN}
815 debug-print-function ${FUNCNAME} "${@}"
817 local _PYTHON_REWRITE_SHEBANG=1
821 # @FUNCTION: python_newscript
822 # @USAGE: <path> <new-name>
824 # Install the given script into the executable install directory
825 # for the current Python implementation (${EPYTHON}), and name it
828 # The file must start with a 'python' shebang. The shebang will be
829 # converted, and the file will be wrapped properly for the Python
830 # implementation. It will be renamed to <new-name>.
835 # python_foreach_impl python_newscript foo.py foo
839 debug-print-function ${FUNCNAME} "${@}"
841 local _PYTHON_REWRITE_SHEBANG=1
845 # @FUNCTION: python_moduleinto
848 # Set the Python module install directory for python_domodule().
849 # The <new-path> can either be an absolute target system path (in which
850 # case it needs to start with a slash, and ${ED} will be prepended to
851 # it) or relative to the implementation's site-packages directory
852 # (then it must not start with a slash). The relative path can be
853 # specified either using the Python package notation (separated by dots)
854 # or the directory notation (using slashes).
856 # When not set explicitly, the modules are installed to the top
857 # site-packages directory.
859 # In the relative case, the exact path is determined directly
860 # by each python_doscript/python_newscript function. Therefore,
861 # python_moduleinto can be safely called before establishing the Python
862 # interpreter and/or a single call can be used to set the path correctly
863 # for multiple implementations, as can be seen in the following example.
868 # python_moduleinto bar
869 # # installs ${PYTHON_SITEDIR}/bar/baz.py
870 # python_foreach_impl python_domodule baz.py
873 python_moduleinto() {
874 debug-print-function ${FUNCNAME} "${@}"
876 python_moduleroot=${1}
879 # @FUNCTION: python_domodule
882 # Install the given modules (or packages) into the current Python module
883 # installation directory. The list can mention both modules (files)
884 # and packages (directories). All listed files will be installed
885 # for all enabled implementations, and compiled afterwards.
890 # # (${PN} being a directory)
891 # python_foreach_impl python_domodule ${PN}
895 debug-print-function ${FUNCNAME} "${@}"
897 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
900 if [[ ${python_moduleroot} == /* ]]; then
902 d=${python_moduleroot}
904 # relative to site-packages
905 local PYTHON_SITEDIR=${PYTHON_SITEDIR}
906 [[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
908 d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot//.//}
914 doins -r "${@}" || return ${?}
917 python_optimize "${ED%/}/${d}"
920 # @FUNCTION: python_doheader
923 # Install the given headers into the implementation-specific include
924 # directory. This function is unconditionally recursive, i.e. you can
925 # pass directories instead of files.
930 # python_foreach_impl python_doheader foo.h bar.h
934 debug-print-function ${FUNCNAME} "${@}"
936 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
938 local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
939 [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
941 d=${PYTHON_INCLUDEDIR#${EPREFIX}}
946 doins -r "${@}" || return ${?}
950 # @FUNCTION: python_wrapper_setup
951 # @USAGE: [<path> [<impl>]]
953 # Create proper 'python' executable and pkg-config wrappers
954 # (if available) in the directory named by <path>. Set up PATH
955 # and PKG_CONFIG_PATH appropriately. <path> defaults to ${T}/${EPYTHON}.
957 # The wrappers will be created for implementation named by <impl>,
958 # or for one named by ${EPYTHON} if no <impl> passed.
960 # If the named directory contains a python symlink already, it will
961 # be assumed to contain proper wrappers already and only environment
962 # setup will be done. If wrapper update is requested, the directory
963 # shall be removed first.
964 python_wrapper_setup() {
965 debug-print-function ${FUNCNAME} "${@}"
967 local workdir=${1:-${T}/${EPYTHON}}
968 local impl=${2:-${EPYTHON}}
970 [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
971 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON specified."
973 if [[ ! -x ${workdir}/bin/python ]]; then
974 _python_check_dead_variables
976 mkdir -p "${workdir}"/{bin,pkgconfig} || die
978 # Clean up, in case we were supposed to do a cheap update.
979 rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
980 rm -f "${workdir}"/bin/2to3 || die
981 rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
984 python_export "${impl}" EPYTHON PYTHON
987 if python_is_python3; then
996 # note: we don't use symlinks because python likes to do some
997 # symlink reading magic that breaks stuff
998 # https://bugs.gentoo.org/show_bug.cgi?id=555752
999 cat > "${workdir}/bin/python" <<-_EOF_ || die
1001 exec "${PYTHON}" "\${@}"
1003 cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1004 chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1006 local nonsupp=( "python${pyother}" "python${pyother}-config" )
1009 if [[ ${EPYTHON} == python* ]]; then
1010 cat > "${workdir}/bin/python-config" <<-_EOF_ || die
1012 exec "${PYTHON}-config" "\${@}"
1014 cp "${workdir}/bin/python-config" \
1015 "${workdir}/bin/python${pyver}-config" || die
1016 chmod +x "${workdir}/bin/python-config" \
1017 "${workdir}/bin/python${pyver}-config" || die
1020 ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
1023 ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}.pc \
1024 "${workdir}"/pkgconfig/python.pc || die
1025 ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die
1027 nonsupp+=( 2to3 python-config "python${pyver}-config" )
1031 for x in "${nonsupp[@]}"; do
1032 cat >"${workdir}"/bin/${x} <<-_EOF_ || die
1034 echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
1037 chmod +x "${workdir}"/bin/${x} || die
1041 # Now, set the environment.
1042 # But note that ${workdir} may be shared with something else,
1043 # and thus already on top of PATH.
1044 if [[ ${PATH##:*} != ${workdir}/bin ]]; then
1045 PATH=${workdir}/bin${PATH:+:${PATH}}
1047 if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
1048 PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
1050 export PATH PKG_CONFIG_PATH
1053 # @FUNCTION: python_is_python3
1056 # Check whether <impl> (or ${EPYTHON}) is a Python3k variant
1057 # (i.e. uses syntax and stdlib of Python 3.*).
1059 # Returns 0 (true) if it is, 1 (false) otherwise.
1060 python_is_python3() {
1061 local impl=${1:-${EPYTHON}}
1062 [[ ${impl} ]] || die "python_is_python3: no impl nor EPYTHON"
1064 [[ ${impl} == python3* || ${impl} == pypy3 ]]
1067 # @FUNCTION: python_is_installed
1070 # Check whether the interpreter for <impl> (or ${EPYTHON}) is installed.
1071 # Uses has_version with a proper dependency string.
1073 # Returns 0 (true) if it is, 1 (false) otherwise.
1074 python_is_installed() {
1075 local impl=${1:-${EPYTHON}}
1076 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
1081 hasv_args+=( --host-root )
1091 if [[ ${PYTHON_REQ_USE} ]]; then
1092 append=[${PYTHON_REQ_USE}]
1095 # be happy with just the interpeter, no need for the virtual
1096 has_version "${hasv_args[@]}" "dev-python/${impl}${append}" \
1097 || has_version "${hasv_args[@]}" "dev-python/${impl}-bin${append}"
1100 local PYTHON_PKG_DEP
1101 python_export "${impl}" PYTHON_PKG_DEP
1102 has_version "${hasv_args[@]}" "${PYTHON_PKG_DEP}"
1107 # @FUNCTION: python_fix_shebang
1108 # @USAGE: [-f|--force] [-q|--quiet] <path>...
1110 # Replace the shebang in Python scripts with the current Python
1111 # implementation (EPYTHON). If a directory is passed, works recursively
1112 # on all Python scripts.
1114 # Only files having a 'python*' shebang will be modified. Files with
1115 # other shebang will either be skipped when working recursively
1116 # on a directory or treated as error when specified explicitly.
1118 # Shebangs matching explicitly current Python version will be left
1119 # unmodified. Shebangs requesting another Python version will be treated
1120 # as fatal error, unless --force is given.
1122 # --force causes the function to replace even shebangs that require
1123 # incompatible Python version. --quiet causes the function not to list
1124 # modified files verbosely.
1125 python_fix_shebang() {
1126 debug-print-function ${FUNCNAME} "${@}"
1128 [[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)"
1131 while [[ ${@} ]]; do
1133 -f|--force) force=1; shift;;
1134 -q|--quiet) quiet=1; shift;;
1140 [[ ${1} ]] || die "${FUNCNAME}: no paths given"
1144 local any_correct any_fixed is_recursive
1146 [[ -d ${path} ]] && is_recursive=1
1148 while IFS= read -r -d '' f; do
1152 # note: we can't ||die here since read will fail if file
1153 # has no newline characters
1154 IFS= read -r shebang <"${f}"
1156 # First, check if it's shebang at all...
1157 if [[ ${shebang} == '#!'* ]]; then
1158 local split_shebang=()
1159 read -r -a split_shebang <<<${shebang} || die
1161 # Match left-to-right in a loop, to avoid matching random
1162 # repetitions like 'python2.7 python2'.
1163 for i in "${split_shebang[@]}"; do
1166 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1167 debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
1169 # Nothing to do, move along.
1174 *python|*python[23])
1175 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1176 debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"
1178 if [[ ${i} == *python2 ]]; then
1180 if [[ ! ${force} ]]; then
1181 python_is_python3 "${EPYTHON}" && error=1
1183 elif [[ ${i} == *python3 ]]; then
1185 if [[ ! ${force} ]]; then
1186 python_is_python3 "${EPYTHON}" || error=1
1193 *python[23].[0123456789]|*pypy|*pypy3|*jython[23].[0123456789])
1194 # Explicit mismatch.
1195 if [[ ! ${force} ]]; then
1199 *python[23].[0123456789])
1200 from="python[23].[0123456789]";;
1205 *jython[23].[0123456789])
1206 from="jython[23].[0123456789]";;
1208 die "${FUNCNAME}: internal error in 2nd pattern match";;
1217 if [[ ! ${error} && ! ${from} ]]; then
1218 # Non-Python shebang. Allowed in recursive mode,
1219 # disallowed when specifying file explicitly.
1220 [[ ${is_recursive} ]] && continue
1224 if [[ ! ${quiet} ]]; then
1225 einfo "Fixing shebang in ${f#${D%/}}."
1228 if [[ ! ${error} ]]; then
1229 # We either want to match ${from} followed by space
1230 # or at end-of-string.
1231 if [[ ${shebang} == *${from}" "* ]]; then
1232 sed -i -e "1s:${from} :${EPYTHON} :" "${f}" || die
1234 sed -i -e "1s:${from}$:${EPYTHON}:" "${f}" || die
1238 eerror "The file has incompatible shebang:"
1239 eerror " file: ${f#${D%/}}"
1240 eerror " current shebang: ${shebang}"
1241 eerror " requested impl: ${EPYTHON}"
1242 die "${FUNCNAME}: conversion of incompatible shebang requested"
1244 done < <(find -H "${path}" -type f -print0 || die)
1246 if [[ ! ${any_fixed} ]]; then
1248 [[ ${EAPI} == 5 ]] && cmd=eqawarn
1250 "${cmd}" "QA warning: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files."
1251 if [[ ${any_correct} ]]; then
1252 "${cmd}" "All files have ${EPYTHON} shebang already."
1254 "${cmd}" "There are no Python files in specified directory."
1257 [[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})"
1262 # @FUNCTION: _python_check_locale_sanity
1264 # @RETURN: 0 if sane, 1 otherwise
1266 # Check whether the specified locale sanely maps between lowercase
1267 # and uppercase ASCII characters.
1268 _python_check_locale_sanity() {
1269 local -x LC_ALL=${1}
1274 local input="${lc[*]}${uc[*]}"
1276 local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}")
1277 [[ ${output} == "${uc[*]}${lc[*]}" ]]
1280 # @FUNCTION: python_export_utf8_locale
1281 # @RETURN: 0 on success, 1 on failure.
1283 # Attempts to export a usable UTF-8 locale in the LC_CTYPE variable. Does
1284 # nothing if LC_ALL is defined, or if the current locale uses a UTF-8 charmap.
1285 # This may be used to work around the quirky open() behavior of python3.
1286 python_export_utf8_locale() {
1287 debug-print-function ${FUNCNAME} "${@}"
1289 # If the locale program isn't available, just return.
1290 type locale >/dev/null || return 0
1292 if [[ $(locale charmap) != UTF-8 ]]; then
1293 # Try English first, then everything else.
1294 local lang locales="C.UTF-8 en_US.UTF-8 en_GB.UTF-8 $(locale -a)"
1296 for lang in ${locales}; do
1297 if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
1298 if _python_check_locale_sanity "${lang}"; then
1299 export LC_CTYPE=${lang}
1300 if [[ -n ${LC_ALL} ]]; then
1301 export LC_NUMERIC=${LC_ALL}
1302 export LC_TIME=${LC_ALL}
1303 export LC_COLLATE=${LC_ALL}
1304 export LC_MONETARY=${LC_ALL}
1305 export LC_MESSAGES=${LC_ALL}
1306 export LC_PAPER=${LC_ALL}
1307 export LC_NAME=${LC_ALL}
1308 export LC_ADDRESS=${LC_ALL}
1309 export LC_TELEPHONE=${LC_ALL}
1310 export LC_MEASUREMENT=${LC_ALL}
1311 export LC_IDENTIFICATION=${LC_ALL}
1319 ewarn "Could not find a UTF-8 locale. This may trigger build failures in"
1320 ewarn "some python packages. Please ensure that a UTF-8 locale is listed in"
1321 ewarn "/etc/locale.gen and run locale-gen."
1328 # @FUNCTION: build_sphinx
1329 # @USAGE: <directory>
1331 # Build HTML documentation using dev-python/sphinx in the specified
1332 # <directory>. Takes care of disabling Intersphinx and appending
1335 # If <directory> is relative to the current directory, care needs
1336 # to be taken to run einstalldocs from the same directory
1339 debug-print-function ${FUNCNAME} "${@}"
1340 [[ ${#} -eq 1 ]] || die "${FUNCNAME} takes 1 arg: <directory>"
1344 sed -i -e 's:^intersphinx_mapping:disabled_&:' \
1345 "${dir}"/conf.py || die
1346 # not all packages include the Makefile in pypi tarball
1347 sphinx-build -b html -d "${dir}"/_build/doctrees "${dir}" \
1348 "${dir}"/_build/html || die
1350 HTML_DOCS+=( "${dir}/_build/html/." )
1353 # -- python.eclass functions --
1355 _python_check_dead_variables() {
1358 for v in PYTHON_DEPEND PYTHON_USE_WITH{,_OR,_OPT} {RESTRICT,SUPPORT}_PYTHON_ABIS
1360 if [[ ${!v} ]]; then
1361 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Ebuild_head"
1365 for v in PYTHON_{CPPFLAGS,CFLAGS,CXXFLAGS,LDFLAGS}
1367 if [[ ${!v} ]]; then
1368 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#PYTHON_CFLAGS"
1372 for v in PYTHON_TESTS_RESTRICTED_ABIS PYTHON_EXPORT_PHASE_FUNCTIONS \
1373 PYTHON_VERSIONED_{SCRIPTS,EXECUTABLES} PYTHON_NONVERSIONED_EXECUTABLES
1375 if [[ ${!v} ]]; then
1376 die "${v} is invalid for python-r1 suite"
1380 for v in DISTUTILS_USE_SEPARATE_SOURCE_DIRECTORIES DISTUTILS_SETUP_FILES \
1381 DISTUTILS_GLOBAL_OPTIONS DISTUTILS_SRC_TEST PYTHON_MODNAME
1383 if [[ ${!v} ]]; then
1384 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#${v}"
1388 if [[ ${DISTUTILS_DISABLE_TEST_DEPENDENCY} ]]; then
1389 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#DISTUTILS_SRC_TEST"
1392 # python.eclass::progress
1393 for v in PYTHON_BDEPEND PYTHON_MULTIPLE_ABIS PYTHON_ABI_TYPE \
1394 PYTHON_RESTRICTED_ABIS PYTHON_TESTS_FAILURES_TOLERANT_ABIS \
1395 PYTHON_CFFI_MODULES_GENERATION_COMMANDS
1397 if [[ ${!v} ]]; then
1398 die "${v} is invalid for python-r1 suite"
1403 python_pkg_setup() {
1404 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1407 python_convert_shebangs() {
1408 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_convert_shebangs"
1411 python_clean_py-compile_files() {
1412 die "${FUNCNAME}() is invalid for python-r1 suite"
1415 python_clean_installation_image() {
1416 die "${FUNCNAME}() is invalid for python-r1 suite"
1419 python_execute_function() {
1420 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#python_execute_function"
1423 python_generate_wrapper_scripts() {
1424 die "${FUNCNAME}() is invalid for python-r1 suite"
1427 python_merge_intermediate_installation_images() {
1428 die "${FUNCNAME}() is invalid for python-r1 suite"
1431 python_set_active_version() {
1432 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1435 python_need_rebuild() {
1436 die "${FUNCNAME}() is invalid for python-r1 suite"
1440 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#.24.28PYTHON.29.2C_.24.7BEPYTHON.7D"
1443 python_get_implementation() {
1444 die "${FUNCNAME}() is invalid for python-r1 suite"
1447 python_get_implementational_package() {
1448 die "${FUNCNAME}() is invalid for python-r1 suite"
1451 python_get_libdir() {
1452 die "${FUNCNAME}() is invalid for python-r1 suite"
1455 python_get_library() {
1456 die "${FUNCNAME}() is invalid for python-r1 suite"
1459 python_get_version() {
1460 die "${FUNCNAME}() is invalid for python-r1 suite"
1463 python_get_implementation_and_version() {
1464 die "${FUNCNAME}() is invalid for python-r1 suite"
1467 python_execute_nosetests() {
1468 die "${FUNCNAME}() is invalid for python-r1 suite"
1471 python_execute_py.test() {
1472 die "${FUNCNAME}() is invalid for python-r1 suite"
1475 python_execute_trial() {
1476 die "${FUNCNAME}() is invalid for python-r1 suite"
1479 python_enable_pyc() {
1480 die "${FUNCNAME}() is invalid for python-r1 suite"
1483 python_disable_pyc() {
1484 die "${FUNCNAME}() is invalid for python-r1 suite"
1487 python_mod_optimize() {
1488 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
1491 python_mod_cleanup() {
1492 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Python_byte-code_compilation"
1495 # python.eclass::progress
1497 python_abi_depend() {
1498 die "${FUNCNAME}() is invalid for python-r1 suite"
1501 python_install_executables() {
1502 die "${FUNCNAME}() is invalid for python-r1 suite"
1505 python_get_extension_module_suffix() {
1506 die "${FUNCNAME}() is invalid for python-r1 suite"
1509 python_byte-compile_modules() {
1510 die "${FUNCNAME}() is invalid for python-r1 suite"
1513 python_clean_byte-compiled_modules() {
1514 die "${FUNCNAME}() is invalid for python-r1 suite"
1517 python_generate_cffi_modules() {
1518 die "${FUNCNAME}() is invalid for python-r1 suite"