python-utils-r1.eclass: Add EPYTEST_PLUGIN_LOAD_VIA_ENV

Add an `EPYTEST_PLUGIN_LOAD_VIA_ENV` option to explicitly load plugins
via `PYTEST_PLUGINS` environment variable rather than `-p` options.
This is useful for testing pytest plugins.

While the use case is not very common and therefore may not deserve
explicit eclass support, the value of `PYTEST_PLUGINS` consists
of Python import names that are not trivial to find and have
historically changed across package versions.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
Part-of: https://github.com/gentoo/gentoo/pull/42876
Signed-off-by: Michał Górny <mgorny@gentoo.org>
This commit is contained in:
Michał Górny
2025-07-05 08:31:02 +02:00
parent 394e3796c6
commit ec67342e26

View File

@@ -1312,6 +1312,15 @@ _python_check_occluded_packages() {
# The recommended way to disable it in EAPI 8 or earlier is to set
# EPYTEST_PLUGINS (possibly to an empty array).
# @ECLASS_VARIABLE: EPYTEST_PLUGIN_LOAD_VIA_ENV
# @DEFAULT_UNSET
# @DESCRIPTION:
# If set to a non-empty value, plugins will be loaded via PYTEST_PLUGINS
# environment variable rather than explicit "-p" options. This ensures
# that plugins are passed down to subprocess, which may be necessary
# when testing pytest plugins. However, this is also more likely
# to cause duplicate plugin errors.
# @FUNCTION: _set_epytest_plugins
# @INTERNAL
# @DESCRIPTION:
@@ -1442,23 +1451,39 @@ epytest() {
if [[ ${PYTEST_DISABLE_PLUGIN_AUTOLOAD} ]]; then
if [[ ${EPYTEST_PLUGINS[@]} ]]; then
local plugin_args=()
readarray -t -d '' plugin_args < <(
"${EPYTHON}" - "${EPYTEST_PLUGINS[@]}" <<-EOF || die
import os
import sys
from importlib.metadata import distribution, entry_points
if [[ ${EPYTEST_PLUGIN_LOAD_VIA_ENV} ]]; then
local -x PYTEST_PLUGINS=$(
"${EPYTHON}" - "${EPYTEST_PLUGINS[@]}" <<-EOF || die
import sys
from importlib.metadata import distribution, entry_points
env_plugins = os.environ.get("PYTEST_PLUGINS", "").split(",")
packages = {distribution(x).name for x in sys.argv[1:]}
eps = {
f"-p{x.name}" for x in entry_points(group="pytest11")
if x.dist.name in packages and x.value not in env_plugins
}
sys.stdout.write("\\0".join(sorted(eps)))
EOF
)
args+=( "${plugin_args[@]}" )
packages = {distribution(x).name for x in sys.argv[1:]}
plugins = {
x.value for x in entry_points(group="pytest11")
if x.dist.name in packages
}
sys.stdout.write(",".join(sorted(plugins)))
EOF
)
else
local plugin_args=()
readarray -t -d '' plugin_args < <(
"${EPYTHON}" - "${EPYTEST_PLUGINS[@]}" <<-EOF || die
import os
import sys
from importlib.metadata import distribution, entry_points
env_plugins = os.environ.get("PYTEST_PLUGINS", "").split(",")
packages = {distribution(x).name for x in sys.argv[1:]}
eps = {
f"-p{x.name}" for x in entry_points(group="pytest11")
if x.dist.name in packages and x.value not in env_plugins
}
sys.stdout.write("\\0".join(sorted(eps)))
EOF
)
args+=( "${plugin_args[@]}" )
fi
fi
else
args+=(
@@ -1541,6 +1566,9 @@ epytest() {
done
set -- "${EPYTHON}" -m pytest "${args[@]}" "${@}" ${EPYTEST_FLAGS}
if [[ ${PYTEST_PLUGINS} ]]; then
einfo "PYTEST_PLUGINS=${PYTEST_PLUGINS}"
fi
echo "${@}" >&2
"${@}"
local ret=${?}