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

View File

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

View File

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

View File

@ -9,6 +9,7 @@ import types
import pytest
from _pytest.config import PytestPluginManager
from _pytest.config.exceptions import UsageError
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import Session
@ -314,6 +315,9 @@ class TestPytestPluginManagerBootstrapming(object):
# Handles -p without following arg (when used without argparse).
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):
pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
l1 = pytestpm.get_plugins()