From cd786536aa23da1d4183a0ebb3c46b5aa7238f76 Mon Sep 17 00:00:00 2001 From: lognd Date: Thu, 1 Oct 2026 21:53:41 -0400 Subject: [PATCH 1/8] Warn when pytest_plugins is defined in a test module Defining ``pytest_plugins`` in a test module activates the plugins for the entire test suite, not just that module, the same problem that led to the non-top-level conftest check. Unlike the conftest case nothing was reported, which wrongly implied that test modules were safe. Emit a ``PytestConfigWarning`` from ``Module.collect`` once a second test module is seen, so single-file plugin test suites stay quiet and a ``filterwarnings = error`` setup gets a normal collection error. Refs #13030 --- src/_pytest/python.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 792d0d5b4f3..5b8bc04936c 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -81,6 +81,7 @@ from _pytest.scope import ScopeName from _pytest.stash import StashKey from _pytest.warning_types import PytestCollectionWarning +from _pytest.warning_types import PytestConfigWarning from _pytest.warning_types import PytestReturnNotNoneWarning @@ -574,6 +575,11 @@ def importtestmodule( return mod +# Test modules collected so far, used to decide whether to warn about +# ``pytest_plugins`` in a test module (#13030). +_collected_modules_key = StashKey[list["Module"]]() + + class Module(nodes.File, PyCollector): """Collector for test classes and functions in a Python module.""" @@ -584,8 +590,31 @@ def collect(self) -> Iterable[nodes.Item | nodes.Collector]: self._register_setup_module_fixture() self._register_setup_function_fixture() self.session._fixturemanager.parsefactories(self) + self._warn_pytest_plugins_in_test_module() return super().collect() + def _warn_pytest_plugins_in_test_module(self) -> None: + """Warn when a test module defines ``pytest_plugins`` (#13030). + + Such plugins affect the entire test suite rather than only the + declaring module. A single-file suite (common for plugin tests) cannot + be affected, so the warning is held back until a second test module + is collected. + """ + modules = self.config.stash.setdefault(_collected_modules_key, []) + modules.append(self) + if len(modules) < 2: + return + for module in modules if len(modules) == 2 else (self,): + if hasattr(module.obj, "pytest_plugins"): + module.warn( + PytestConfigWarning( + f"Defining 'pytest_plugins' in test module {module.nodeid} " + "affects the entire test suite instead of just this module.\n" + "Please move it to a top level conftest file at the rootdir." + ) + ) + def _register_setup_module_fixture(self) -> None: """Register an autouse, module-scoped fixture for the collected module object that invokes setUpModule/tearDownModule if either or both are available. From 7b0feeb8c77a8f231e670b3f63c3bbd60fc60d29 Mon Sep 17 00:00:00 2001 From: lognd Date: Thu, 1 Oct 2026 22:14:37 -0400 Subject: [PATCH 2/8] Test the pytest_plugins-in-test-module warning Cover the warning, the single-file suite exemption, and the behavior under an error warning filter. Refs #13030 --- testing/test_config.py | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/testing/test_config.py b/testing/test_config.py index dad1653e299..9568e8ebdae 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -3036,6 +3036,58 @@ def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported" assert msg not in res.stdout.str() + @pytest.mark.filterwarnings("default") + def test_pytest_plugins_in_test_module_warns(self, pytester: Pytester) -> None: + """Using pytest_plugins in a test module affects the whole suite (#13030).""" + pytester.makepyfile( + test_a="def test_a(): pass", + test_b=""" + pytest_plugins = ['capture'] + + def test_b(): pass + """, + ) + res = pytester.runpytest() + assert res.ret == 0 + res.stdout.fnmatch_lines( + [ + "*test_b.py:1: PytestConfigWarning: Defining 'pytest_plugins' " + "in test module test_b.py affects the entire test suite*", + "*2 passed, 1 warning*", + ] + ) + + def test_pytest_plugins_in_single_test_module_no_warning( + self, pytester: Pytester + ) -> None: + """A single-file test suite (e.g. a plugin's own tests) stays quiet (#13030).""" + pytester.makepyfile( + """ + pytest_plugins = ['capture'] + + def test_func(): pass + """ + ) + res = pytester.runpytest() + assert res.ret == 0 + assert "Defining 'pytest_plugins' in test module" not in res.stdout.str() + + def test_pytest_plugins_in_test_module_as_error(self, pytester: Pytester) -> None: + """Turned into an error, the warning is a regular collection error (#13030).""" + pytester.makepyfile( + test_a="def test_a(): pass", + test_b=""" + pytest_plugins = ['capture'] + + def test_b(): pass + """, + ) + res = pytester.runpytest("-W", "error::pytest.PytestConfigWarning") + assert res.ret == pytest.ExitCode.INTERRUPTED + res.stdout.fnmatch_lines( + ["*ERROR collecting test_b.py*", "*in test module test_b.py affects*"] + ) + def test_conftest_import_error_repr(tmp_path: Path) -> None: """`ConftestImportFailure` should use a short error message and readable From f26886cb19009b161074e241f0d3d8023904ed03 Mon Sep 17 00:00:00 2001 From: lognd Date: Thu, 1 Oct 2026 22:41:05 -0400 Subject: [PATCH 3/8] Drop redundant pytest_plugins from test_cacheprovider The pytester plugin is already enabled for the whole suite through addopts, and the module-level declaration now triggers the new warning, which pytest's own suite turns into an error. --- testing/test_cacheprovider.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index a38a72c6011..bb4fd9f6ad1 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -19,9 +19,6 @@ import pytest -pytest_plugins = ("pytester",) - - class TestNewAPI: def test_config_cache_mkdir(self, pytester: Pytester) -> None: pytester.makeini("[pytest]") From 19b6f821cd48413a9884715a33889048bdc9ffa6 Mon Sep 17 00:00:00 2001 From: lognd Date: Thu, 1 Oct 2026 23:07:06 -0400 Subject: [PATCH 4/8] Document the pytest_plugins-in-test-module warning Add the changelog entry, a note in the plugin-writing guide next to the existing non-root conftest note, and the AUTHORS entry. Closes #13030 --- AUTHORS | 1 + changelog/13030.improvement.rst | 1 + doc/en/how-to/writing_plugins.rst | 4 ++++ 3 files changed, 6 insertions(+) create mode 100644 changelog/13030.improvement.rst diff --git a/AUTHORS b/AUTHORS index e2fad5e8364..ead34f9807b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -288,6 +288,7 @@ Levon Saldamli Lewis Cowles Liam DeVoe Llandy Riveron Del Risco +Logan Dapp Loic Esteve lovetheguitar Lukas Bednar diff --git a/changelog/13030.improvement.rst b/changelog/13030.improvement.rst new file mode 100644 index 00000000000..15445a397be --- /dev/null +++ b/changelog/13030.improvement.rst @@ -0,0 +1 @@ +A :class:`~pytest.PytestConfigWarning` is now emitted when :globalvar:`pytest_plugins` is defined in a test module and more than one test file is collected, since the plugins affect the entire test suite rather than only that module. diff --git a/doc/en/how-to/writing_plugins.rst b/doc/en/how-to/writing_plugins.rst index 079bde6274f..799a1aa3dc6 100644 --- a/doc/en/how-to/writing_plugins.rst +++ b/doc/en/how-to/writing_plugins.rst @@ -278,6 +278,10 @@ of the variable will also be loaded as plugins, and so on. :globalvar:`pytest_plugins` in any ``conftest.py`` file which is not located in the tests root directory is deprecated, and will raise a warning. + Likewise, defining :globalvar:`pytest_plugins` in a test module affects the + entire test suite, so pytest emits a :class:`~pytest.PytestConfigWarning` + when it finds one while collecting more than one test file. + This mechanism makes it easy to share fixtures within applications or even external applications without the need to create external plugins using the :std:doc:`entry point packaging metadata From 24c84bcc871fc84b1e933654d5484721a0aa7189 Mon Sep 17 00:00:00 2001 From: lognd Date: Tue, 13 Oct 2026 01:56:45 -0400 Subject: [PATCH 5/8] Keep only a count and the first module for the pytest_plugins check Storing every collected Module in the config stash kept them all alive for the whole session. The check only needs to know how many modules were collected and which one came first, and the first one can be dropped once the second is collected. --- src/_pytest/python.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 5b8bc04936c..e221fb67f9d 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -575,9 +575,16 @@ def importtestmodule( return mod -# Test modules collected so far, used to decide whether to warn about -# ``pytest_plugins`` in a test module (#13030). -_collected_modules_key = StashKey[list["Module"]]() +@dataclasses.dataclass +class _CollectedTestModules: + """Test modules collected so far, to warn about ``pytest_plugins`` (#13030).""" + + count: int = 0 + # Held only until the second test module is collected. + first: Module | None = None + + +_collected_test_modules_key = StashKey[_CollectedTestModules]() class Module(nodes.File, PyCollector): @@ -601,19 +608,27 @@ def _warn_pytest_plugins_in_test_module(self) -> None: be affected, so the warning is held back until a second test module is collected. """ - modules = self.config.stash.setdefault(_collected_modules_key, []) - modules.append(self) - if len(modules) < 2: + collected = self.config.stash.setdefault( + _collected_test_modules_key, _CollectedTestModules() + ) + collected.count += 1 + if collected.count == 1: + collected.first = self return - for module in modules if len(modules) == 2 else (self,): - if hasattr(module.obj, "pytest_plugins"): - module.warn( - PytestConfigWarning( - f"Defining 'pytest_plugins' in test module {module.nodeid} " - "affects the entire test suite instead of just this module.\n" - "Please move it to a top level conftest file at the rootdir." - ) + if collected.first is not None: + first, collected.first = collected.first, None + first._warn_if_pytest_plugins() + self._warn_if_pytest_plugins() + + def _warn_if_pytest_plugins(self) -> None: + if hasattr(self.obj, "pytest_plugins"): + self.warn( + PytestConfigWarning( + f"Defining 'pytest_plugins' in test module {self.nodeid} " + "affects the entire test suite instead of just this module.\n" + "Please move it to a top level conftest file at the rootdir." ) + ) def _register_setup_module_fixture(self) -> None: """Register an autouse, module-scoped fixture for the collected module object From 32add17ca74d6e928179bf3a4529ef545de55c76 Mon Sep 17 00:00:00 2001 From: lognd Date: Tue, 13 Oct 2026 02:23:10 -0400 Subject: [PATCH 6/8] Report the pytest_plugins warning against the module defining it The first collected module can only be warned about once a second one is collected. With -W error that surfaced as a collection error of the second module, even though the first one defines pytest_plugins. Report it as a collection error of the defining module instead, and test both the first and a later module. --- src/_pytest/python.py | 16 +++++++++++- testing/test_config.py | 55 ++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index e221fb67f9d..8623f7c5de9 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -77,6 +77,7 @@ from _pytest.pathlib import import_path from _pytest.pathlib import ImportPathMismatchError from _pytest.pathlib import scandir +from _pytest.reports import CollectReport from _pytest.scope import Scope from _pytest.scope import ScopeName from _pytest.stash import StashKey @@ -617,7 +618,7 @@ def _warn_pytest_plugins_in_test_module(self) -> None: return if collected.first is not None: first, collected.first = collected.first, None - first._warn_if_pytest_plugins() + first._warn_pytest_plugins_retroactively() self._warn_if_pytest_plugins() def _warn_if_pytest_plugins(self) -> None: @@ -630,6 +631,19 @@ def _warn_if_pytest_plugins(self) -> None: ) ) + def _warn_pytest_plugins_retroactively(self) -> None: + """Warn about this already collected module while another one is collected. + + If the warning is turned into an error, report it as a collection error + of this module instead of the module currently being collected. + """ + try: + self._warn_if_pytest_plugins() + except PytestConfigWarning: + longrepr = self.repr_failure(ExceptionInfo.from_current()) + report = CollectReport(self.nodeid, "failed", longrepr, []) + self.ihook.pytest_collectreport(report=report) + def _register_setup_module_fixture(self) -> None: """Register an autouse, module-scoped fixture for the collected module object that invokes setUpModule/tearDownModule if either or both are available. diff --git a/testing/test_config.py b/testing/test_config.py index 9568e8ebdae..cfce8165434 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -3036,23 +3036,34 @@ def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported" assert msg not in res.stdout.str() + @pytest.mark.parametrize("module", ["test_a", "test_b"]) @pytest.mark.filterwarnings("default") - def test_pytest_plugins_in_test_module_warns(self, pytester: Pytester) -> None: - """Using pytest_plugins in a test module affects the whole suite (#13030).""" + def test_pytest_plugins_in_test_module_warns( + self, pytester: Pytester, module: str + ) -> None: + """Using pytest_plugins in a test module affects the whole suite (#13030). + + Covers both the first collected module (warned retroactively) and a later one. + """ pytester.makepyfile( test_a="def test_a(): pass", - test_b=""" - pytest_plugins = ['capture'] + test_b="def test_b(): pass", + ) + pytester.makepyfile( + **{ + module: f""" + pytest_plugins = ['capture'] - def test_b(): pass - """, + def {module}(): pass + """ + } ) res = pytester.runpytest() assert res.ret == 0 res.stdout.fnmatch_lines( [ - "*test_b.py:1: PytestConfigWarning: Defining 'pytest_plugins' " - "in test module test_b.py affects the entire test suite*", + f"*{module}.py:1: PytestConfigWarning: Defining 'pytest_plugins' " + f"in test module {module}.py affects the entire test suite*", "*2 passed, 1 warning*", ] ) @@ -3072,21 +3083,35 @@ def test_func(): pass assert res.ret == 0 assert "Defining 'pytest_plugins' in test module" not in res.stdout.str() - def test_pytest_plugins_in_test_module_as_error(self, pytester: Pytester) -> None: - """Turned into an error, the warning is a regular collection error (#13030).""" + @pytest.mark.parametrize("module", ["test_a", "test_b"]) + def test_pytest_plugins_in_test_module_as_error( + self, pytester: Pytester, module: str + ) -> None: + """As an error, it is a collection error of the defining module (#13030).""" pytester.makepyfile( test_a="def test_a(): pass", - test_b=""" - pytest_plugins = ['capture'] + test_b="def test_b(): pass", + ) + pytester.makepyfile( + **{ + module: f""" + pytest_plugins = ['capture'] - def test_b(): pass - """, + def {module}(): pass + """ + } ) res = pytester.runpytest("-W", "error::pytest.PytestConfigWarning") assert res.ret == pytest.ExitCode.INTERRUPTED res.stdout.fnmatch_lines( - ["*ERROR collecting test_b.py*", "*in test module test_b.py affects*"] + [ + f"*ERROR collecting {module}.py*", + f"*in test module {module}.py affects*", + "*1 error*", + ] ) + other = "test_b" if module == "test_a" else "test_a" + res.stdout.no_fnmatch_line(f"*ERROR collecting {other}.py*") def test_conftest_import_error_repr(tmp_path: Path) -> None: From e2d46077db04002089bff7d982624cdca794cbe4 Mon Sep 17 00:00:00 2001 From: lognd Date: Tue, 13 Oct 2026 02:53:07 -0400 Subject: [PATCH 7/8] Deprecate pytest_plugins in test modules The long-term direction is to deprecate pytest_plugins in test modules altogether, so emit a PytestDeprecationWarning instead of a config warning. It is not tied to a removal version yet. Document it in the deprecations page and turn the changelog entry into a deprecation. --- changelog/13030.deprecation.rst | 2 ++ changelog/13030.improvement.rst | 1 - doc/en/deprecations.rst | 24 ++++++++++++++++++++++++ doc/en/how-to/writing_plugins.rst | 5 +++-- src/_pytest/deprecated.py | 11 +++++++++++ src/_pytest/python.py | 13 ++++--------- testing/test_config.py | 4 ++-- 7 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 changelog/13030.deprecation.rst delete mode 100644 changelog/13030.improvement.rst diff --git a/changelog/13030.deprecation.rst b/changelog/13030.deprecation.rst new file mode 100644 index 00000000000..21949d62e4c --- /dev/null +++ b/changelog/13030.deprecation.rst @@ -0,0 +1,2 @@ +Defining :globalvar:`pytest_plugins` in a test module is now deprecated and emits a :class:`~pytest.PytestDeprecationWarning` when more than one test file is collected, since the plugins affect the entire test suite rather than only that module. +See :ref:`pytest-plugins-in-test-modules` for details. diff --git a/changelog/13030.improvement.rst b/changelog/13030.improvement.rst deleted file mode 100644 index 15445a397be..00000000000 --- a/changelog/13030.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -A :class:`~pytest.PytestConfigWarning` is now emitted when :globalvar:`pytest_plugins` is defined in a test module and more than one test file is collected, since the plugins affect the entire test suite rather than only that module. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 59f11c4ec09..395ffed8bfd 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -15,6 +15,30 @@ Below is a complete list of all pytest features which are considered deprecated. :class:`~pytest.PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. +.. _pytest-plugins-in-test-modules: + +``pytest_plugins`` in test modules +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 9.2 + +Defining :globalvar:`pytest_plugins` in a test module is deprecated, because the +plugins it lists are activated for the *entire* test suite, not only for that +module. This is surprising, and the outcome of other test modules can depend on +whether that module happens to be collected. + +To keep single-file test suites (common for testing plugins) working, the +:class:`~pytest.PytestDeprecationWarning` is only emitted when more than one +test file is collected. There is no removal version yet. + +Move the variable to a ``conftest.py`` file at the rootdir instead: + +.. code-block:: python + + # content of conftest.py + pytest_plugins = ["myapp.testsupport.myplugin"] + + .. _callspec2-renamed: ``_pytest.python.CallSpec2`` renamed to ``CallSpec`` diff --git a/doc/en/how-to/writing_plugins.rst b/doc/en/how-to/writing_plugins.rst index 799a1aa3dc6..743fe73e69c 100644 --- a/doc/en/how-to/writing_plugins.rst +++ b/doc/en/how-to/writing_plugins.rst @@ -279,8 +279,9 @@ of the variable will also be loaded as plugins, and so on. tests root directory is deprecated, and will raise a warning. Likewise, defining :globalvar:`pytest_plugins` in a test module affects the - entire test suite, so pytest emits a :class:`~pytest.PytestConfigWarning` - when it finds one while collecting more than one test file. + entire test suite, so it is deprecated and pytest emits a + :class:`~pytest.PytestDeprecationWarning` when it finds one while collecting + more than one test file. See :ref:`pytest-plugins-in-test-modules`. This mechanism makes it easy to share fixtures within applications or even external applications without the need to create external plugins using the diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 0370240ee80..aafd23b06f1 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -47,6 +47,17 @@ PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.") +# Not tied to a removal version yet (#13030). +PYTEST_PLUGINS_IN_TEST_MODULE = UnformattedWarning( + PytestDeprecationWarning, + "Defining 'pytest_plugins' in test module {nodeid} affects the entire test suite " + "instead of just this module.\n" + "Please move it to a top level conftest file at the rootdir.\n" + "See https://docs.pytest.org/en/stable/deprecations.html" + "#pytest-plugins-in-test-modules", +) + + HOOK_LEGACY_MARKING = UnformattedWarning( PytestRemovedIn10Warning, "The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n" diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 8623f7c5de9..52780d2f29d 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -57,6 +57,7 @@ from _pytest.config.argparsing import Parser from _pytest.deprecated import CALLSPEC2_RENAMED from _pytest.deprecated import check_ispytest +from _pytest.deprecated import PYTEST_PLUGINS_IN_TEST_MODULE from _pytest.fixtures import _resolve_args_directness from _pytest.fixtures import FixtureDef from _pytest.fixtures import FixtureRequest @@ -82,7 +83,7 @@ from _pytest.scope import ScopeName from _pytest.stash import StashKey from _pytest.warning_types import PytestCollectionWarning -from _pytest.warning_types import PytestConfigWarning +from _pytest.warning_types import PytestDeprecationWarning from _pytest.warning_types import PytestReturnNotNoneWarning @@ -623,13 +624,7 @@ def _warn_pytest_plugins_in_test_module(self) -> None: def _warn_if_pytest_plugins(self) -> None: if hasattr(self.obj, "pytest_plugins"): - self.warn( - PytestConfigWarning( - f"Defining 'pytest_plugins' in test module {self.nodeid} " - "affects the entire test suite instead of just this module.\n" - "Please move it to a top level conftest file at the rootdir." - ) - ) + self.warn(PYTEST_PLUGINS_IN_TEST_MODULE.format(nodeid=self.nodeid)) def _warn_pytest_plugins_retroactively(self) -> None: """Warn about this already collected module while another one is collected. @@ -639,7 +634,7 @@ def _warn_pytest_plugins_retroactively(self) -> None: """ try: self._warn_if_pytest_plugins() - except PytestConfigWarning: + except PytestDeprecationWarning: longrepr = self.repr_failure(ExceptionInfo.from_current()) report = CollectReport(self.nodeid, "failed", longrepr, []) self.ihook.pytest_collectreport(report=report) diff --git a/testing/test_config.py b/testing/test_config.py index cfce8165434..ec19b88e328 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -3062,7 +3062,7 @@ def {module}(): pass assert res.ret == 0 res.stdout.fnmatch_lines( [ - f"*{module}.py:1: PytestConfigWarning: Defining 'pytest_plugins' " + f"*{module}.py:1: PytestDeprecationWarning: Defining 'pytest_plugins' " f"in test module {module}.py affects the entire test suite*", "*2 passed, 1 warning*", ] @@ -3101,7 +3101,7 @@ def {module}(): pass """ } ) - res = pytester.runpytest("-W", "error::pytest.PytestConfigWarning") + res = pytester.runpytest("-W", "error::pytest.PytestDeprecationWarning") assert res.ret == pytest.ExitCode.INTERRUPTED res.stdout.fnmatch_lines( [ From ed22eab3e7776a26bc29208bd5f29762b2d721d0 Mon Sep 17 00:00:00 2001 From: lognd Date: Tue, 13 Oct 2026 08:58:35 -0400 Subject: [PATCH 8/8] Use the structured node id for the pytest_plugins collection report Collection reports are built from the node's structured id since #14758 (see runner.py and cacheprovider.py). Passing the string nodeid made CollectReport parse it back. --- src/_pytest/python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 974aead1fd1..c92864d57ce 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -636,7 +636,7 @@ def _warn_pytest_plugins_retroactively(self) -> None: self._warn_if_pytest_plugins() except PytestDeprecationWarning: longrepr = self.repr_failure(ExceptionInfo.from_current()) - report = CollectReport(self.nodeid, "failed", longrepr, []) + report = CollectReport(self.id, "failed", longrepr, []) self.ihook.pytest_collectreport(report=report) def _register_setup_module_fixture(self) -> None: