From 91c3ec28d8da3d036ccf9898687865b3f7e9536f Mon Sep 17 00:00:00 2001 From: Flatcar Buildbot Date: Mon, 30 Jun 2025 07:11:27 +0000 Subject: [PATCH] eclass/python-utils-r1: Sync with Gentoo It's from Gentoo commit 5d8cc9a83de7eec8350aebcccd091c6b6c9ff2a5. --- .../eclass/python-utils-r1.eclass | 112 +++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass b/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass index 840b820d00..dce565b8b0 100644 --- a/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass +++ b/sdk_container/src/third_party/portage-stable/eclass/python-utils-r1.eclass @@ -1273,6 +1273,78 @@ _python_check_occluded_packages() { # parameter, when calling epytest. The listed files will be entirely # skipped from test collection. +# @ECLASS_VARIABLE: EPYTEST_PLUGINS +# @DEFAULT_UNSET +# @DESCRIPTION: +# An array of pytest plugin package names (without categories) to use +# for the package. It has a twofold purpose: +# +# 1. When set prior to calling distutils_enable_tests, it causes +# dependencies on the specified pytest plugins to be added. +# +# 2. When plugin autoloading is disabled, it causes "-p" arguments +# loading specified plugins to be added. +# +# Defaults to an empty list. +# +# The eclasses explicitly handle a number of pytest plugins, and assume +# the default of "dev-python/${package}" and obtain "-p" via entry +# points. If this is incorrect for some plugin package, please report +# a bug. +# +# This is not a perfect solution, and may not be sufficient for some +# packages. In these cases, either plugin autoloading should be used +# or PYTEST_PLUGINS environment variable may be used directly (see +# pytest documentation). +# +# For pytest-timeout and pytest-xdist plugins, it is generally +# preferable to use EPYTEST_TIMEOUT and EPYTEST_XDIST options +# that handle passing all needed options. + +# @ECLASS_VARIABLE: EPYTEST_PLUGIN_AUTOLOAD +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to a non-empty value, permits pytest plugin autoloading. +# Otherwise, PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 is set to disable it. +# +# If EPYTEST_PLUGINS is set explicitly or EAPI is 9 or later, +# defaults to disabled. Otherwise, defaults to enabled. +# The recommended way to disable it in EAPI 8 or earlier is to set +# EPYTEST_PLUGINS (possibly to an empty array). + +# @FUNCTION: _set_epytest_plugins +# @INTERNAL +# @DESCRIPTION: +# Check if EPYTEST_PLUGINS is set correctly, and set the default +# if it is not. +_set_epytest_plugins() { + debug-print-function ${FUNCNAME} "$@" + + # TODO: drop BASH_VERSINFO check when we require EAPI 8 + if [[ ${BASH_VERSINFO[0]} -ge 5 ]]; then + [[ ${EPYTEST_PLUGINS@a} == *a* ]] + else + [[ $(declare -p EPYTEST_PLUGINS) == "declare -a"* ]] + fi + if [[ ${?} -eq 0 ]]; then + # EPYTEST_PLUGINS set explicitly -- disable autoloading + : "${EPYTEST_PLUGIN_AUTOLOAD:=}" + else + if ! declare -p EPYTEST_PLUGINS &>/dev/null; then + # EPYTEST_PLUGINS unset -- default to empty. + # EPYTEST_PLUGIN_AUTOLOAD default depends on EAPI. + EPYTEST_PLUGINS=() + if [[ ${EAPI} != [78] ]]; then + : "${EPYTEST_PLUGIN_AUTOLOAD:=}" + else + : "${EPYTEST_PLUGIN_AUTOLOAD:=1}" + fi + else + die 'EPYTEST_PLUGINS must be an array.' + fi + fi +} + # @ECLASS_VARIABLE: EPYTEST_TIMEOUT # @DEFAULT_UNSET # @DESCRIPTION: @@ -1324,6 +1396,9 @@ epytest() { local color=yes [[ ${NO_COLOR} ]] && color=no + mkdir -p "${T}/pytest-xml" || die + local junit_xml=$(mktemp "${T}/pytest-xml/${EPYTHON}-XXX.xml" || die) + local args=( # verbose progress reporting and tracebacks -vv @@ -1345,9 +1420,44 @@ epytest() { # we don't need to preserve them -o tmp_path_retention_count=0 -o tmp_path_retention_policy=failed + # write a junit .xml file to aid machine processing of results + --junit-xml="${junit_xml}" + # use xunit1 format as that includes an explicit path + -o junit_family=xunit1 ) - if [[ ! ${PYTEST_DISABLE_PLUGIN_AUTOLOAD} ]]; then + if has_version ">=dev-python/pytest-8.4.0"; then + args+=( + # do not repeat (potentially multi-line) exception messages + # in the "short summary" section to make it more readable; + # we have them in the backtraces anyway + --force-short-summary + ) + fi + + _set_epytest_plugins + if [[ ! ${EPYTEST_PLUGIN_AUTOLOAD} ]]; then + local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 + fi + + if [[ ${PYTEST_DISABLE_PLUGIN_AUTOLOAD} ]]; then + if [[ ${EPYTEST_PLUGINS[@]} ]]; then + local plugin_args=() + readarray -t -d '' plugin_args < <( + "${EPYTHON}" - "${EPYTEST_PLUGINS[@]}" <<-EOF || die + import sys + from importlib.metadata import distribution, entry_points + 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 + } + sys.stdout.write("\\0".join(sorted(eps))) + EOF + ) + args+=( "${plugin_args[@]}" ) + fi + else args+=( # disable the undesirable-dependency plugins by default to # trigger missing argument strips. strip options that require