From 415899d428650d3eb85a339a4811ee75bd2be43d Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 20 Mar 2019 02:25:35 +0100 Subject: [PATCH] config: handle `-p no:plugin` with default plugins `-p no:capture` should not load its fixtures in the first place. --- changelog/4957.bugfix.rst | 3 +++ src/_pytest/config/__init__.py | 11 ++++++++--- testing/test_config.py | 13 +++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 changelog/4957.bugfix.rst 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/testing/test_config.py b/testing/test_config.py index 3dd707bfa..8c2e7a49e 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", "--tb=native") + 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