The Python eclasses are eclasses maintained by the Gentoo Python team and aimed at helping writing ebuilds that install Python scripts, modules or simply require or use Python.
The Python ecosystem includes 5 core eclasses formed in three layers. Those are, bottom-most first:
- python-utils-r1 providing common utility functions for all other eclasses,
- python-any-r1, python-single-r1 and python-r1 providing the basic framework for creating Python packages,
- and distutils-r1 providing convenient interface to distutils, setuptools and compatible build systems.
Each higher-level eclass exposes the API of the eclasses below it, and it is customary not to inherit them directly. All eclasses expose the common utility API defined by python-utils-r1. The distutils-r1 eclass can use and expose either python-r1 or python-single-r1, depending on the value of DISTUTILS_SINGLE_IMPL configuration variable.
|Pure build-time||1-impl install||n-impl install|
|distutils, setuptools & compatible||—||distutils-r1|
|other build systems||python-any-r1||python-single-r1||python-r1|
Aside to the core eclasses, there might be one or more minor eclasses. At the moment, they include:
- twisted-r1 for packages from the Twisted suite.
Choosing the correct eclass
In order to easily choose the correct eclass, you can use the following algorithm. You should stop at the first eclass that matches.
- Does your package use distutils, setuptools or a compatible build system (setup.py)? If it does, use distutils-r1.
- Does your package need Python at build time only (and not install any scripts or modules)? If it does, use python-any-r1.
- Does the benefit of allowing user to select more than one implementation outweigh the implementation cost? If it does, use python-r1.
- Otherwise, use python-single-r1.
The most of the confusion occurs between choosing multi-impl eclass (python-r1) and single-impl (python-single-r1). The difference from the user perspective is that the latter requires the user to choose one of the Python implementations supported by the package, while the former allows selecting multiple targets. Technically this implies the necessity of facilitating for multiple install stages in the ebuild.
As emphasized in the aforementioned algorithm, it is frequently a matter of implementation cost. For distutils-r1 ebuilds, multi-impl install is usually used since it has near zero cost. For other ebuilds, python-r1 is recommended only if it is really necessary (e.g. to satisfy reverse dependencies) or beneficial to the user. Otherwise, python-single-r1 is much simpler.
Note that in order to support multi-impl install, the package needs to ensure that a separate copy of each file can be installed for each supported implementation. This includes Python modules (usually installed in site-packages directory), scripts (usually wrapped by python-exec) but also libraries linking to libpython. The last category frequently requires incompatible patching of packages — e.g. dev-libs/boost is adding custom suffixes to the boost_python library.
The API exposed by the middle-layer eclasses is explained in the terms of API packs. Each pack represents a particular programming model and a consistent set of functions made available to the ebuild environment. Note that the implementations of the same functions differe between the eclasses, and in some cases there could be slight API differences.
The following packs are defined:
- Common API — basic simple interfaces exposed by all eclasses:
- PYTHON_COMPAT, PYTHON_REQ_USE declarations,
- PYTHON_DEPS variable,
- Any-of dep API — to construct any-of (||) dependencies and process their results:
- python_check_deps() function support in python_setup.
- USE flag API — to select implementations using USE flags and expose dependencies based on them:
- IUSE values,
- PYTHON_USEDEP, PYTHON_REQUIRED_USE variables,
- python_gen_usedep, python_gen_useflags, python_gen_cond_dep, python_gen_impl_dep>
- Multibuild API — to facilitate building package for multiple implementations of Python.
- python_foreach_impl, python_copy_sources, python_replicate_script.
The support for different API packs in the three eclasses is summarized in the following table.
|Any-of dep API||Yes||No||Yes|
|USE flag API||No||Yes||Yes|