distutils-r1.eclass
Description
A simple eclass providing functions to build Python packages using
the distutils build system. It exports phase functions for all
the src_* phases
. Each of the phases runs two pseudo-phases:
python_..._all()
(e.g. python_prepare_all()
) once in ${S}
, then
python_...()
(e.g. python_prepare()
) for each implementation
(see: python_foreach_impl()
in python-r1
).
In distutils-r1_src_prepare()
, the 'all' function is run before
per-implementation ones (because it creates the implementations),
per-implementation functions are run in a random order.
In remaining phase functions, the per-implementation functions are run before the 'all' one, and they are ordered from the least to the most preferred implementation (so that 'better' files overwrite 'worse' ones).
If the ebuild doesn't specify a particular pseudo-phase function,
the default one will be used (distutils-r1_...
). Defaults are provided
for all per-implementation pseudo-phases, python_prepare_all()
and python_install_all()
; whenever writing your own pseudo-phase
functions, you should consider calling the defaults (and especially
distutils-r1_python_prepare_all
).
Please note that distutils-r1
sets RDEPEND
and BDEPEND
(or
DEPEND
in earlier EAPIs) unconditionally for you.
Also, please note that distutils-r1
will always inherit python-r1
as well. Thus, all the variables defined and documented there are
relevant to the packages using distutils-r1
.
For more information, please see the Python Guide: https://projects.gentoo.org/python/guide/
Functions
- distutils_enable_sphinx <subdir> [--no-autodoc | <plugin-pkgs>...]
-
Set up
IUSE
,BDEPEND
,python_check_deps()
andpython_compile_all()
for building HTML docs viadev-python/sphinx
.python_compile_all()
will append toHTML_DOCS
if docs are enabled.This helper is meant for the most common case, that is a single Sphinx subdirectory with standard layout, building and installing HTML docs behind
USE=doc
. It assumes it's the only consumer of the three aforementioned functions. If you need to use a custom implemention, you can't use it.If your package uses additional Sphinx plugins, they should be passed (without
PYTHON_USEDEP
) as <plugin-pkgs>. The function will take care of setting appropriate any-of dep andpython_check_deps()
.If no plugin packages are specified, the eclass will still utilize
any-r1
API to supportautodoc
(documenting source code). If the package uses neitherautodoc
nor additional plugins, you should pass--no-autodoc
to disable this API and simplify the resulting code.This function must be called in global scope. Take care not to overwrite the variables set by it. If you need to extend
python_compile_all()
, you can call the original implementation assphinx_compile_all
. - distutils_enable_tests [--install] <test-runner>
-
Set up
IUSE
,RESTRICT
,BDEPEND
andpython_test()
for running tests with the specified test runner. Also copies the current value ofRDEPEND
totest?-BDEPEND
. The test-runner argument must be one of:-
nose: nosetests (
dev-python/nose
) -
pytest:
dev-python/pytest
-
setup.py:
setup.py
test (no deps included) -
unittest: for built-in Python unittest module
Additionally, if
--install
is passed as the first parameter,distutils_install_for_testing --via-root`
is called before running the test suite.This function is meant as a helper for common use cases, and it only takes care of basic setup. You still need to list additional test dependencies manually. If you have uncommon use case, you should not use it and instead enable tests manually.
This function must be called in global scope, after
RDEPEND
has been declared. Take care not to overwrite the variables set by it. -
- esetup.py [<args>...]
-
Run
setup.py
using currently selected Python interpreter (if${EPYTHON}
is set; fallbackpython
otherwise).setup.py
will be passed the following, in order:-
${DISTUTILS_ARGS[@]}
-
${mydistutilsargs[@]}
(deprecated) -
additional arguments passed to the
esetup.py
function.
Please note that
setup.py
will respect defaults (unless overridden via command-line options) fromsetup.cfg
that is created indistutils-r1_python_compile
and indistutils-r1_python_install
.This command dies on failure.
-
- distutils_install_for_testing [--via-root|--via-home|--via-venv] [<args>...]
-
Install the package into a temporary location for running tests. Update
PYTHONPATH
appropriately and setTEST_DIR
to the test installation root. The Python packages will be installed inlib
subdir, and scripts inscripts
subdir (like inBUILD_DIR
).Please note that this function should be only used if package uses namespaces (and therefore proper install needs to be done to enforce
PYTHONPATH
) or tests rely on the results of install command. For most of the packages, tests built inBUILD_DIR
are good enough.The function supports three install modes. These are:
--via-root
(the default) that usessetup.py install --root=...
combined withPYTHONPATH
and is recommended for the majority of packages.--via-venv
that creates a (non-isolated) venv and installs the package into it viasetup.py install
. This mode does not usePYTHONPATH
but requires python to be called viaPATH
. It may solve a few corner cases that--via-root
do not support.--via-home
that usessetup.py install --home=...
. This is a historical mode that was mostly broken by setuptools 50.3.0+. If your package does not work with the other two modes but works with this one, please report a bug.Please note that in order to test the solution properly you need to unmerge the package first.
This function is not available in PEP517 mode. The eclass provides a venv-style install unconditionally therefore, and therefore it should no longer be necessary.
- distutils_write_namespace <namespace>...
-
Write the
__init__.py
file for the requested namespace into PEP517 install tree, in order to fix running tests when legacy namespace packages are installed (dev-python/namespace-*
).This function must only be used in
python_test()
. The created file will automatically be removed upon leaving the test phase. - distutils-r1_python_prepare_all
-
The default
python_prepare_all()
. It applies the patches fromPATCHES
array, then user patches and finally callspython_copy_sources
to create copies of resulting sources for each Python implementation.At some point in the future, it may also apply eclass-specific distutils patches and/or quirks.
- distutils_wheel_install <root> <wheel>
-
Install the specified wheel into <root>.
This function is intended for expert use only.
- distutils_pep517_install <root>
-
Build the wheel for the package in the current directory using PEP 517 backend and install it into <root>.
This function is intended for expert use only. It does not handle wrapping executables.
- distutils-r1_python_compile [additional-args...]
-
The default
python_compile()
.If
DISTUTILS_USE_PEP517
is set tono
, a no-op.If
DISTUTILS_USE_PEP517
is set to any other value, builds a wheel using the PEP517 backend and installs it into${BUILD_DIR}/install
. May additionally callbuild_ext
prior to that when usingsetuptools
and the eclass detects a potential benefit from parallel extension builds.In legacy mode, runs
esetup.py build
. Any parameters passed to this function will be appended tosetup.py
invocation, i.e. passed as options to thebuild
command. - distutils-r1_python_test [additional-args...]
-
The
python_test()
implementation used bydistutils_enable_tests
. Runs tests using the specified test runner, possibly installing them first.This function is used only if
distutils_enable_tests
is called. - distutils-r1_python_install [additional-args...]
-
The default
python_install()
.In PEP517 mode, merges the files from
${BUILD_DIR}/install
(if present) to the image directory.In the legacy mode, calls
esetup.py install
to install the package. Any parameters passed to this function will be appended to thesetup.py
invocation (i.e. as options to theinstall
command). - distutils-r1_python_install_all
-
The default
python_install_all()
. It installs the documentation.
Variables
- DISTUTILS_OPTIONAL
-
If set to a non-null value, distutils part in the ebuild will be considered optional. No dependencies will be added and no phase functions will be exported.
If you enable
DISTUTILS_OPTIONAL
, you have to set proper dependencies for your package (using${PYTHON_DEPS}
) and to either calldistutils-r1
default phase functions or call the build system manually. - DISTUTILS_SINGLE_IMPL
-
If set to a non-null value, the ebuild will support setting a single Python implementation only. It will effectively replace the
python-r1
eclass inherit withpython-single-r1
.Note that inheriting
python-single-r1
will causepkg_setup()
to be exported. It must be run in order for the eclass functions to function properly. - DISTUTILS_USE_PEP517 (SET BEFORE INHERIT)
-
Enable the PEP 517 mode for the specified build system. In this mode, the complete build and install is done in
python_compile()
, a venv-style install tree is provided topython_test()
, andpython_install()
just merges the temporary install tree into the real fs.This mode is recommended for Python packages. However, some packages using custom hacks on top of distutils/setuptools may not install correctly in this mode. Please verify the list of installed files when using it.
The variable specifies the build system used. Currently, the following values are supported:
-
flit - flit_core backend
-
flit_scm - flit_scm backend
-
hatchling - hatchling backend (from hatch)
-
jupyter - jupyter_packaging backend
-
maturin - maturin backend
-
meson-python - meson-python (mesonpy) backend
-
no - no PEP517 build system (see below)
-
pbr - pbr backend
-
pdm - pdm.pep517 backend
-
poetry - poetry-core backend
-
setuptools - distutils or setuptools (incl. legacy mode)
-
sip - sipbuild backend
-
standalone - standalone build systems without external deps (used for bootstrapping).
The variable needs to be set before the inherit line. The eclass adds appropriate build-time dependencies and verifies the value.
The special value
no
indicates that the package has no build system. This is not equivalent to unsetDISTUTILS_USE_PEP517
(legacy mode). It causes the eclass not to include any build system dependencies and to disable defaultpython_compile()
andpython_install()
implementations. Baseline Python deps and phase functions will still be set (depending on the value ofDISTUTILS_OPTIONAL
). Most of the other eclass functions will work. Testing venv will be provided in${BUILD_DIR}/install
afterpython_compile()
, and if any (other) files are found in${BUILD_DIR}/install
afterpython_install()
, they will be merged into${D}
. -
- DISTUTILS_USE_SETUPTOOLS (SET BEFORE INHERIT)
-
Controls adding
dev-python/setuptools
dependency. The allowed values are:-
no -- do not add the dependency (pure distutils package)
-
bdepend -- add it to
BDEPEND
(the default) -
rdepend -- add it to
BDEPEND+RDEPEND
(e.g. when using pkg_resources) -
pyproject.toml -- use
pyproject2setuptools
to install a project usingpyproject.toml
(flit, poetry...) -
manual -- do not add the dependency and suppress the checks (assumes you will take care of doing it correctly)
This variable is effective only if
DISTUTILS_OPTIONAL
is disabled. It is available only in non-PEP517 mode. It needs to be set before the inherit line. -
- DISTUTILS_DEPS (GENERATED BY ECLASS)
-
This is an eclass-generated build-time dependency string for the build system packages. This string is automatically appended to
BDEPEND
unlessDISTUTILS_OPTIONAL
is used. This variable is available only in PEP 517 mode.Example use:
DISTUTILS_OPTIONAL=1 # ... RDEPEND="${PYTHON_DEPS}" BDEPEND=" ${PYTHON_DEPS} ${DISTUTILS_DEPS}"
- PATCHES
-
An array containing patches to be applied to the sources before copying them.
If unset, no custom patches will be applied.
Please note, however, that at some point the eclass may apply additional distutils patches/quirks independently of this variable.
Example:
PATCHES=( "${FILESDIR}"/${P}-make-gentoo-happy.patch )
- DOCS
-
An array containing documents installed using
dodoc
. The files listed there must exist in the directory from whichdistutils-r1_python_install_all()
is run (${S}
by default).If unset, the function will instead look up files matching default filename pattern list (from the Package Manager Specification), and install those found.
Example:
DOCS=( NEWS README )
- HTML_DOCS
-
An array containing documents installed using
dohtml
. The files and directories listed there must exist in the directory from whichdistutils-r1_python_install_all()
is run (${S}
by default).If unset, no HTML docs will be installed.
Example:
HTML_DOCS=( doc/html/. )
- DISTUTILS_IN_SOURCE_BUILD
-
If set to a non-null value, in-source builds will be enabled. If unset, the default is to use in-source builds when
python_prepare()
is declared, and out-of-source builds otherwise.If in-source builds are used, the eclass will create a copy of package sources for each Python implementation in
python_prepare_all()
, and work on that copy afterwards.If out-of-source builds are used, the eclass will instead work on the sources directly, prepending
setup.py
arguments withbuild --build-base ${BUILD_DIR}
to enforce keeping & using built files in the specific root. - DISTUTILS_ALL_SUBPHASE_IMPLS
-
An array of patterns specifying which implementations can be used for
*_all()
sub-phase functions. If undefined, defaults to*
(allowing any implementation). If multiple values are specified, implementations matching any of the patterns will be accepted.For the pattern syntax, please see
_python_impl_matches
inpython-utils-r1.eclass
.If the restriction needs to apply conditionally to a USE flag, the variable should be set conditionally as well (e.g. in an early phase function or other convenient location).
Please remember to add a matching
||
block toREQUIRED_USE
, to ensure that at least one implementation matching the patterns will be enabled.Example:
REQUIRED_USE="doc? ( || ( $(python_gen_useflags 'python2*') ) )" pkg_setup() { use doc && DISTUTILS_ALL_SUBPHASE_IMPLS=( 'python2*' ) }
- DISTUTILS_ARGS
-
An array containing options to be passed to the build system. Supported by a subset of build systems used by the eclass.
For setuptools, the arguments will be passed as first parameters to
setup.py
invocations (viaesetup.py
), as well as to the PEP517 backend. For future compatibility, only global options should be used and specifying commands should be avoided.For sip, the options are passed to the PEP517 backend in a form resembling sip-build calls. Options taking arguments need to be specified in the
--key=value
form, while flag options as--key
. If an option takes multiple arguments, it can be specified multiple times, same as for sip-build.Example:
python_configure_all() { DISTUTILS_ARGS=( --enable-my-hidden-option ) }
Authors
Author: Michał Górny <mgorny@gentoo.org>
Based on the work of: Krzysztof Pawlik <nelchael@gentoo.org>
Maintainers
Python team <python@gentoo.org>
Reporting Bugs
Please report bugs via https://bugs.gentoo.org/