1 # Copyright 1999-2018 Gentoo Foundation
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: 0 1 2 3 4 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
26 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
30 if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
31 die 'python-r1 suite eclasses can not be used with python.eclass.'
34 if [[ ! ${_PYTHON_UTILS_R1} ]]; then
36 [[ ${EAPI:-0} == [012345] ]] && inherit eutils multilib
37 inherit toolchain-funcs
39 # @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
42 # All supported Python implementations, most preferred last.
47 python3_4 python3_5 python3_6 python3_7
49 readonly _PYTHON_ALL_IMPLS
51 # @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
54 # Set to a non-empty value in order to make eclass tolerate (ignore)
55 # unknown implementations in PYTHON_COMPAT.
57 # This is intended to be set by the user when using ebuilds that may
58 # have unknown (newer) implementations in PYTHON_COMPAT. The assumption
59 # is that the ebuilds are intended to be used within multiple contexts
60 # which can involve revisions of this eclass that support a different
61 # set of Python implementations.
63 # @FUNCTION: _python_impl_supported
67 # Check whether the implementation <impl> (PYTHON_COMPAT-form)
70 # Returns 0 if the implementation is valid and supported. If it is
71 # unsupported, returns 1 -- and the caller should ignore the entry.
72 # If it is invalid, dies with an appopriate error messages.
73 _python_impl_supported() {
74 debug-print-function ${FUNCNAME} "${@}"
76 [[ ${#} -eq 1 ]] || die "${FUNCNAME}: takes exactly 1 argument (impl)."
80 # keep in sync with _PYTHON_ALL_IMPLS!
81 # (not using that list because inline patterns shall be faster)
83 python2_7|python3_[4567]|jython2_7)
86 pypy1_[89]|pypy2_0|python2_[56]|python3_[123])
90 if [[ ${EAPI:-0} == [01234] ]]; then
91 die "PyPy is supported in EAPI 5 and newer only."
95 [[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
96 die "Invalid implementation in PYTHON_COMPAT: ${impl}"
100 # @FUNCTION: _python_set_impls
103 # Check PYTHON_COMPAT for well-formedness and validity, then set
104 # two global variables:
106 # - _PYTHON_SUPPORTED_IMPLS containing valid implementations supported
107 # by the ebuild (PYTHON_COMPAT - dead implementations),
109 # - and _PYTHON_UNSUPPORTED_IMPLS containing valid implementations that
110 # are not supported by the ebuild.
112 # Implementations in both variables are ordered using the pre-defined
113 # eclass implementation ordering.
115 # This function must be called once in global scope by an eclass
116 # utilizing PYTHON_COMPAT.
117 _python_set_impls() {
120 if ! declare -p PYTHON_COMPAT &>/dev/null; then
121 die 'PYTHON_COMPAT not declared.'
123 if [[ $(declare -p PYTHON_COMPAT) != "declare -a"* ]]; then
124 die 'PYTHON_COMPAT must be an array.'
126 for i in "${PYTHON_COMPAT[@]}"; do
127 # trigger validity checks
128 _python_impl_supported "${i}"
131 local supp=() unsupp=()
133 for i in "${_PYTHON_ALL_IMPLS[@]}"; do
134 if has "${i}" "${PYTHON_COMPAT[@]}"; then
141 if [[ ! ${supp[@]} ]]; then
142 die "No supported implementation in PYTHON_COMPAT."
145 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
146 # set once already, verify integrity
147 if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
148 eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
149 eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
150 eerror "Now : ${supp[*]}"
151 die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
153 if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
154 eerror "Unsupported impls changed between inherits!"
155 eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
156 eerror "Now : ${unsupp[*]}"
157 die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
160 _PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
161 _PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
162 readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
166 # @FUNCTION: _python_impl_matches
167 # @USAGE: <impl> <pattern>...
170 # Check whether the specified <impl> matches at least one
171 # of the patterns following it. Return 0 if it does, 1 otherwise.
173 # <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
175 # a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
176 # b) '-2' to indicate all Python 2 variants (= !python_is_python3)
177 # c) '-3' to indicate all Python 3 variants (= python_is_python3)
178 _python_impl_matches() {
179 [[ ${#} -ge 2 ]] || die "${FUNCNAME}: takes at least 2 parameters"
181 local impl=${1} pattern
185 if [[ ${pattern} == -2 ]]; then
186 ! python_is_python3 "${impl}"
188 elif [[ ${pattern} == -3 ]]; then
189 python_is_python3 "${impl}"
191 # unify value style to allow lax matching
192 elif [[ ${impl/./_} == ${pattern/./_} ]]; then
200 # @ECLASS-VARIABLE: PYTHON
203 # The absolute path to the current Python interpreter.
205 # This variable is set automatically in the following contexts:
207 # python-r1: Set in functions called by python_foreach_impl() or after
208 # calling python_export_best().
210 # python-single-r1: Set after calling python-single-r1_pkg_setup().
212 # distutils-r1: Set within any of the python sub-phase functions.
219 # @ECLASS-VARIABLE: EPYTHON
222 # The executable name of the current Python interpreter.
224 # This variable is set automatically in the following contexts:
226 # python-r1: Set in functions called by python_foreach_impl() or after
227 # calling python_export_best().
229 # python-single-r1: Set after calling python-single-r1_pkg_setup().
231 # distutils-r1: Set within any of the python sub-phase functions.
238 # @ECLASS-VARIABLE: PYTHON_SITEDIR
241 # The path to Python site-packages directory.
243 # Set and exported on request using python_export().
244 # Requires a proper build-time dependency on the Python implementation.
248 # /usr/lib64/python2.7/site-packages
251 # @ECLASS-VARIABLE: PYTHON_INCLUDEDIR
254 # The path to Python include directory.
256 # Set and exported on request using python_export().
257 # Requires a proper build-time dependency on the Python implementation.
261 # /usr/include/python2.7
264 # @ECLASS-VARIABLE: PYTHON_LIBPATH
267 # The path to Python library.
269 # Set and exported on request using python_export().
270 # Valid only for CPython. Requires a proper build-time dependency
271 # on the Python implementation.
275 # /usr/lib64/libpython2.7.so
278 # @ECLASS-VARIABLE: PYTHON_CFLAGS
281 # Proper C compiler flags for building against Python. Obtained from
282 # pkg-config or python-config.
284 # Set and exported on request using python_export().
285 # Valid only for CPython. Requires a proper build-time dependency
286 # on the Python implementation and on pkg-config.
290 # -I/usr/include/python2.7
293 # @ECLASS-VARIABLE: PYTHON_LIBS
296 # Proper C compiler flags for linking against Python. Obtained from
297 # pkg-config or python-config.
299 # Set and exported on request using python_export().
300 # Valid only for CPython. Requires a proper build-time dependency
301 # on the Python implementation and on pkg-config.
308 # @ECLASS-VARIABLE: PYTHON_CONFIG
311 # Path to the python-config executable.
313 # Set and exported on request using python_export().
314 # Valid only for CPython. Requires a proper build-time dependency
315 # on the Python implementation and on pkg-config.
319 # /usr/bin/python2.7-config
322 # @ECLASS-VARIABLE: PYTHON_PKG_DEP
325 # The complete dependency on a particular Python package as a string.
327 # Set and exported on request using python_export().
331 # dev-lang/python:2.7[xml]
334 # @ECLASS-VARIABLE: PYTHON_SCRIPTDIR
337 # The location where Python scripts must be installed for current impl.
339 # Set and exported on request using python_export().
343 # /usr/lib/python-exec/python2.7
346 # @FUNCTION: python_export
347 # @USAGE: [<impl>] <variables>...
349 # Set and export the Python implementation-relevant variables passed
352 # The optional first parameter may specify the requested Python
353 # implementation (either as PYTHON_TARGETS value, e.g. python2_7,
354 # or an EPYTHON one, e.g. python2.7). If no implementation passed,
355 # the current one will be obtained from ${EPYTHON}.
357 # The variables which can be exported are: PYTHON, EPYTHON,
358 # PYTHON_SITEDIR. They are described more completely in the eclass
359 # variable documentation.
361 debug-print-function ${FUNCNAME} "${@}"
376 if [[ -z ${impl} ]]; then
377 die "python_export called without a python implementation and EPYTHON is unset"
381 debug-print "${FUNCNAME}: implementation: ${impl}"
386 export EPYTHON=${impl}
387 debug-print "${FUNCNAME}: EPYTHON = ${EPYTHON}"
390 export PYTHON=${EPREFIX}/usr/bin/${impl}
391 debug-print "${FUNCNAME}: PYTHON = ${PYTHON}"
394 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
395 # sysconfig can't be used because:
396 # 1) pypy doesn't give site-packages but stdlib
397 # 2) jython gives paths with wrong case
398 PYTHON_SITEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())') || die
399 export PYTHON_SITEDIR
400 debug-print "${FUNCNAME}: PYTHON_SITEDIR = ${PYTHON_SITEDIR}"
403 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
404 PYTHON_INCLUDEDIR=$("${PYTHON}" -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_inc())') || die
405 export PYTHON_INCLUDEDIR
406 debug-print "${FUNCNAME}: PYTHON_INCLUDEDIR = ${PYTHON_INCLUDEDIR}"
408 # Jython gives a non-existing directory
409 if [[ ! -d ${PYTHON_INCLUDEDIR} ]]; then
410 die "${impl} does not install any header files!"
414 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
415 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
416 export PYTHON_LIBPATH
417 debug-print "${FUNCNAME}: PYTHON_LIBPATH = ${PYTHON_LIBPATH}"
419 if [[ ! ${PYTHON_LIBPATH} ]]; then
420 die "${impl} lacks a (usable) dynamic library"
428 # python-2.7, python-3.2, etc.
429 val=$($(tc-getPKG_CONFIG) --cflags ${impl/n/n-}) || die
432 die "${impl}: obtaining ${var} not supported"
436 export PYTHON_CFLAGS=${val}
437 debug-print "${FUNCNAME}: PYTHON_CFLAGS = ${PYTHON_CFLAGS}"
444 # python-2.7, python-3.2, etc.
445 val=$($(tc-getPKG_CONFIG) --libs ${impl/n/n-}) || die
448 die "${impl}: obtaining ${var} not supported"
452 export PYTHON_LIBS=${val}
453 debug-print "${FUNCNAME}: PYTHON_LIBS = ${PYTHON_LIBS}"
460 [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it"
461 flags=$("${PYTHON}" -c 'import sysconfig; print(sysconfig.get_config_var("ABIFLAGS") or "")') || die
462 val=${PYTHON}${flags}-config
465 die "${impl}: obtaining ${var} not supported"
469 export PYTHON_CONFIG=${val}
470 debug-print "${FUNCNAME}: PYTHON_CONFIG = ${PYTHON_CONFIG}"
476 PYTHON_PKG_DEP='>=dev-lang/python-2.7.5-r2:2.7';;
478 PYTHON_PKG_DEP='>=dev-lang/python-3.3.2-r2:3.3';;
480 PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
482 PYTHON_PKG_DEP='>=virtual/pypy-5:0=';;
484 PYTHON_PKG_DEP='>=virtual/pypy3-5:0=';;
486 PYTHON_PKG_DEP='dev-java/jython:2.7';;
488 die "Invalid implementation: ${impl}"
492 if [[ ${PYTHON_REQ_USE} ]]; then
493 PYTHON_PKG_DEP+=[${PYTHON_REQ_USE}]
496 export PYTHON_PKG_DEP
497 debug-print "${FUNCNAME}: PYTHON_PKG_DEP = ${PYTHON_PKG_DEP}"
501 export PYTHON_SCRIPTDIR=${EPREFIX}/usr/lib/python-exec/${impl}
502 debug-print "${FUNCNAME}: PYTHON_SCRIPTDIR = ${PYTHON_SCRIPTDIR}"
505 die "python_export: unknown variable ${var}"
510 # @FUNCTION: python_get_sitedir
513 # Obtain and print the 'site-packages' path for the given
514 # implementation. If no implementation is provided, ${EPYTHON} will
517 # If you just need to have PYTHON_SITEDIR set (and exported), then it is
518 # better to use python_export() directly instead.
519 python_get_sitedir() {
520 debug-print-function ${FUNCNAME} "${@}"
522 python_export "${@}" PYTHON_SITEDIR
523 echo "${PYTHON_SITEDIR}"
526 # @FUNCTION: python_get_includedir
529 # Obtain and print the include path for the given implementation. If no
530 # implementation is provided, ${EPYTHON} will be used.
532 # If you just need to have PYTHON_INCLUDEDIR set (and exported), then it
533 # is better to use python_export() directly instead.
534 python_get_includedir() {
535 debug-print-function ${FUNCNAME} "${@}"
537 python_export "${@}" PYTHON_INCLUDEDIR
538 echo "${PYTHON_INCLUDEDIR}"
541 # @FUNCTION: python_get_library_path
544 # Obtain and print the Python library path for the given implementation.
545 # If no implementation is provided, ${EPYTHON} will be used.
547 # Please note that this function can be used with CPython only. Use
548 # in another implementation will result in a fatal failure.
549 python_get_library_path() {
550 debug-print-function ${FUNCNAME} "${@}"
552 python_export "${@}" PYTHON_LIBPATH
553 echo "${PYTHON_LIBPATH}"
556 # @FUNCTION: python_get_CFLAGS
559 # Obtain and print the compiler flags for building against Python,
560 # for the given implementation. If no implementation is provided,
561 # ${EPYTHON} will be used.
563 # Please note that this function can be used with CPython only.
564 # It requires Python and pkg-config installed, and therefore proper
565 # build-time dependencies need be added to the ebuild.
566 python_get_CFLAGS() {
567 debug-print-function ${FUNCNAME} "${@}"
569 python_export "${@}" PYTHON_CFLAGS
570 echo "${PYTHON_CFLAGS}"
573 # @FUNCTION: python_get_LIBS
576 # Obtain and print the compiler flags for linking against Python,
577 # for the given implementation. If no implementation is provided,
578 # ${EPYTHON} will be used.
580 # Please note that this function can be used with CPython only.
581 # It requires Python and pkg-config installed, and therefore proper
582 # build-time dependencies need be added to the ebuild.
584 debug-print-function ${FUNCNAME} "${@}"
586 python_export "${@}" PYTHON_LIBS
587 echo "${PYTHON_LIBS}"
590 # @FUNCTION: python_get_PYTHON_CONFIG
593 # Obtain and print the PYTHON_CONFIG location for the given
594 # implementation. If no implementation is provided, ${EPYTHON} will be
597 # Please note that this function can be used with CPython only.
598 # It requires Python installed, and therefore proper build-time
599 # dependencies need be added to the ebuild.
600 python_get_PYTHON_CONFIG() {
601 debug-print-function ${FUNCNAME} "${@}"
603 python_export "${@}" PYTHON_CONFIG
604 echo "${PYTHON_CONFIG}"
607 # @FUNCTION: python_get_scriptdir
610 # Obtain and print the script install path for the given
611 # implementation. If no implementation is provided, ${EPYTHON} will
613 python_get_scriptdir() {
614 debug-print-function ${FUNCNAME} "${@}"
616 python_export "${@}" PYTHON_SCRIPTDIR
617 echo "${PYTHON_SCRIPTDIR}"
620 # @FUNCTION: _python_ln_rel
621 # @USAGE: <from> <to>
624 # Create a relative symlink.
626 debug-print-function ${FUNCNAME} "${@}"
631 local tgpath=${target%/*}/
632 local sympath=${symname%/*}/
635 while [[ ${sympath} ]]; do
638 while [[ ! ${tgseg} && ${tgpath} ]]; do
640 tgpath=${tgpath#${tgseg}/}
643 while [[ ! ${symseg} && ${sympath} ]]; do
644 symseg=${sympath%%/*}
645 sympath=${sympath#${symseg}/}
648 if [[ ${tgseg} != ${symseg} ]]; then
649 rel_target=../${rel_target}${tgseg:+${tgseg}/}
652 rel_target+=${tgpath}${target##*/}
654 debug-print "${FUNCNAME}: ${symname} -> ${target}"
655 debug-print "${FUNCNAME}: rel_target = ${rel_target}"
657 ln -fs "${rel_target}" "${symname}"
660 # @FUNCTION: python_optimize
661 # @USAGE: [<directory>...]
663 # Compile and optimize Python modules in specified directories (absolute
664 # paths). If no directories are provided, the default system paths
665 # are used (prepended with ${D}).
667 debug-print-function ${FUNCNAME} "${@}"
669 if [[ ${EBUILD_PHASE} == pre* || ${EBUILD_PHASE} == post* ]]; then
670 eerror "The new Python eclasses expect the compiled Python files to"
671 eerror "be controlled by the Package Manager. For this reason,"
672 eerror "the python_optimize function can be used only during src_* phases"
673 eerror "(src_install most commonly) and not during pkg_* phases."
675 die "python_optimize is not to be used in pre/post* phases"
678 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
680 local PYTHON=${PYTHON}
681 [[ ${PYTHON} ]] || python_export PYTHON
683 # default to sys.path
684 if [[ ${#} -eq 0 ]]; then
686 while IFS= read -r -d '' f; do
687 # 1) accept only absolute paths
688 # (i.e. skip '', '.' or anything like that)
689 # 2) skip paths which do not exist
690 # (python2.6 complains about them verbosely)
692 if [[ ${f} == /* && -d ${D%/}${f} ]]; then
693 set -- "${D%/}${f}" "${@}"
695 done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))' || die)
697 debug-print "${FUNCNAME}: using sys.path: ${*/%/;}"
702 # make sure to get a nice path without //
703 local instpath=${d#${D%/}}
704 instpath=/${instpath##/}
707 python2.7|python3.[34])
708 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
709 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
712 # both levels of optimization are separate since 3.5
713 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
714 "${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
715 "${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
718 "${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
724 # @FUNCTION: python_scriptinto
727 # Set the directory to which files passed to python_doexe(),
728 # python_doscript(), python_newexe() and python_newscript()
729 # are going to be installed. The new value needs to be relative
730 # to the installation root (${ED}).
732 # If not set explicitly, the directory defaults to /usr/bin.
737 # python_scriptinto /usr/sbin
738 # python_foreach_impl python_doscript foo
741 python_scriptinto() {
742 debug-print-function ${FUNCNAME} "${@}"
744 python_scriptroot=${1}
747 # @FUNCTION: python_doexe
750 # Install the given executables into the executable install directory,
751 # for the current Python implementation (${EPYTHON}).
753 # The executable will be wrapped properly for the Python implementation,
754 # though no shebang mangling will be performed.
756 debug-print-function ${FUNCNAME} "${@}"
760 python_newexe "${f}" "${f##*/}"
764 # @FUNCTION: python_newexe
765 # @USAGE: <path> <new-name>
767 # Install the given executable into the executable install directory,
768 # for the current Python implementation (${EPYTHON}).
770 # The executable will be wrapped properly for the Python implementation,
771 # though no shebang mangling will be performed. It will be renamed
774 debug-print-function ${FUNCNAME} "${@}"
776 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
777 [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <path> <new-name>"
778 if [[ ${EAPI:-0} == [0123] ]]; then
779 die "python_do* and python_new* helpers are banned in EAPIs older than 4."
782 local wrapd=${python_scriptroot:-/usr/bin}
787 local PYTHON_SCRIPTDIR d
788 python_export PYTHON_SCRIPTDIR
789 d=${PYTHON_SCRIPTDIR#${EPREFIX}}
795 newexe "${f}" "${newfn}" || return ${?}
798 # install the wrapper
799 _python_ln_rel "${ED%/}"/usr/lib/python-exec/python-exec2 \
800 "${ED%/}/${wrapd}/${newfn}" || die
802 # don't use this at home, just call python_doscript() instead
803 if [[ ${_PYTHON_REWRITE_SHEBANG} ]]; then
804 python_fix_shebang -q "${ED%/}/${d}/${newfn}"
808 # @FUNCTION: python_doscript
811 # Install the given scripts into the executable install directory,
812 # for the current Python implementation (${EPYTHON}).
814 # All specified files must start with a 'python' shebang. The shebang
815 # will be converted, and the files will be wrapped properly
816 # for the Python implementation.
821 # python_foreach_impl python_doscript ${PN}
825 debug-print-function ${FUNCNAME} "${@}"
827 local _PYTHON_REWRITE_SHEBANG=1
831 # @FUNCTION: python_newscript
832 # @USAGE: <path> <new-name>
834 # Install the given script into the executable install directory
835 # for the current Python implementation (${EPYTHON}), and name it
838 # The file must start with a 'python' shebang. The shebang will be
839 # converted, and the file will be wrapped properly for the Python
840 # implementation. It will be renamed to <new-name>.
845 # python_foreach_impl python_newscript foo.py foo
849 debug-print-function ${FUNCNAME} "${@}"
851 local _PYTHON_REWRITE_SHEBANG=1
855 # @FUNCTION: python_moduleinto
858 # Set the Python module install directory for python_domodule().
859 # The <new-path> can either be an absolute target system path (in which
860 # case it needs to start with a slash, and ${ED} will be prepended to
861 # it) or relative to the implementation's site-packages directory
862 # (then it must not start with a slash). The relative path can be
863 # specified either using the Python package notation (separated by dots)
864 # or the directory notation (using slashes).
866 # When not set explicitly, the modules are installed to the top
867 # site-packages directory.
869 # In the relative case, the exact path is determined directly
870 # by each python_doscript/python_newscript function. Therefore,
871 # python_moduleinto can be safely called before establishing the Python
872 # interpreter and/or a single call can be used to set the path correctly
873 # for multiple implementations, as can be seen in the following example.
878 # python_moduleinto bar
879 # # installs ${PYTHON_SITEDIR}/bar/baz.py
880 # python_foreach_impl python_domodule baz.py
883 python_moduleinto() {
884 debug-print-function ${FUNCNAME} "${@}"
886 python_moduleroot=${1}
889 # @FUNCTION: python_domodule
892 # Install the given modules (or packages) into the current Python module
893 # installation directory. The list can mention both modules (files)
894 # and packages (directories). All listed files will be installed
895 # for all enabled implementations, and compiled afterwards.
900 # # (${PN} being a directory)
901 # python_foreach_impl python_domodule ${PN}
905 debug-print-function ${FUNCNAME} "${@}"
907 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
908 if [[ ${EAPI:-0} == [0123] ]]; then
909 die "python_do* and python_new* helpers are banned in EAPIs older than 4."
913 if [[ ${python_moduleroot} == /* ]]; then
915 d=${python_moduleroot}
917 # relative to site-packages
918 local PYTHON_SITEDIR=${PYTHON_SITEDIR}
919 [[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
921 d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot//.//}
927 doins -r "${@}" || return ${?}
930 python_optimize "${ED%/}/${d}"
933 # @FUNCTION: python_doheader
936 # Install the given headers into the implementation-specific include
937 # directory. This function is unconditionally recursive, i.e. you can
938 # pass directories instead of files.
943 # python_foreach_impl python_doheader foo.h bar.h
947 debug-print-function ${FUNCNAME} "${@}"
949 [[ ${EPYTHON} ]] || die 'No Python implementation set (EPYTHON is null).'
950 if [[ ${EAPI:-0} == [0123] ]]; then
951 die "python_do* and python_new* helpers are banned in EAPIs older than 4."
954 local d PYTHON_INCLUDEDIR=${PYTHON_INCLUDEDIR}
955 [[ ${PYTHON_INCLUDEDIR} ]] || python_export PYTHON_INCLUDEDIR
957 d=${PYTHON_INCLUDEDIR#${EPREFIX}}
962 doins -r "${@}" || return ${?}
966 # @FUNCTION: python_wrapper_setup
967 # @USAGE: [<path> [<impl>]]
969 # Create proper 'python' executable and pkg-config wrappers
970 # (if available) in the directory named by <path>. Set up PATH
971 # and PKG_CONFIG_PATH appropriately. <path> defaults to ${T}/${EPYTHON}.
973 # The wrappers will be created for implementation named by <impl>,
974 # or for one named by ${EPYTHON} if no <impl> passed.
976 # If the named directory contains a python symlink already, it will
977 # be assumed to contain proper wrappers already and only environment
978 # setup will be done. If wrapper update is requested, the directory
979 # shall be removed first.
980 python_wrapper_setup() {
981 debug-print-function ${FUNCNAME} "${@}"
983 local workdir=${1:-${T}/${EPYTHON}}
984 local impl=${2:-${EPYTHON}}
986 [[ ${workdir} ]] || die "${FUNCNAME}: no workdir specified."
987 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON specified."
989 if [[ ! -x ${workdir}/bin/python ]]; then
990 _python_check_dead_variables
992 mkdir -p "${workdir}"/{bin,pkgconfig} || die
994 # Clean up, in case we were supposed to do a cheap update.
995 rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
996 rm -f "${workdir}"/bin/2to3 || die
997 rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
1000 python_export "${impl}" EPYTHON PYTHON
1003 if python_is_python3; then
1011 # Python interpreter
1012 # note: we don't use symlinks because python likes to do some
1013 # symlink reading magic that breaks stuff
1014 # https://bugs.gentoo.org/show_bug.cgi?id=555752
1015 cat > "${workdir}/bin/python" <<-_EOF_ || die
1017 exec "${PYTHON}" "\${@}"
1019 cp "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1020 chmod +x "${workdir}/bin/python" "${workdir}/bin/python${pyver}" || die
1022 local nonsupp=( "python${pyother}" "python${pyother}-config" )
1025 if [[ ${EPYTHON} == python* ]]; then
1026 cat > "${workdir}/bin/python-config" <<-_EOF_ || die
1028 exec "${PYTHON}-config" "\${@}"
1030 cp "${workdir}/bin/python-config" \
1031 "${workdir}/bin/python${pyver}-config" || die
1032 chmod +x "${workdir}/bin/python-config" \
1033 "${workdir}/bin/python${pyver}-config" || die
1036 ln -s "${PYTHON/python/2to3-}" "${workdir}"/bin/2to3 || die
1039 ln -s "${EPREFIX}"/usr/$(get_libdir)/pkgconfig/${EPYTHON/n/n-}.pc \
1040 "${workdir}"/pkgconfig/python.pc || die
1041 ln -s python.pc "${workdir}"/pkgconfig/python${pyver}.pc || die
1043 nonsupp+=( 2to3 python-config "python${pyver}-config" )
1047 for x in "${nonsupp[@]}"; do
1048 cat >"${workdir}"/bin/${x} <<-_EOF_ || die
1050 echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
1053 chmod +x "${workdir}"/bin/${x} || die
1057 # Now, set the environment.
1058 # But note that ${workdir} may be shared with something else,
1059 # and thus already on top of PATH.
1060 if [[ ${PATH##:*} != ${workdir}/bin ]]; then
1061 PATH=${workdir}/bin${PATH:+:${PATH}}
1063 if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
1064 PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
1066 export PATH PKG_CONFIG_PATH
1069 # @FUNCTION: python_is_python3
1072 # Check whether <impl> (or ${EPYTHON}) is a Python3k variant
1073 # (i.e. uses syntax and stdlib of Python 3.*).
1075 # Returns 0 (true) if it is, 1 (false) otherwise.
1076 python_is_python3() {
1077 local impl=${1:-${EPYTHON}}
1078 [[ ${impl} ]] || die "python_is_python3: no impl nor EPYTHON"
1080 [[ ${impl} == python3* || ${impl} == pypy3 ]]
1083 # @FUNCTION: python_is_installed
1086 # Check whether the interpreter for <impl> (or ${EPYTHON}) is installed.
1087 # Uses has_version with a proper dependency string.
1089 # Returns 0 (true) if it is, 1 (false) otherwise.
1090 python_is_installed() {
1091 local impl=${1:-${EPYTHON}}
1092 [[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
1100 hasv_args+=( --host-root )
1110 if [[ ${PYTHON_REQ_USE} ]]; then
1111 append=[${PYTHON_REQ_USE}]
1114 # be happy with just the interpeter, no need for the virtual
1115 has_version "${hasv_args[@]}" "dev-python/${impl}${append}" \
1116 || has_version "${hasv_args[@]}" "dev-python/${impl}-bin${append}"
1119 local PYTHON_PKG_DEP
1120 python_export "${impl}" PYTHON_PKG_DEP
1121 has_version "${hasv_args[@]}" "${PYTHON_PKG_DEP}"
1126 # @FUNCTION: python_fix_shebang
1127 # @USAGE: [-f|--force] [-q|--quiet] <path>...
1129 # Replace the shebang in Python scripts with the current Python
1130 # implementation (EPYTHON). If a directory is passed, works recursively
1131 # on all Python scripts.
1133 # Only files having a 'python*' shebang will be modified. Files with
1134 # other shebang will either be skipped when working recursively
1135 # on a directory or treated as error when specified explicitly.
1137 # Shebangs matching explicitly current Python version will be left
1138 # unmodified. Shebangs requesting another Python version will be treated
1139 # as fatal error, unless --force is given.
1141 # --force causes the function to replace even shebangs that require
1142 # incompatible Python version. --quiet causes the function not to list
1143 # modified files verbosely.
1144 python_fix_shebang() {
1145 debug-print-function ${FUNCNAME} "${@}"
1147 [[ ${EPYTHON} ]] || die "${FUNCNAME}: EPYTHON unset (pkg_setup not called?)"
1150 while [[ ${@} ]]; do
1152 -f|--force) force=1; shift;;
1153 -q|--quiet) quiet=1; shift;;
1159 [[ ${1} ]] || die "${FUNCNAME}: no paths given"
1163 local any_correct any_fixed is_recursive
1165 [[ -d ${path} ]] && is_recursive=1
1167 while IFS= read -r -d '' f; do
1171 # note: we can't ||die here since read will fail if file
1172 # has no newline characters
1173 IFS= read -r shebang <"${f}"
1175 # First, check if it's shebang at all...
1176 if [[ ${shebang} == '#!'* ]]; then
1177 local split_shebang=()
1178 read -r -a split_shebang <<<${shebang} || die
1180 # Match left-to-right in a loop, to avoid matching random
1181 # repetitions like 'python2.7 python2'.
1182 for i in "${split_shebang[@]}"; do
1185 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1186 debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
1188 # Nothing to do, move along.
1193 *python|*python[23])
1194 debug-print "${FUNCNAME}: in file ${f#${D%/}}"
1195 debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"
1197 if [[ ${i} == *python2 ]]; then
1199 if [[ ! ${force} ]]; then
1200 python_is_python3 "${EPYTHON}" && error=1
1202 elif [[ ${i} == *python3 ]]; then
1204 if [[ ! ${force} ]]; then
1205 python_is_python3 "${EPYTHON}" || error=1
1212 *python[23].[0123456789]|*pypy|*pypy3|*jython[23].[0123456789])
1213 # Explicit mismatch.
1214 if [[ ! ${force} ]]; then
1218 *python[23].[0123456789])
1219 from="python[23].[0123456789]";;
1224 *jython[23].[0123456789])
1225 from="jython[23].[0123456789]";;
1227 die "${FUNCNAME}: internal error in 2nd pattern match";;
1236 if [[ ! ${error} && ! ${from} ]]; then
1237 # Non-Python shebang. Allowed in recursive mode,
1238 # disallowed when specifying file explicitly.
1239 [[ ${is_recursive} ]] && continue
1243 if [[ ! ${quiet} ]]; then
1244 einfo "Fixing shebang in ${f#${D%/}}."
1247 if [[ ! ${error} ]]; then
1248 # We either want to match ${from} followed by space
1249 # or at end-of-string.
1250 if [[ ${shebang} == *${from}" "* ]]; then
1251 sed -i -e "1s:${from} :${EPYTHON} :" "${f}" || die
1253 sed -i -e "1s:${from}$:${EPYTHON}:" "${f}" || die
1257 eerror "The file has incompatible shebang:"
1258 eerror " file: ${f#${D%/}}"
1259 eerror " current shebang: ${shebang}"
1260 eerror " requested impl: ${EPYTHON}"
1261 die "${FUNCNAME}: conversion of incompatible shebang requested"
1263 done < <(find -H "${path}" -type f -print0 || die)
1265 if [[ ! ${any_fixed} ]]; then
1267 [[ ${EAPI:-0} == [012345] ]] && cmd=eqawarn
1269 "${cmd}" "QA warning: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files."
1270 if [[ ${any_correct} ]]; then
1271 "${cmd}" "All files have ${EPYTHON} shebang already."
1273 "${cmd}" "There are no Python files in specified directory."
1276 [[ ${cmd} == eerror ]] && die "${FUNCNAME} did not match any fixable files (QA warning fatal in EAPI ${EAPI})"
1281 # @FUNCTION: _python_check_locale_sanity
1283 # @RETURN: 0 if sane, 1 otherwise
1285 # Check whether the specified locale sanely maps between lowercase
1286 # and uppercase ASCII characters.
1287 _python_check_locale_sanity() {
1288 local -x LC_ALL=${1}
1293 local input="${lc[*]}${uc[*]}"
1295 local output=$(tr '[:lower:][:upper:]' '[:upper:][:lower:]' <<<"${input}")
1296 [[ ${output} == "${uc[*]}${lc[*]}" ]]
1299 # @FUNCTION: python_export_utf8_locale
1300 # @RETURN: 0 on success, 1 on failure.
1302 # Attempts to export a usable UTF-8 locale in the LC_CTYPE variable. Does
1303 # nothing if LC_ALL is defined, or if the current locale uses a UTF-8 charmap.
1304 # This may be used to work around the quirky open() behavior of python3.
1305 python_export_utf8_locale() {
1306 debug-print-function ${FUNCNAME} "${@}"
1308 # If the locale program isn't available, just return.
1309 type locale >/dev/null || return 0
1311 if [[ $(locale charmap) != UTF-8 ]]; then
1312 # Try English first, then everything else.
1313 local lang locales="C.UTF-8 en_US.UTF-8 en_GB.UTF-8 $(locale -a)"
1315 for lang in ${locales}; do
1316 if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
1317 if _python_check_locale_sanity "${lang}"; then
1318 export LC_CTYPE=${lang}
1319 if [[ -n ${LC_ALL} ]]; then
1320 export LC_NUMERIC=${LC_ALL}
1321 export LC_TIME=${LC_ALL}
1322 export LC_COLLATE=${LC_ALL}
1323 export LC_MONETARY=${LC_ALL}
1324 export LC_MESSAGES=${LC_ALL}
1325 export LC_PAPER=${LC_ALL}
1326 export LC_NAME=${LC_ALL}
1327 export LC_ADDRESS=${LC_ALL}
1328 export LC_TELEPHONE=${LC_ALL}
1329 export LC_MEASUREMENT=${LC_ALL}
1330 export LC_IDENTIFICATION=${LC_ALL}
1338 ewarn "Could not find a UTF-8 locale. This may trigger build failures in"
1339 ewarn "some python packages. Please ensure that a UTF-8 locale is listed in"
1340 ewarn "/etc/locale.gen and run locale-gen."
1347 # -- python.eclass functions --
1349 _python_check_dead_variables() {
1352 for v in PYTHON_DEPEND PYTHON_USE_WITH{,_OR,_OPT} {RESTRICT,SUPPORT}_PYTHON_ABIS
1354 if [[ ${!v} ]]; then
1355 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#Ebuild_head"
1359 for v in PYTHON_{CPPFLAGS,CFLAGS,CXXFLAGS,LDFLAGS}
1361 if [[ ${!v} ]]; then
1362 die "${v} is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#PYTHON_CFLAGS"
1366 for v in PYTHON_TESTS_RESTRICTED_ABIS PYTHON_EXPORT_PHASE_FUNCTIONS \
1367 PYTHON_VERSIONED_{SCRIPTS,EXECUTABLES} PYTHON_NONVERSIONED_EXECUTABLES
1369 if [[ ${!v} ]]; then
1370 die "${v} is invalid for python-r1 suite"
1374 for v in DISTUTILS_USE_SEPARATE_SOURCE_DIRECTORIES DISTUTILS_SETUP_FILES \
1375 DISTUTILS_GLOBAL_OPTIONS DISTUTILS_SRC_TEST PYTHON_MODNAME
1377 if [[ ${!v} ]]; then
1378 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#${v}"
1382 if [[ ${DISTUTILS_DISABLE_TEST_DEPENDENCY} ]]; then
1383 die "${v} is invalid for distutils-r1, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#DISTUTILS_SRC_TEST"
1386 # python.eclass::progress
1387 for v in PYTHON_BDEPEND PYTHON_MULTIPLE_ABIS PYTHON_ABI_TYPE \
1388 PYTHON_RESTRICTED_ABIS PYTHON_TESTS_FAILURES_TOLERANT_ABIS \
1389 PYTHON_CFFI_MODULES_GENERATION_COMMANDS
1391 if [[ ${!v} ]]; then
1392 die "${v} is invalid for python-r1 suite"
1397 python_pkg_setup() {
1398 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1401 python_convert_shebangs() {
1402 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"
1405 python_clean_py-compile_files() {
1406 die "${FUNCNAME}() is invalid for python-r1 suite"
1409 python_clean_installation_image() {
1410 die "${FUNCNAME}() is invalid for python-r1 suite"
1413 python_execute_function() {
1414 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"
1417 python_generate_wrapper_scripts() {
1418 die "${FUNCNAME}() is invalid for python-r1 suite"
1421 python_merge_intermediate_installation_images() {
1422 die "${FUNCNAME}() is invalid for python-r1 suite"
1425 python_set_active_version() {
1426 die "${FUNCNAME}() is invalid for python-r1 suite, please take a look @ https://wiki.gentoo.org/wiki/Project:Python/Python.eclass_conversion#pkg_setup"
1429 python_need_rebuild() {
1430 die "${FUNCNAME}() is invalid for python-r1 suite"
1434 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"
1437 python_get_implementation() {
1438 die "${FUNCNAME}() is invalid for python-r1 suite"
1441 python_get_implementational_package() {
1442 die "${FUNCNAME}() is invalid for python-r1 suite"
1445 python_get_libdir() {
1446 die "${FUNCNAME}() is invalid for python-r1 suite"
1449 python_get_library() {
1450 die "${FUNCNAME}() is invalid for python-r1 suite"
1453 python_get_version() {
1454 die "${FUNCNAME}() is invalid for python-r1 suite"
1457 python_get_implementation_and_version() {
1458 die "${FUNCNAME}() is invalid for python-r1 suite"
1461 python_execute_nosetests() {
1462 die "${FUNCNAME}() is invalid for python-r1 suite"
1465 python_execute_py.test() {
1466 die "${FUNCNAME}() is invalid for python-r1 suite"
1469 python_execute_trial() {
1470 die "${FUNCNAME}() is invalid for python-r1 suite"
1473 python_enable_pyc() {
1474 die "${FUNCNAME}() is invalid for python-r1 suite"
1477 python_disable_pyc() {
1478 die "${FUNCNAME}() is invalid for python-r1 suite"
1481 python_mod_optimize() {
1482 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"
1485 python_mod_cleanup() {
1486 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"
1489 # python.eclass::progress
1491 python_abi_depend() {
1492 die "${FUNCNAME}() is invalid for python-r1 suite"
1495 python_install_executables() {
1496 die "${FUNCNAME}() is invalid for python-r1 suite"
1499 python_get_extension_module_suffix() {
1500 die "${FUNCNAME}() is invalid for python-r1 suite"
1503 python_byte-compile_modules() {
1504 die "${FUNCNAME}() is invalid for python-r1 suite"
1507 python_clean_byte-compiled_modules() {
1508 die "${FUNCNAME}() is invalid for python-r1 suite"
1511 python_generate_cffi_modules() {
1512 die "${FUNCNAME}() is invalid for python-r1 suite"