Split out list of essential plugins

Fixes https://github.com/pytest-dev/pytest/issues/4976.
This commit is contained in:
Daniel Hahler 2019-03-27 19:10:33 +01:00
parent 407d74be27
commit 8c734dfc2f
4 changed files with 24 additions and 19 deletions

View File

@ -112,13 +112,18 @@ def directory_arg(path, optname):
return path return path
default_plugins = ( # Plugins that cannot be disabled via "-p no:X" currently.
essential_plugins = (
"mark", "mark",
"main", "main",
"terminal",
"runner", "runner",
"python", "python",
"fixtures", "fixtures",
"helpconfig", # Provides -p.
)
default_plugins = essential_plugins + (
"terminal", # Has essential options, but xdist uses -pno:terminal.
"debugging", "debugging",
"unittest", "unittest",
"capture", "capture",
@ -127,7 +132,6 @@ default_plugins = (
"monkeypatch", "monkeypatch",
"recwarn", "recwarn",
"pastebin", "pastebin",
"helpconfig",
"nose", "nose",
"assertion", "assertion",
"junitxml", "junitxml",
@ -143,7 +147,6 @@ default_plugins = (
"reports", "reports",
) )
builtin_plugins = set(default_plugins) builtin_plugins = set(default_plugins)
builtin_plugins.add("pytester") builtin_plugins.add("pytester")
@ -496,6 +499,9 @@ class PytestPluginManager(PluginManager):
def consider_pluginarg(self, arg): def consider_pluginarg(self, arg):
if arg.startswith("no:"): if arg.startswith("no:"):
name = arg[3:] name = arg[3:]
if name in essential_plugins:
raise UsageError("plugin %s cannot be disabled" % name)
# PR #4304 : remove stepwise if cacheprovider is blocked # PR #4304 : remove stepwise if cacheprovider is blocked
if name == "cacheprovider": if name == "cacheprovider":
self.set_blocked("stepwise") self.set_blocked("stepwise")

View File

@ -173,6 +173,7 @@ def getreportopt(config):
return reportopts return reportopts
@pytest.hookimpl(trylast=True) # after _pytest.runner
def pytest_report_teststatus(report): def pytest_report_teststatus(report):
if report.passed: if report.passed:
letter = "." letter = "."

View File

@ -1205,20 +1205,12 @@ def test_config_does_not_load_blocked_plugin_from_args(testdir):
[ [
x x
for x in _pytest.config.default_plugins for x in _pytest.config.default_plugins
if x if x not in _pytest.config.essential_plugins
not in [
"fixtures",
"helpconfig", # Provides -p.
"main",
"mark",
"python",
"runner",
"terminal", # works in OK case (no output), but not with failures.
]
], ],
) )
def test_config_blocked_default_plugins(testdir, plugin): def test_config_blocked_default_plugins(testdir, plugin):
if plugin == "debugging": if plugin == "debugging":
# Fixed in xdist master (after 1.27.0).
# https://github.com/pytest-dev/pytest-xdist/pull/422 # https://github.com/pytest-dev/pytest-xdist/pull/422
try: try:
import xdist # noqa: F401 import xdist # noqa: F401
@ -1230,9 +1222,11 @@ def test_config_blocked_default_plugins(testdir, plugin):
p = testdir.makepyfile("def test(): pass") p = testdir.makepyfile("def test(): pass")
result = testdir.runpytest(str(p), "-pno:%s" % plugin) result = testdir.runpytest(str(p), "-pno:%s" % plugin)
assert result.ret == EXIT_OK assert result.ret == EXIT_OK
result.stdout.fnmatch_lines(["* 1 passed in *"]) if plugin != "terminal":
result.stdout.fnmatch_lines(["* 1 passed in *"])
p = testdir.makepyfile("def test(): assert 0") if plugin != "terminal": # fails to report due to its options being used elsewhere.
result = testdir.runpytest(str(p), "-pno:%s" % plugin) p = testdir.makepyfile("def test(): assert 0")
assert result.ret == EXIT_TESTSFAILED result = testdir.runpytest(str(p), "-pno:%s" % plugin)
result.stdout.fnmatch_lines(["* 1 failed in *"]) assert result.ret == EXIT_TESTSFAILED
result.stdout.fnmatch_lines(["* 1 failed in *"])

View File

@ -9,6 +9,7 @@ import types
import pytest import pytest
from _pytest.config import PytestPluginManager from _pytest.config import PytestPluginManager
from _pytest.config.exceptions import UsageError
from _pytest.main import EXIT_NOTESTSCOLLECTED from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import Session from _pytest.main import Session
@ -314,6 +315,9 @@ class TestPytestPluginManagerBootstrapming(object):
# Handles -p without following arg (when used without argparse). # Handles -p without following arg (when used without argparse).
pytestpm.consider_preparse(["-p"]) pytestpm.consider_preparse(["-p"])
with pytest.raises(UsageError, match="^plugin main cannot be disabled$"):
pytestpm.consider_preparse(["-p", "no:main"])
def test_plugin_prevent_register(self, pytestpm): def test_plugin_prevent_register(self, pytestpm):
pytestpm.consider_preparse(["xyz", "-p", "no:abc"]) pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
l1 = pytestpm.get_plugins() l1 = pytestpm.get_plugins()