diff --git a/allure-pytest/src/compat.py b/allure-pytest/src/compat.py new file mode 100644 index 00000000..bf7db2dd --- /dev/null +++ b/allure-pytest/src/compat.py @@ -0,0 +1,34 @@ +"""Provides compatibility with different pytest versions.""" + +from inspect import signature + +__GETFIXTUREDEFS_2ND_PAR_IS_STR = None + + +def getfixturedefs(fixturemanager, name, item): + """Calls FixtureManager.getfixturedefs in a way compatible with Python + versions before and after the change described in pytest-dev/pytest#11785. + """ + getfixturedefs = fixturemanager.getfixturedefs + itemarg = __resolve_getfixturedefs_2nd_arg(getfixturedefs, item) + return getfixturedefs(name, itemarg) + + +def __resolve_getfixturedefs_2nd_arg(getfixturedefs, item): + # Starting from pytest 8.1, getfixturedefs requires the item itself. + # In earlier versions it requires the nodeid string. + return item.nodeid if __2nd_parameter_is_str(getfixturedefs) else item + + +def __2nd_parameter_is_str(getfixturedefs): + global __GETFIXTUREDEFS_2ND_PAR_IS_STR + if __GETFIXTUREDEFS_2ND_PAR_IS_STR is None: + __GETFIXTUREDEFS_2ND_PAR_IS_STR =\ + __get_2nd_parameter_type(getfixturedefs) is str + return __GETFIXTUREDEFS_2ND_PAR_IS_STR + + +def __get_2nd_parameter_type(fn): + return list( + signature(fn).parameters.values() + )[1].annotation diff --git a/allure-pytest/src/listener.py b/allure-pytest/src/listener.py index eb222bc0..11153630 100644 --- a/allure-pytest/src/listener.py +++ b/allure-pytest/src/listener.py @@ -1,6 +1,5 @@ import pytest import doctest -from packaging import version import allure_commons from allure_commons.utils import now @@ -8,6 +7,7 @@ from allure_commons.utils import represent from allure_commons.utils import platform_label from allure_commons.utils import host_tag, thread_tag +from allure_commons.utils import md5 from allure_commons.reporter import AllureReporter from allure_commons.model2 import TestStepResult, TestResult, TestBeforeResult, TestAfterResult from allure_commons.model2 import TestResultContainer @@ -25,7 +25,7 @@ from allure_pytest.utils import get_pytest_report_status from allure_pytest.utils import format_allure_link from allure_pytest.utils import get_history_id -from allure_commons.utils import md5 +from allure_pytest.compat import getfixturedefs class AllureListener: @@ -349,23 +349,13 @@ def _test_fixtures(item): if hasattr(item, "_request") and hasattr(item._request, "fixturenames"): for name in item._request.fixturenames: - fixturedefs_pytest = _getfixturedefs(fixturemanager, name, item) + fixturedefs_pytest = getfixturedefs(fixturemanager, name, item) if fixturedefs_pytest: fixturedefs.extend(fixturedefs_pytest) return fixturedefs -def _getfixturedefs(fixturemanager, name, item): - # See pytest-dev/pytest#11785 - itemarg = item if __is_pytest8_1_or_greater() else item.nodeid - return fixturemanager.getfixturedefs(name, itemarg) - - -def __is_pytest8_1_or_greater(): - return version.parse(pytest.__version__) >= version.parse("8.1") - - def _exception_brokes_test(exception): return not isinstance(exception, ( AssertionError,