diff --git a/changelog/4957.bugfix.rst b/changelog/4957.bugfix.rst new file mode 100644 index 000000000..ade73ce22 --- /dev/null +++ b/changelog/4957.bugfix.rst @@ -0,0 +1,3 @@ +``-p no:plugin`` is handled correctly for default (internal) plugins now, e.g. with ``-p no:capture``. + +Previously they were loaded (imported) always, making e.g. the ``capfd`` fixture available. diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index c44392073..b2e4fd774 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -147,10 +147,15 @@ builtin_plugins = set(default_plugins) builtin_plugins.add("pytester") -def get_config(): +def get_config(args=None): # subsequent calls to main will create a fresh instance pluginmanager = PytestPluginManager() config = Config(pluginmanager) + + if args is not None: + # Handle any "-p no:plugin" args. + pluginmanager.consider_preparse(args) + for spec in default_plugins: pluginmanager.import_plugin(spec) return config @@ -178,7 +183,7 @@ def _prepareconfig(args=None, plugins=None): msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})" raise TypeError(msg.format(args, type(args))) - config = get_config() + config = get_config(args) pluginmanager = config.pluginmanager try: if plugins: @@ -713,7 +718,7 @@ class Config(object): @classmethod def fromdictargs(cls, option_dict, args): """ constructor useable for subprocesses. """ - config = get_config() + config = get_config(args) config.option.__dict__.update(option_dict) config.parse(args, addopts=False) for x in config.option.plugins: diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 3d46ec896..d15456ee8 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -246,7 +246,7 @@ class TerminalReporter(object): def _determine_show_progress_info(self): """Return True if we should display progress information based on the current config""" # do not show progress if we are not capturing output (#3038) - if self.config.getoption("capture") == "no": + if self.config.getoption("capture", "no") == "no": return False # do not show progress if we are showing fixture setup/teardown if self.config.getoption("setupshow"): @@ -456,8 +456,6 @@ class TerminalReporter(object): self._tw.write(msg + "\n", cyan=True) def _get_progress_information_message(self): - if self.config.getoption("capture") == "no": - return "" collected = self._session.testscollected if self.config.getini("console_output_style") == "count": if collected: diff --git a/testing/test_config.py b/testing/test_config.py index 3dd707bfa..50a40a2cb 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -15,6 +15,7 @@ from _pytest.config.findpaths import determine_setup from _pytest.config.findpaths import get_common_ancestor from _pytest.config.findpaths import getcfg from _pytest.main import EXIT_NOTESTSCOLLECTED +from _pytest.main import EXIT_TESTSFAILED from _pytest.main import EXIT_USAGEERROR @@ -1176,3 +1177,15 @@ def test_help_and_version_after_argument_error(testdir): ["*pytest*{}*imported from*".format(pytest.__version__)] ) assert result.ret == EXIT_USAGEERROR + + +def test_config_does_not_load_blocked_plugin_from_args(testdir): + """This tests that pytest's config setup handles "-p no:X".""" + p = testdir.makepyfile("def test(capfd): pass") + result = testdir.runpytest(str(p), "-pno:capture") + result.stdout.fnmatch_lines(["E fixture 'capfd' not found"]) + assert result.ret == EXIT_TESTSFAILED + + result = testdir.runpytest(str(p), "-pno:capture", "-s") + result.stderr.fnmatch_lines(["*: error: unrecognized arguments: -s"]) + assert result.ret == EXIT_USAGEERROR