Project:Python/python-single-r1

From Gentoo Wiki
Jump to: navigation, search

python-single-r1 is the python-r1 suite eclass intended for ebuilds that install files that may be used only with one of the Python interpreters installed on the system. This often includes simple Python scripts that have no need for supporting multiple interpreters and programs that embed Python.

Since building packages with a single Python interpreter is pretty straightforward and supported correctly by most build systems, this eclass is much simpler than python-r1.

Description

python-single-r1 eclass is suited to provide user with a choice of one Python implementation he wishes to build his package with. It exports a simple pkg_setup implementation that obtains that choice and performs a complete build environment setup for it.

The eclass sets USE flags for the ebuild. You need to set RDEPEND and DEPEND, and REQUIRED_USE variables properly. For simple dependencies on other packages, PYTHON_USEDEP provides the necessary USE dependency string. For more complex dependencies, there is a number of metadata writing helpers.

This kind of setup is enough for most build systems to be able to find and use the implementation of choice properly. If the installed Python scripts lack proper shebang, python_fix_shebang can be used to fix them.

Examples

Simple package

This is the most trivial use case for python-single-r1 — a simple package that unconditionally installs some Python bits. The code is compatible with both Python 2 and 3.4 through 3.6, and has a few plain dependencies. The packages dev-python/foo and dev-python/bar provide Python modules used by the installed code — they are needed at build time only if the modules are actually used, i.e. if tests are being run. The package dev-python/frobnicate provides a script that is called directly at build time. The phase functions are not covered here.

CODE Simple ebuild code for using python-single-r1
PYTHON_COMPAT=( python2_7 python3_{4,5,6} )

inherit python-single-r1

IUSE="test"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"

RDEPEND="${PYTHON_DEPS}
    dev-python/bar[${PYTHON_USEDEP}]
    dev-python/foo[${PYTHON_USEDEP}]"
DEPEND="${PYTHON_DEPS}
    dev-python/frobnicate
    test? ( ${RDEPEND} )"

# pkg_setup exported by eclass, call it if you need to redefine
# pkg_setup() {
#   python-single-r1_pkg_setup
# }

Package with conditional Python bits

This is a little extension of the example above, presuming that the Python bits are conditional to the python USE flag.

CODE python-single-r1 ebuild with conditional use of Python
PYTHON_COMPAT=( python2_7 python3_{4,5,6} )

inherit python-single-r1

IUSE="python test"
REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"

RDEPEND="python? (
        ${PYTHON_DEPS}
        dev-python/bar[${PYTHON_USEDEP}]
        dev-python/foo[${PYTHON_USEDEP}]
    )"
DEPEND="python? (
        ${PYTHON_DEPS}
        dev-python/frobnicate
        test? ( ${RDEPEND} )
    )"

pkg_setup() {
    use python && python-single-r1_pkg_setup
}

Package with optional parts supporting subset of PYTHON_COMPAT

In this example, our package has a little optional component, frobnicator that supports the subset of all implementations supported by the package. The package code itself is Python 3-ready but frobnicator depends on a Python 2-only package, and so if it is enabled, we want to build the package for Python 2.

CODE python-single-r1 ebuild with subset-dep for frobnicator
PYTHON_COMPAT=( python2_7 python3_{4,5,6} )

inherit python-single-r1

IUSE="frobnicator"
REQUIRED_USE="${PYTHON_REQUIRED_USE}
    frobnicator? ( $(python_gen_useflags -2) )"

RDEPEND="
    ${PYTHON_DEPS}
    dev-python/bar[${PYTHON_USEDEP}]
    dev-python/foo[${PYTHON_USEDEP}]
    frobnicator? ( dev-python/frobnicate[$(python_gen_usedep -2)] )"
DEPEND="${PYTHON_DEPS}"

#pkg_setup() {
#    python-single-r1_pkg_setup
#}

API reference

Variables set by ebuilds

PYTHON_COMPAT

Obligatory. Must be set above the inherit line.

A list of all Python implementations supported by ebuild. The possible values are listed in the implementations article.

CODE Example PYTHON_COMPAT
PYTHON_COMPAT=( python{2_7,3_4,3_5} pypy )

