From 15c846666ac3f5c563c508ebed9b8ca6e9e6554f Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:31:55 +0700 Subject: [PATCH] Replace pytest version check with signature test --- allure-pytest/src/compat.py | 34 ++++++++++++++++++++++++++++++++++ allure-pytest/src/listener.py | 16 +++------------- 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 allure-pytest/src/compat.py 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,