diff --git a/changelog/4936.feature.rst b/changelog/4936.feature.rst new file mode 100644 index 000000000..744af1297 --- /dev/null +++ b/changelog/4936.feature.rst @@ -0,0 +1,4 @@ +Handle ``-p plug`` after ``-p no:plug``. + +This can be used to override a blocked plugin (e.g. in "addopts") from the +command line etc. diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 22eeaa33d..c44392073 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -496,6 +496,14 @@ class PytestPluginManager(PluginManager): if not name.startswith("pytest_"): self.set_blocked("pytest_" + name) else: + name = arg + # Unblock the plugin. None indicates that it has been blocked. + # There is no interface with pluggy for this. + if self._name2plugin.get(name, -1) is None: + del self._name2plugin[name] + if not name.startswith("pytest_"): + if self._name2plugin.get("pytest_" + name, -1) is None: + del self._name2plugin["pytest_" + name] self.import_plugin(arg, consider_entry_points=True) def consider_conftest(self, conftestmodule): diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 80817932e..4e0c0ed1e 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -346,3 +346,10 @@ class TestPytestPluginManagerBootstrapming(object): l2 = pytestpm.get_plugins() assert 42 not in l2 assert 43 not in l2 + + def test_blocked_plugin_can_be_used(self, pytestpm): + pytestpm.consider_preparse(["xyz", "-p", "no:abc", "-p", "abc"]) + + assert pytestpm.has_plugin("abc") + assert not pytestpm.is_blocked("abc") + assert not pytestpm.is_blocked("pytest_abc")