PYTHON_REQ_USE

Optional, defaults to none. Must be set above the inherit line.

USE-dependency that will be applied to all Python interpreters pulled in as dependencies. Takes the form of EAPI 4 USE dependency string, must apply cleanly to all supported Python implementations. See Project:Python/Implementation USE flags for reference.

CODE Example for PYTHON_REQ_USE
PYTHON_REQ_USE="ssl(+)?,xml(+)"
Note
Please do not confuse PYTHON_REQ_USE with PYTHON_REQUIRED_USE:

The PYTHON_REQ_USE variable is used to set the required USE flags on the python dependency atoms. For instance, the above example would specify some equivalent to "dev-lang/python[ssl(+)?,xml(+)]" in *DEPEND.

The PYTHON_REQUIRED_USE variable is (as described below) read-only, and is assigned to the ebuild's REQUIRED_USE in order to ensure the version flags specified via PYTHON_COMPAT, PYTHON_TARGETS, etc. are kept in sync.

Variables exported by eclass

Obligatory: It is the ebuild author's responsibility to set DEPEND, RDEPEND, and REQUIRED_USE; the eclass does not set them.

PYTHON_DEPS

Contains the dependency string on Python interpreters and auxiliary tools (dev-lang/python-exec).

It must be used within RDEPEND and/or DEPEND. If the Python dependency is conditional to a USE flag, the reference should be placed in appropriate USE-conditional block.

CODE Example use of PYTHON_DEPS
RDEPEND="python? ( ${PYTHON_DEPS} )"
DEPEND="${RDEPEND}"

PYTHON_REQUIRED_USE

Contains the REQUIRED_USE constraint requiring at least one Python implementation to be selected.

It must be used within REQUIRED_USE. If the Python dependency is conditional to a USE flag, the reference should be placed in appropriate USE-conditional block.

CODE Example use of PYTHON_REQUIRED_USE
REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"

PYTHON_USEDEP

Contains a USE dependency string that must be used to enforce matching Python implementations on package dependencies.

It can be used on package dependencies which are using the python-r1 and python-single-r1 eclasses.

CODE Example use of PYTHON_USEDEP
RDEPEND="dev-python/jinja[${PYTHON_USEDEP}]"
DEPEND="${RDEPEND}
    dev-python/setuptools[${PYTHON_USEDEP}]"

Metadata needing to be set by ebuilds

RDEPEND, DEPEND

Obligatory. Must be set (somewhere after the inherit line, unless distutils-r1 is used).

RDEPEND and DEPEND need to be defined by the ebuild to provide dependencies on proper Python implementations and packages.

The eclass provides PYTHON_DEPS convenience variable with a proper dependency on Python interpreters. If the Python support in package is unconditional, PYTHON_DEPS needs to be placed directly in RDEPEND and/or DEPEND. If the Python support is conditional to a USE flag, the PYTHON_DEPS reference needs to be placed inside matching USE conditional.

Additionally, the eclass provides PYTHON_USEDEP to provide proper USE dependencies on packages providing Python modules.

CODE *DEPEND example with USE conditional
RDEPEND="
    python? (
        ${PYTHON_DEPS}
        dev-python/foo[${PYTHON_USEDEP}]
    )"
DEPEND=${RDEPEND}
CODE *DEPEND example for unconditional use of Python
RDEPEND="${PYTHON_DEPS}
    dev-python/foo[${PYTHON_USEDEP}]"
DEPEND=${RDEPEND}


REQUIRED_USE

Obligatory. Must be set (somewhere after the inherit line, unless distutils-r1 is used).

REQUIRED_USE needs to be defined by the ebuild so that at least one of the supported Python implementations is enabled at installation time, pulling in the proper Python dependencies.

The eclass provides PYTHON_REQUIRED_USE convenience variable with a proper REQUIRED_USE value. If the Python support in package is unconditional during build- or run-time, PYTHON_REQUIRED_USE needs to be placed directly in REQUIRED_USE. If the Python support is always conditional to a USE flag, the PYTHON_REQUIRED_USE reference needs to be placed inside matching USE conditional.

