diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 3a10c3aa8..e08fc41d3 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1199,9 +1199,43 @@ class Config: """ self._cleanup_stack.callback(func) + @contextlib.contextmanager + def _catch_configured_warnings( + self, + *, + record: bool, + ) -> Generator[list[warnings.WarningMessage] | None]: + config_filters = self.getini("filterwarnings") + cmdline_filters = self.known_args_namespace.pythonwarnings or [] + with warnings.catch_warnings(record=record) as log: + if not sys.warnoptions: + ... + apply_warning_filters(config_filters, cmdline_filters) + yield log def _do_configure(self) -> None: + if self.pluginmanager.hasplugin("warnings"): + with contextlib.ExitStack() as stack: + stack.enter_context(self._catch_configured_warnings(record=False)) + self.add_cleanup(stack.pop_all().close) self.hook.pytest_configure.call_historic(kwargs=dict(config=self)) diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index d599d6c27..2c721d6e3 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -33,19 +30,7 @@ def catch_warnings_for_item( Each warning captured triggers the ``pytest_warning_recorded`` hook. """ - with warnings.catch_warnings(record=record) as log: - if not sys.warnoptions: - ... - apply_warning_filters(config_filters, cmdline_filters) + with config._catch_configured_warnings(record=record) as log: diff --git a/testing/test_warnings.py b/testing/test_warnings.py index e2363bd88..6b439eb4b 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -700,6 +700,39 @@ def test_pytest_configure_warning(pytester: Pytester, recwarn) -> None: +@pytest.mark.parametrize("tryfirst", [True, False]) +def test_pytest_configure_warning_filter(pytester: Pytester, tryfirst: bool) -> None: + pytester.makeini( + """ + [pytest] + filterwarnings = + ignore::UserWarning + """ + ) + pytester.makeconftest( + f""" + @pytest.hookimpl(tryfirst={tryfirst}) + def pytest_configure(): + warnings.warn("from pytest_configure", UserWarning) + """ + ) + pytester.makepyfile("def test_it(): pass") + result = pytester.runpytest_subprocess() + result.assert_outcomes(passed=1) + result.stdout.no_fnmatch_line("*from pytest_configure*")