argparsing: support parser.addini(type="paths") which returns pathlib.Paths
This commit is contained in:
parent
634312b14a
commit
113a860a1f
|
@ -1,2 +1,7 @@
|
||||||
Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
|
Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
|
||||||
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
|
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
|
||||||
|
|
||||||
|
Added a ``paths`` type to :meth:`parser.addini() <_pytest.config.argparsing.Parser.addini>`,
|
||||||
|
as in ``parser.addini("mypaths", "my paths", type="paths")``,
|
||||||
|
which is similar to the existing ``pathlist``,
|
||||||
|
but returns a list of :class:`pathlib.Path` instead of legacy ``py.path.local``.
|
||||||
|
|
|
@ -1427,6 +1427,12 @@ class Config:
|
||||||
dp = self.inipath.parent
|
dp = self.inipath.parent
|
||||||
input_values = shlex.split(value) if isinstance(value, str) else value
|
input_values = shlex.split(value) if isinstance(value, str) else value
|
||||||
return [legacy_path(str(dp / x)) for x in input_values]
|
return [legacy_path(str(dp / x)) for x in input_values]
|
||||||
|
elif type == "paths":
|
||||||
|
# TODO: This assert is probably not valid in all cases.
|
||||||
|
assert self.inipath is not None
|
||||||
|
dp = self.inipath.parent
|
||||||
|
input_values = shlex.split(value) if isinstance(value, str) else value
|
||||||
|
return [dp / x for x in input_values]
|
||||||
elif type == "args":
|
elif type == "args":
|
||||||
return shlex.split(value) if isinstance(value, str) else value
|
return shlex.split(value) if isinstance(value, str) else value
|
||||||
elif type == "linelist":
|
elif type == "linelist":
|
||||||
|
|
|
@ -163,22 +163,35 @@ class Parser:
|
||||||
name: str,
|
name: str,
|
||||||
help: str,
|
help: str,
|
||||||
type: Optional[
|
type: Optional[
|
||||||
"Literal['string', 'pathlist', 'args', 'linelist', 'bool']"
|
"Literal['string', 'paths', 'pathlist', 'args', 'linelist', 'bool']"
|
||||||
] = None,
|
] = None,
|
||||||
default=None,
|
default=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register an ini-file option.
|
"""Register an ini-file option.
|
||||||
|
|
||||||
:name: Name of the ini-variable.
|
:name:
|
||||||
:type: Type of the variable, can be ``string``, ``pathlist``, ``args``,
|
Name of the ini-variable.
|
||||||
``linelist`` or ``bool``. Defaults to ``string`` if ``None`` or
|
:type:
|
||||||
not passed.
|
Type of the variable. Can be:
|
||||||
:default: Default value if no ini-file option exists but is queried.
|
|
||||||
|
* ``string``: a string
|
||||||
|
* ``bool``: a boolean
|
||||||
|
* ``args``: a list of strings, separated as in a shell
|
||||||
|
* ``linelist``: a list of strings, separated by line breaks
|
||||||
|
* ``paths``: a list of :class:`pathlib.Path`, separated as in a shell
|
||||||
|
* ``pathlist``: a list of ``py.path``, separated as in a shell
|
||||||
|
|
||||||
|
.. versionadded:: 6.3
|
||||||
|
The ``paths`` variable type.
|
||||||
|
|
||||||
|
Defaults to ``string`` if ``None`` or not passed.
|
||||||
|
:default:
|
||||||
|
Default value if no ini-file option exists but is queried.
|
||||||
|
|
||||||
The value of ini-variables can be retrieved via a call to
|
The value of ini-variables can be retrieved via a call to
|
||||||
:py:func:`config.getini(name) <_pytest.config.Config.getini>`.
|
:py:func:`config.getini(name) <_pytest.config.Config.getini>`.
|
||||||
"""
|
"""
|
||||||
assert type in (None, "string", "pathlist", "args", "linelist", "bool")
|
assert type in (None, "string", "paths", "pathlist", "args", "linelist", "bool")
|
||||||
self._inidict[name] = (help, type, default)
|
self._inidict[name] = (help, type, default)
|
||||||
self._ininames.append(name)
|
self._ininames.append(name)
|
||||||
|
|
||||||
|
|
|
@ -595,14 +595,14 @@ class TestConfigAPI:
|
||||||
def test_getconftest_pathlist(self, pytester: Pytester, tmp_path: Path) -> None:
|
def test_getconftest_pathlist(self, pytester: Pytester, tmp_path: Path) -> None:
|
||||||
somepath = tmp_path.joinpath("x", "y", "z")
|
somepath = tmp_path.joinpath("x", "y", "z")
|
||||||
p = tmp_path.joinpath("conftest.py")
|
p = tmp_path.joinpath("conftest.py")
|
||||||
p.write_text(f"pathlist = ['.', {str(somepath)!r}]")
|
p.write_text(f"mylist = {['.', os.fspath(somepath)]}")
|
||||||
config = pytester.parseconfigure(p)
|
config = pytester.parseconfigure(p)
|
||||||
assert (
|
assert (
|
||||||
config._getconftest_pathlist("notexist", path=tmp_path, rootpath=tmp_path)
|
config._getconftest_pathlist("notexist", path=tmp_path, rootpath=tmp_path)
|
||||||
is None
|
is None
|
||||||
)
|
)
|
||||||
pl = (
|
pl = (
|
||||||
config._getconftest_pathlist("pathlist", path=tmp_path, rootpath=tmp_path)
|
config._getconftest_pathlist("mylist", path=tmp_path, rootpath=tmp_path)
|
||||||
or []
|
or []
|
||||||
)
|
)
|
||||||
print(pl)
|
print(pl)
|
||||||
|
@ -634,41 +634,37 @@ class TestConfigAPI:
|
||||||
assert val == "hello"
|
assert val == "hello"
|
||||||
pytest.raises(ValueError, config.getini, "other")
|
pytest.raises(ValueError, config.getini, "other")
|
||||||
|
|
||||||
def make_conftest_for_pathlist(self, pytester: Pytester) -> None:
|
@pytest.mark.parametrize("config_type", ["ini", "pyproject"])
|
||||||
|
@pytest.mark.parametrize("ini_type", ["paths", "pathlist"])
|
||||||
|
def test_addini_paths(
|
||||||
|
self, pytester: Pytester, config_type: str, ini_type: str
|
||||||
|
) -> None:
|
||||||
pytester.makeconftest(
|
pytester.makeconftest(
|
||||||
"""
|
f"""
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
parser.addini("paths", "my new ini value", type="pathlist")
|
parser.addini("paths", "my new ini value", type="{ini_type}")
|
||||||
parser.addini("abc", "abc value")
|
parser.addini("abc", "abc value")
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
if config_type == "ini":
|
||||||
def test_addini_pathlist_ini_files(self, pytester: Pytester) -> None:
|
inipath = pytester.makeini(
|
||||||
self.make_conftest_for_pathlist(pytester)
|
"""
|
||||||
p = pytester.makeini(
|
[pytest]
|
||||||
|
paths=hello world/sub.py
|
||||||
"""
|
"""
|
||||||
[pytest]
|
)
|
||||||
paths=hello world/sub.py
|
elif config_type == "pyproject":
|
||||||
"""
|
inipath = pytester.makepyprojecttoml(
|
||||||
)
|
"""
|
||||||
self.check_config_pathlist(pytester, p)
|
[tool.pytest.ini_options]
|
||||||
|
paths=["hello", "world/sub.py"]
|
||||||
def test_addini_pathlist_pyproject_toml(self, pytester: Pytester) -> None:
|
|
||||||
self.make_conftest_for_pathlist(pytester)
|
|
||||||
p = pytester.makepyprojecttoml(
|
|
||||||
"""
|
"""
|
||||||
[tool.pytest.ini_options]
|
)
|
||||||
paths=["hello", "world/sub.py"]
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
self.check_config_pathlist(pytester, p)
|
|
||||||
|
|
||||||
def check_config_pathlist(self, pytester: Pytester, config_path: Path) -> None:
|
|
||||||
config = pytester.parseconfig()
|
config = pytester.parseconfig()
|
||||||
values = config.getini("paths")
|
values = config.getini("paths")
|
||||||
assert len(values) == 2
|
assert len(values) == 2
|
||||||
assert values[0] == config_path.parent.joinpath("hello")
|
assert values[0] == inipath.parent.joinpath("hello")
|
||||||
assert values[1] == config_path.parent.joinpath("world/sub.py")
|
assert values[1] == inipath.parent.joinpath("world/sub.py")
|
||||||
pytest.raises(ValueError, config.getini, "other")
|
pytest.raises(ValueError, config.getini, "other")
|
||||||
|
|
||||||
def make_conftest_for_args(self, pytester: Pytester) -> None:
|
def make_conftest_for_args(self, pytester: Pytester) -> None:
|
||||||
|
@ -1519,11 +1515,12 @@ class TestOverrideIniArgs:
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
result.stdout.fnmatch_lines(["custom_option:3.0"])
|
result.stdout.fnmatch_lines(["custom_option:3.0"])
|
||||||
|
|
||||||
def test_override_ini_pathlist(self, pytester: Pytester) -> None:
|
@pytest.mark.parametrize("ini_type", ["paths", "pathlist"])
|
||||||
|
def test_override_ini_paths(self, pytester: Pytester, ini_type: str) -> None:
|
||||||
pytester.makeconftest(
|
pytester.makeconftest(
|
||||||
"""
|
f"""
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
parser.addini("paths", "my new ini value", type="pathlist")"""
|
parser.addini("paths", "my new ini value", type="{ini_type}")"""
|
||||||
)
|
)
|
||||||
pytester.makeini(
|
pytester.makeini(
|
||||||
"""
|
"""
|
||||||
|
@ -1531,12 +1528,16 @@ class TestOverrideIniArgs:
|
||||||
paths=blah.py"""
|
paths=blah.py"""
|
||||||
)
|
)
|
||||||
pytester.makepyfile(
|
pytester.makepyfile(
|
||||||
"""
|
rf"""
|
||||||
def test_pathlist(pytestconfig):
|
def test_overriden(pytestconfig):
|
||||||
config_paths = pytestconfig.getini("paths")
|
config_paths = pytestconfig.getini("paths")
|
||||||
print(config_paths)
|
print(config_paths)
|
||||||
for cpf in config_paths:
|
for cpf in config_paths:
|
||||||
print('\\nuser_path:%s' % cpf.basename)"""
|
if "{ini_type}" == "pathlist":
|
||||||
|
print('\nuser_path:%s' % cpf.basename)
|
||||||
|
else:
|
||||||
|
print('\nuser_path:%s' % cpf.name)
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
result = pytester.runpytest(
|
result = pytester.runpytest(
|
||||||
"--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s"
|
"--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s"
|
||||||
|
|
Loading…
Reference in New Issue