Consider pyproject.toml files for config if no other config files were found
Today `pyproject.toml` is the standard for declaring a Python project root, so seems reasonable to consider it for the ini configuration (and specially `rootdir`) in case we do not find other suitable candidates. Related to #11311
This commit is contained in:
parent
7690a0ddf1
commit
b5999191aa
|
@ -0,0 +1 @@
|
||||||
|
In case no other suitable candidates for configuration file are found, a ``pyproject.toml`` (even without a ``[tool.pytest.ini_options]`` table) will be considered as the configuration file and define the ``rootdir``.
|
|
@ -177,6 +177,9 @@ Files will only be matched for configuration if:
|
||||||
* ``tox.ini``: contains a ``[pytest]`` section.
|
* ``tox.ini``: contains a ``[pytest]`` section.
|
||||||
* ``setup.cfg``: contains a ``[tool:pytest]`` section.
|
* ``setup.cfg``: contains a ``[tool:pytest]`` section.
|
||||||
|
|
||||||
|
Finally, a ``pyproject.toml`` file will be considered the ``configfile`` if no other match was found, in this case
|
||||||
|
even if it does not contain a ``[tool.pytest.ini_options]`` table (this was added in ``8.1``).
|
||||||
|
|
||||||
The files are considered in the order above. Options from multiple ``configfiles`` candidates
|
The files are considered in the order above. Options from multiple ``configfiles`` candidates
|
||||||
are never merged - the first match wins.
|
are never merged - the first match wins.
|
||||||
|
|
||||||
|
|
|
@ -101,15 +101,20 @@ def locate_config(
|
||||||
args = [x for x in args if not str(x).startswith("-")]
|
args = [x for x in args if not str(x).startswith("-")]
|
||||||
if not args:
|
if not args:
|
||||||
args = [invocation_dir]
|
args = [invocation_dir]
|
||||||
|
found_pyproject_toml: Optional[Path] = None
|
||||||
for arg in args:
|
for arg in args:
|
||||||
argpath = absolutepath(arg)
|
argpath = absolutepath(arg)
|
||||||
for base in (argpath, *argpath.parents):
|
for base in (argpath, *argpath.parents):
|
||||||
for config_name in config_names:
|
for config_name in config_names:
|
||||||
p = base / config_name
|
p = base / config_name
|
||||||
if p.is_file():
|
if p.is_file():
|
||||||
|
if p.name == "pyproject.toml" and found_pyproject_toml is None:
|
||||||
|
found_pyproject_toml = p
|
||||||
ini_config = load_config_dict_from_file(p)
|
ini_config = load_config_dict_from_file(p)
|
||||||
if ini_config is not None:
|
if ini_config is not None:
|
||||||
return base, p, ini_config
|
return base, p, ini_config
|
||||||
|
if found_pyproject_toml is not None:
|
||||||
|
return found_pyproject_toml.parent, found_pyproject_toml, {}
|
||||||
return None, None, {}
|
return None, None, {}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,15 +135,45 @@ class TestParseIni:
|
||||||
assert config.getini("minversion") == "3.36"
|
assert config.getini("minversion") == "3.36"
|
||||||
|
|
||||||
def test_pyproject_toml(self, pytester: Pytester) -> None:
|
def test_pyproject_toml(self, pytester: Pytester) -> None:
|
||||||
pytester.makepyprojecttoml(
|
pyproject_toml = pytester.makepyprojecttoml(
|
||||||
"""
|
"""
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
minversion = "1.0"
|
minversion = "1.0"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
config = pytester.parseconfig()
|
config = pytester.parseconfig()
|
||||||
|
assert config.inipath == pyproject_toml
|
||||||
assert config.getini("minversion") == "1.0"
|
assert config.getini("minversion") == "1.0"
|
||||||
|
|
||||||
|
def test_empty_pyproject_toml(self, pytester: Pytester) -> None:
|
||||||
|
"""An empty pyproject.toml is considered as config if no other option is found."""
|
||||||
|
pyproject_toml = pytester.makepyprojecttoml("")
|
||||||
|
config = pytester.parseconfig()
|
||||||
|
assert config.inipath == pyproject_toml
|
||||||
|
|
||||||
|
def test_empty_pyproject_toml_found_many(self, pytester: Pytester) -> None:
|
||||||
|
"""
|
||||||
|
In case we find multiple pyproject.toml files in our search, without a [tool.pytest.ini_options]
|
||||||
|
table and without finding other candidates, the closest to where we started wins.
|
||||||
|
"""
|
||||||
|
pytester.makefile(
|
||||||
|
".toml",
|
||||||
|
**{
|
||||||
|
"pyproject": "",
|
||||||
|
"foo/pyproject": "",
|
||||||
|
"foo/bar/pyproject": "",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
config = pytester.parseconfig(pytester.path / "foo/bar")
|
||||||
|
assert config.inipath == pytester.path / "foo/bar/pyproject.toml"
|
||||||
|
|
||||||
|
def test_pytest_ini_trumps_pyproject_toml(self, pytester: Pytester) -> None:
|
||||||
|
"""An empty pyproject.toml is considered as config if no other option is found."""
|
||||||
|
pytester.makepyprojecttoml("[tool.pytest.ini_options]")
|
||||||
|
pytest_ini = pytester.makefile(".ini", pytest="")
|
||||||
|
config = pytester.parseconfig()
|
||||||
|
assert config.inipath == pytest_ini
|
||||||
|
|
||||||
def test_toxini_before_lower_pytestini(self, pytester: Pytester) -> None:
|
def test_toxini_before_lower_pytestini(self, pytester: Pytester) -> None:
|
||||||
sub = pytester.mkdir("sub")
|
sub = pytester.mkdir("sub")
|
||||||
sub.joinpath("tox.ini").write_text(
|
sub.joinpath("tox.ini").write_text(
|
||||||
|
|
Loading…
Reference in New Issue