From f00d15e70428ac60219038236bf6504fe111be6b Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Tue, 16 Jul 2024 03:05:07 +0200 Subject: [PATCH] Load plugins referencing entry point name provided via config and env var This allows to load plugins via `PYTEST_PLUGINS` environment variable and `pytest_plugins` global variable using their names in installed package entry points. Closes #12624. --- AUTHORS | 1 + changelog/12624.improvement.rst | 5 +++++ doc/en/reference/reference.rst | 4 +++- src/_pytest/config/__init__.py | 2 +- testing/test_assertion.py | 1 + testing/test_config.py | 4 ++++ testing/test_helpconfig.py | 3 ++- 7 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 changelog/12624.improvement.rst diff --git a/AUTHORS b/AUTHORS index 9b6cb6a9d23..7a91651f098 100644 --- a/AUTHORS +++ b/AUTHORS @@ -257,6 +257,7 @@ Mandeep Bhutani Manuel Krebber Marc Mueller Marc Schlaich +Marcel Telka Marcelo Duarte Trevisani Marcin Bachry Marc Bresson diff --git a/changelog/12624.improvement.rst b/changelog/12624.improvement.rst new file mode 100644 index 00000000000..7ca60d428dd --- /dev/null +++ b/changelog/12624.improvement.rst @@ -0,0 +1,5 @@ +Plugins specified in the :globalvar:`pytest_plugins` config setting and +:envvar:`PYTEST_PLUGINS` environment variable now allow using +:ref:`entry points ` names additionally to the +importable definitions. Prior to this release, these identifiers used to only +work with the ``-p`` CLI option -- by :user:`mtelka` and :user:`webknjaz`. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index 099c8a00260..f7c364952bd 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -1153,7 +1153,9 @@ specified plugins will be loaded. .. envvar:: PYTEST_PLUGINS -Contains comma-separated list of modules that should be loaded as plugins: +Contains comma-separated list of :term:`importable modules ` +or :ref:`entry point names ` that should be +loaded as plugins: .. code-block:: bash diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 0c1850df503..bb8cf4b0ad9 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -828,7 +828,7 @@ def _import_plugin_specs( ) -> None: plugins = _get_plugin_specs_as_list(spec) for import_spec in plugins: - self.import_plugin(import_spec) + self.import_plugin(import_spec, consider_entry_points=True) def import_plugin(self, modname: str, consider_entry_points: bool = False) -> None: """Import a plugin with ``modname``. diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 69ca0f73ff2..2c7bebcd3fb 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -222,6 +222,7 @@ def test_installed_plugin_rewrite( self, pytester: Pytester, mode, monkeypatch ) -> None: monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) # Make sure the hook is installed early enough so that plugins # installed via distribution package are rewritten. pytester.mkdir("hampkg") diff --git a/testing/test_config.py b/testing/test_config.py index 232839399e2..f4b2dbbd279 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -503,6 +503,7 @@ def my_dists(): monkeypatch.setattr(importlib.metadata, "distributions", my_dists) monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) pytester.makeini(ini_file_text) @@ -1143,6 +1144,7 @@ def test_importlib_metadata_broken_distribution( ) -> None: """Integration test for broken distributions with 'files' metadata being None (#5389)""" monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) class DummyEntryPoint: name = "mytestplugin" @@ -1169,6 +1171,7 @@ def test_plugin_preparse_prevents_setuptools_loading( pytester: Pytester, monkeypatch: MonkeyPatch, block_it: bool ) -> None: monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) plugin_module_placeholder = object() @@ -1237,6 +1240,7 @@ def distributions(): return (Distribution(),) monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1") + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) monkeypatch.setattr(importlib.metadata, "distributions", distributions) monkeypatch.setitem(sys.modules, "mytestplugin", PseudoPlugin()) config = pytester.parseconfig(*parse_args) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 7fcf5804ace..b02ba4478f7 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -62,7 +62,7 @@ def pytest_addoption(parser): ) -def test_empty_help_param(pytester: Pytester) -> None: +def test_empty_help_param(pytester: Pytester, monkeypatch) -> None: """Test that an empty help param is displayed correctly.""" pytester.makeconftest( """ @@ -70,6 +70,7 @@ def pytest_addoption(parser): parser.addini("test_ini", "", default=True, type="bool") """ ) + monkeypatch.delenv("PYTEST_PLUGINS", raising=False) result = pytester.runpytest("--help") assert result.ret == 0 lines = [