Make InvocationParams.args a tuple
This avoids mutating the original list to reflect on InvocationParams, which is supposed to be an immutable snapshot of the state of pytest.main() at the moment of invocation (see pytest-dev/pytest-xdist#478).
This commit is contained in:
parent
119bf66d7a
commit
d12cdd3127
|
@ -0,0 +1,2 @@
|
||||||
|
``Config.InvocationParams.args`` is now always a ``tuple`` to better convey that it should be
|
||||||
|
immutable and avoid accidental modifications.
|
|
@ -169,7 +169,7 @@ def get_config(args=None, plugins=None):
|
||||||
config = Config(
|
config = Config(
|
||||||
pluginmanager,
|
pluginmanager,
|
||||||
invocation_params=Config.InvocationParams(
|
invocation_params=Config.InvocationParams(
|
||||||
args=args, plugins=plugins, dir=Path().resolve()
|
args=args or (), plugins=plugins, dir=Path().resolve()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ class Config:
|
||||||
|
|
||||||
Contains the following read-only attributes:
|
Contains the following read-only attributes:
|
||||||
|
|
||||||
* ``args``: list of command-line arguments as passed to ``pytest.main()``.
|
* ``args``: tuple of command-line arguments as passed to ``pytest.main()``.
|
||||||
* ``plugins``: list of extra plugins, might be None.
|
* ``plugins``: list of extra plugins, might be None.
|
||||||
* ``dir``: directory where ``pytest.main()`` was invoked from.
|
* ``dir``: directory where ``pytest.main()`` was invoked from.
|
||||||
"""
|
"""
|
||||||
|
@ -667,13 +667,13 @@ class Config:
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Currently the environment variable PYTEST_ADDOPTS is also handled by
|
Note that the environment variable ``PYTEST_ADDOPTS`` and the ``addopts``
|
||||||
pytest implicitly, not being part of the invocation.
|
ini option are handled by pytest, not being included in the ``args`` attribute.
|
||||||
|
|
||||||
Plugins accessing ``InvocationParams`` must be aware of that.
|
Plugins accessing ``InvocationParams`` must be aware of that.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
args = attr.ib()
|
args = attr.ib(converter=tuple)
|
||||||
plugins = attr.ib()
|
plugins = attr.ib()
|
||||||
dir = attr.ib(type=Path)
|
dir = attr.ib(type=Path)
|
||||||
|
|
||||||
|
@ -938,7 +938,6 @@ class Config:
|
||||||
assert not hasattr(
|
assert not hasattr(
|
||||||
self, "args"
|
self, "args"
|
||||||
), "can only parse cmdline args at most once per Config object"
|
), "can only parse cmdline args at most once per Config object"
|
||||||
assert self.invocation_params.args == args
|
|
||||||
self.hook.pytest_addhooks.call_historic(
|
self.hook.pytest_addhooks.call_historic(
|
||||||
kwargs=dict(pluginmanager=self.pluginmanager)
|
kwargs=dict(pluginmanager=self.pluginmanager)
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import _pytest._code
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.compat import importlib_metadata
|
from _pytest.compat import importlib_metadata
|
||||||
from _pytest.config import _iter_rewritable_modules
|
from _pytest.config import _iter_rewritable_modules
|
||||||
|
from _pytest.config import Config
|
||||||
from _pytest.config.exceptions import UsageError
|
from _pytest.config.exceptions import UsageError
|
||||||
from _pytest.config.findpaths import determine_setup
|
from _pytest.config.findpaths import determine_setup
|
||||||
from _pytest.config.findpaths import get_common_ancestor
|
from _pytest.config.findpaths import get_common_ancestor
|
||||||
|
@ -456,7 +457,7 @@ class TestConfigFromdictargs:
|
||||||
|
|
||||||
config = Config.fromdictargs(option_dict, args)
|
config = Config.fromdictargs(option_dict, args)
|
||||||
assert config.args == ["a", "b"]
|
assert config.args == ["a", "b"]
|
||||||
assert config.invocation_params.args == args
|
assert config.invocation_params.args == tuple(args)
|
||||||
assert config.option.verbose == 4
|
assert config.option.verbose == 4
|
||||||
assert config.option.capture == "no"
|
assert config.option.capture == "no"
|
||||||
|
|
||||||
|
@ -1235,7 +1236,7 @@ def test_invocation_args(testdir):
|
||||||
call = calls[0]
|
call = calls[0]
|
||||||
config = call.item.config
|
config = call.item.config
|
||||||
|
|
||||||
assert config.invocation_params.args == [p, "-v"]
|
assert config.invocation_params.args == (p, "-v")
|
||||||
assert config.invocation_params.dir == Path(str(testdir.tmpdir))
|
assert config.invocation_params.dir == Path(str(testdir.tmpdir))
|
||||||
|
|
||||||
plugins = config.invocation_params.plugins
|
plugins = config.invocation_params.plugins
|
||||||
|
@ -1243,6 +1244,10 @@ def test_invocation_args(testdir):
|
||||||
assert plugins[0] is plugin
|
assert plugins[0] is plugin
|
||||||
assert type(plugins[1]).__name__ == "Collect" # installed by testdir.inline_run()
|
assert type(plugins[1]).__name__ == "Collect" # installed by testdir.inline_run()
|
||||||
|
|
||||||
|
# args cannot be None
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
Config.InvocationParams(args=None, plugins=None, dir=Path())
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"plugin",
|
"plugin",
|
||||||
|
|
Loading…
Reference in New Issue