From 1e736b6e4091c23038c296dbbf6c27a6d858682a Mon Sep 17 00:00:00 2001 From: Nate Clark Date: Mon, 23 Oct 2023 10:52:29 -0400 Subject: [PATCH] Issue #362: Only unconfigure if configured `pytest_unconfigure` can be called even if `pytest_configure` was not. In order to avoid errors during unconfigure only perform the unconfigure if the configure was performed. Add a counter which is incremented before configure to track the number of times pytest started initialization so that the config is not popped early from the stack. --- src/pytest_bdd/plugin.py | 15 +++++++++++++-- tests/test_hooks.py | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/pytest_bdd/plugin.py b/src/pytest_bdd/plugin.py index 486cdf87..a92b3565 100644 --- a/src/pytest_bdd/plugin.py +++ b/src/pytest_bdd/plugin.py @@ -21,6 +21,10 @@ from .parser import Feature, Scenario, Step +# Counter to track how many times pytest initialization was started +_INIT_COUNT = 0 + + def pytest_addhooks(pluginmanager: PytestPluginManager) -> None: """Register plugin hooks.""" from pytest_bdd import hooks @@ -52,6 +56,8 @@ def _pytest_bdd_example() -> dict: def pytest_addoption(parser: Parser) -> None: """Add pytest-bdd options.""" + global _INIT_COUNT + _INIT_COUNT += 1 add_bdd_ini(parser) cucumber_json.add_options(parser) generation.add_options(parser) @@ -66,14 +72,19 @@ def add_bdd_ini(parser: Parser) -> None: def pytest_configure(config: Config) -> None: """Configure all subplugins.""" CONFIG_STACK.append(config) + assert _INIT_COUNT == len(CONFIG_STACK) cucumber_json.configure(config) gherkin_terminal_reporter.configure(config) def pytest_unconfigure(config: Config) -> None: """Unconfigure all subplugins.""" - CONFIG_STACK.pop() - cucumber_json.unconfigure(config) + global _INIT_COUNT + assert len(CONFIG_STACK) <= _INIT_COUNT + if len(CONFIG_STACK) == _INIT_COUNT: + CONFIG_STACK.pop() + _INIT_COUNT -= 1 + cucumber_json.unconfigure(config) @pytest.hookimpl(hookwrapper=True) diff --git a/tests/test_hooks.py b/tests/test_hooks.py index e3fda90c..c863b3bb 100644 --- a/tests/test_hooks.py +++ b/tests/test_hooks.py @@ -135,3 +135,17 @@ def pytest_bdd_after_scenario(request, feature, scenario): assert scenario_1.name == "Scenario 1" assert scenario_2.name == "Scenario 2" + + +def test_pytest_unconfigure_without_configure(pytester): + pytester.makeconftest( + """ + import pytest + + def pytest_configure(config): + pytest.exit("Exit during configure", 0) + """ + ) + + result = pytester.runpytest() + assert result.ret == 0