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>`,
|
||||
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
|
||||
input_values = shlex.split(value) if isinstance(value, str) else value
|
||||
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":
|
||||
return shlex.split(value) if isinstance(value, str) else value
|
||||
elif type == "linelist":
|
||||
|
|
|
@ -163,22 +163,35 @@ class Parser:
|
|||
name: str,
|
||||
help: str,
|
||||
type: Optional[
|
||||
"Literal['string', 'pathlist', 'args', 'linelist', 'bool']"
|
||||
"Literal['string', 'paths', 'pathlist', 'args', 'linelist', 'bool']"
|
||||
] = None,
|
||||
default=None,
|
||||
) -> None:
|
||||
"""Register an ini-file option.
|
||||
|
||||
:name: Name of the ini-variable.
|
||||
:type: Type of the variable, can be ``string``, ``pathlist``, ``args``,
|
||||
``linelist`` or ``bool``. Defaults to ``string`` if ``None`` or
|
||||
not passed.
|
||||
:default: Default value if no ini-file option exists but is queried.
|
||||
:name:
|
||||
Name of the ini-variable.
|
||||
:type:
|
||||
Type of the variable. Can be:
|
||||
|
||||
* ``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
|
||||
: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._ininames.append(name)
|
||||
|
||||
|
|
|
@ -595,14 +595,14 @@ class TestConfigAPI:
|
|||
def test_getconftest_pathlist(self, pytester: Pytester, tmp_path: Path) -> None:
|
||||
somepath = tmp_path.joinpath("x", "y", "z")
|
||||
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)
|
||||
assert (
|
||||
config._getconftest_pathlist("notexist", path=tmp_path, rootpath=tmp_path)
|
||||
is None
|
||||
)
|
||||
pl = (
|
||||
config._getconftest_pathlist("pathlist", path=tmp_path, rootpath=tmp_path)
|
||||
config._getconftest_pathlist("mylist", path=tmp_path, rootpath=tmp_path)
|
||||
or []
|
||||
)
|
||||
print(pl)
|
||||
|
@ -634,41 +634,37 @@ class TestConfigAPI:
|
|||
assert val == "hello"
|
||||
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(
|
||||
"""
|
||||
f"""
|
||||
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")
|
||||
"""
|
||||
)
|
||||
|
||||
def test_addini_pathlist_ini_files(self, pytester: Pytester) -> None:
|
||||
self.make_conftest_for_pathlist(pytester)
|
||||
p = pytester.makeini(
|
||||
if config_type == "ini":
|
||||
inipath = pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
paths=hello world/sub.py
|
||||
"""
|
||||
[pytest]
|
||||
paths=hello world/sub.py
|
||||
"""
|
||||
)
|
||||
self.check_config_pathlist(pytester, p)
|
||||
|
||||
def test_addini_pathlist_pyproject_toml(self, pytester: Pytester) -> None:
|
||||
self.make_conftest_for_pathlist(pytester)
|
||||
p = pytester.makepyprojecttoml(
|
||||
)
|
||||
elif config_type == "pyproject":
|
||||
inipath = pytester.makepyprojecttoml(
|
||||
"""
|
||||
[tool.pytest.ini_options]
|
||||
paths=["hello", "world/sub.py"]
|
||||
"""
|
||||
[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()
|
||||
values = config.getini("paths")
|
||||
assert len(values) == 2
|
||||
assert values[0] == config_path.parent.joinpath("hello")
|
||||
assert values[1] == config_path.parent.joinpath("world/sub.py")
|
||||
assert values[0] == inipath.parent.joinpath("hello")
|
||||
assert values[1] == inipath.parent.joinpath("world/sub.py")
|
||||
pytest.raises(ValueError, config.getini, "other")
|
||||
|
||||
def make_conftest_for_args(self, pytester: Pytester) -> None:
|
||||
|
@ -1519,11 +1515,12 @@ class TestOverrideIniArgs:
|
|||
assert result.ret == 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(
|
||||
"""
|
||||
f"""
|
||||
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(
|
||||
"""
|
||||
|
@ -1531,12 +1528,16 @@ class TestOverrideIniArgs:
|
|||
paths=blah.py"""
|
||||
)
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pathlist(pytestconfig):
|
||||
rf"""
|
||||
def test_overriden(pytestconfig):
|
||||
config_paths = pytestconfig.getini("paths")
|
||||
print(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(
|
||||
"--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s"
|
||||
|
|
Loading…
Reference in New Issue