CODE REQUIRED_USE example with USE conditional
REQUIRED_USE="|| ( alsa pulseaudio ) python? ( ${PYTHON_REQUIRED_USE} )"
CODE REQUIRED_USE example for unconditional use of Python
REQUIRED_USE="|| ( alsa pulseaudio ) ${PYTHON_REQUIRED_USE}"
Note
Failure to add REQUIRED_USE definitions will result in user inconvenience and bug reports.

Metadata writing helpers

Implementation patterns

All of the following functions accept patterns to match implementations. If multiple patterns are passed, at least one of them needs to match the implementation for it to be used. The patterns can be either:

  1. fnmatch-style patterns (matched via bash == operator) matching PYTHON_COMPAT values, e.g. python2*, pypy*;
  2. literal -2 to match all implementations compatible with Python 2 (where python_is_python3 is false),
  3. literal -3 to match all implementations compatible with Python 3 (where python_is_python3 is true).

Please remember that wildcard characters such as *, ? and [...] groups need to be quoted or escaped, or otherwise bash will attempt to perform filename expansion in place. This could cause horrible results depending on the current working directory during ebuild processing.

python_gen_usedep

Usage: python_gen_usedep <pattern>...

Outputs USE dependency string that requires the implementations matching pattern(s) to match. Can be used to output USE-dependencies on dependencies that are available or needed only in some of the supported implementations.

Often, python_gen_usedep needs to be used with proper REQUIRED_USE in order to require any of the implementations to be enabled.

CODE Example use of python_gen_usedep
# epydoc supports only python2*
DEPEND="doc? ( dev-python/epydoc[$(python_gen_usedep 'python2*')] )"
REQUIRED_USE="doc? ( || ( $(python_gen_useflags 'python2*') ) )"

python_gen_useflags

Usage: python_gen_useflags <pattern>...

Outputs space separated list of flags for implementations matching pattern(s). Can be used to create REQUIRED_USE values, usually in conjunction with python_gen_usedep.

python_gen_cond_dep

Usage: python_gen_cond_dep <dependency-string> <pattern>...

Outputs provided dependency strings enclosed in USE-conditional block, making them conditional to one of the implementations matching patterns being enabled.

${PYTHON_USEDEP} may be used inside the dependency string. It will be expanded appropriately.

CODE Example use of python_gen_cond_dep
# based on virtual/python-futures
RDEPEND="$(python_gen_cond_dep 'dev-python/futures[${PYTHON_USEDEP}]' 'python2*')

python_gen_impl_dep

Usage: python_gen_impl_dep [<req-use-flags> [<pattern>...]]

Outputs a dependency on Python implementations with the USE dependency string from <req-use-flags>, or no USE dependency string if it is empty or not passed. If any <pattern>s are provided, the dependency will be generated only for matching implementations. Otherwise, all implementations will be used.

This function is intended to be used when more than one form of dependency string is needed. In this case, PYTHON_REQ_USE and PYTHON_DEPS should be used for the common form, and python_gen_impl_dep to generate additional variants.

CODE Example use of python_gen_impl_dep
# USE=foo requires XML support in Python
RDEPEND="foo? ( $(python_gen_impl_dep 'xml(+)') )
    ${PYTHON_DEPS}"

Eclass functions

python_setup

Usage: python_setup

Obtain the user-selected Python interpreter and set up the build environment for it. EPYTHON, PYTHON and BUILD_DIR are exported, and Python executable & pkg-config wrappers will be set up.

This function dies if no Python interpreter flag was enabled or the flags are invalid. To avoid the delayed failure, please make sure to use PYTHON_REQUIRED_USE.

python-single-r1_pkg_setup

Usage: python-single-r1_pkg_setup

The standard exported pkg_setup phase. It calls python_setup.

If Python support in the package is conditional to a USE flag, a custom pkg_setup must be used with python-single-r1_pkg_setup being invoked conditionally to the flag.

CODE Example use of conditional python-single-r1_pkg_setup
pkg_setup() {
    use python && python-single-r1_pkg_setup
}
CODE Reference implementation of python-single-r1_pkg_setup
python-single-r1_pkg_setup() {
    [[ ${MERGE_TYPE} != binary ]] && python_setup
}