Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Config.invocation_params #5564

Merged
merged 4 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/5564.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
New ``Config.invocation_args`` and ``Config.invocation_plugins`` attributes.

nicoddemus marked this conversation as resolved.
Show resolved Hide resolved
These attributes can be used by plugins to access the unchanged arguments passed to ``pytest.main()``.
26 changes: 20 additions & 6 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def main(args=None, plugins=None):
tw.line(line.rstrip(), red=True)
return 4
else:
config.invocation_args = args
config.invocation_plugins = plugins
try:
return config.hook.pytest_cmdline_main(config=config)
finally:
Expand Down Expand Up @@ -608,20 +610,33 @@ def _iter_rewritable_modules(package_files):


class Config:
""" access to configuration values, pluginmanager and plugin hooks. """
"""
Access to configuration values, pluginmanager and plugin hooks.

:ivar PytestPluginManager pluginmanager: the plugin manager handles plugin registration and hook invocation.

:ivar argparse.Namespace option: access to command line option as attributes.

:ivar invocation_args: list of command-line arguments as passed to pytest.main()

:ivar invocation_plugins: list of extra plugins passed to pytest.main(), might be None

:ivar py.path.local invocation_dir: directory where pytest.main() was invoked from
"""

def __init__(self, pluginmanager):
#: access to command line option as attributes.
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
self.option = argparse.Namespace()
from .argparsing import Parser, FILE_OR_DIR

self.option = argparse.Namespace()
self.invocation_args = None
nicoddemus marked this conversation as resolved.
Show resolved Hide resolved
self.invocation_plugins = None
self.invocation_dir = py.path.local()

_a = FILE_OR_DIR
self._parser = Parser(
usage="%(prog)s [options] [{}] [{}] [...]".format(_a, _a),
processopt=self._processopt,
)
#: a pluginmanager instance
self.pluginmanager = pluginmanager
self.trace = self.pluginmanager.trace.root.get("config")
self.hook = self.pluginmanager.hook
Expand All @@ -631,7 +646,6 @@ def __init__(self, pluginmanager):
self._cleanup = []
self.pluginmanager.register(self, "pytestconfig")
self._configured = False
self.invocation_dir = py.path.local()
self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))

def add_cleanup(self, func):
Expand Down
22 changes: 22 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,28 @@ def test_config_does_not_load_blocked_plugin_from_args(testdir):
assert result.ret == ExitCode.USAGE_ERROR


def test_invocation_arguments(testdir):
"""Ensure that Config.invocation_* arguments are correctly defined"""

class DummyPlugin:
pass

p = testdir.makepyfile("def test(): pass")
plugin = DummyPlugin()
rec = testdir.inline_run(p, "-v", plugins=[plugin])
calls = rec.getcalls("pytest_runtest_protocol")
assert len(calls) == 1
call = calls[0]
config = call.item.config

assert config.invocation_args == [p, "-v"]

plugins = config.invocation_plugins
assert len(plugins) == 2
assert plugins[0] is plugin
assert type(plugins[1]).__name__ == "Collect" # installed by testdir.inline_run()


@pytest.mark.parametrize(
"plugin",
[
Expand Down