Skip to content

Commit adb7799

Browse files
committed
fix: provide clear messaging about config file loading
Fix bug where tox is silently ignoring loading pyproject.toml files that failed be loaded by tomllint and falling back to other config. - if pyproject.toml does not have one of the two expected sections it will be logged, so it would be visible with `-v` - make pyproject.toml failure to load a fatal error with clear information about cause - keeps ignoring missing pyproject.toml files as expected With these, users of tox will not be surprised when they break the config file by mistake, like adding a duplicate section.
1 parent 7d4cb4e commit adb7799

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

docs/changelog/3567.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Makes the error message more clear when pyproject.toml file cannot be loaded
2+
or is missing expected keys.

src/tox/config/source/discover.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
from typing import TYPE_CHECKING
77

8+
from tox.config.types import MissingRequiredConfigKeyError
89
from tox.report import HandledError
910

1011
from .legacy_toml import LegacyToml
@@ -59,21 +60,32 @@ def _locate_source() -> Source | None:
5960
for base in chain([folder], folder.parents):
6061
for src_type in SOURCE_TYPES:
6162
candidate: Path = base / src_type.FILENAME
62-
try:
63-
return src_type(candidate)
64-
except ValueError:
65-
pass
63+
if candidate.exists():
64+
try:
65+
return src_type(candidate)
66+
except MissingRequiredConfigKeyError as e:
67+
msg = f"{src_type.__name__} skipped loading {candidate.resolve()} due to {e}"
68+
logging.info(msg)
69+
except ValueError as e:
70+
msg = f"{src_type.__name__} failed loading {candidate.resolve()} due to {e}"
71+
raise HandledError(msg) from e
6672
return None
6773

6874

6975
def _load_exact_source(config_file: Path) -> Source:
7076
# if the filename matches to the letter some config file name do not fallback to other source types
77+
if not config_file.exists():
78+
msg = f"config file {config_file} does not exist"
79+
raise HandledError(msg)
7180
exact_match = [s for s in SOURCE_TYPES if config_file.name == s.FILENAME] # pragma: no cover
7281
for src_type in exact_match or SOURCE_TYPES: # pragma: no branch
7382
try:
7483
return src_type(config_file)
75-
except ValueError: # noqa: PERF203
84+
except MissingRequiredConfigKeyError: # noqa: PERF203
7685
pass
86+
except ValueError as e:
87+
msg = f"{src_type.__name__} failed loading {config_file.resolve()} due to {e}"
88+
raise HandledError(msg) from e
7789
msg = f"could not recognize config file {config_file}"
7890
raise HandledError(msg)
7991

@@ -88,7 +100,7 @@ def _create_default_source(root_dir: Path | None) -> Source:
88100
else: # if not set use where we find pyproject.toml in the tree or cwd
89101
empty = root_dir
90102
names = " or ".join({i.FILENAME: None for i in SOURCE_TYPES})
91-
logging.warning("No %s found, assuming empty tox.ini at %s", names, empty)
103+
logging.warning("No loadable %s found, assuming empty tox.ini at %s", names, empty)
92104
return ToxIni(empty / "tox.ini", content="")
93105

94106

src/tox/config/source/legacy_toml.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import sys
44

5+
from tox.config.types import MissingRequiredConfigKeyError
6+
57
if sys.version_info >= (3, 11): # pragma: no cover (py311+)
68
import tomllib
79
else: # pragma: no cover (py311+)
@@ -27,7 +29,8 @@ def __init__(self, path: Path) -> None:
2729
try:
2830
content = toml_content["tool"]["tox"]["legacy_tox_ini"]
2931
except KeyError as exc:
30-
raise ValueError(path) from exc
32+
msg = f"`tool.tox.legacy_tox_ini` missing from {path}"
33+
raise MissingRequiredConfigKeyError(msg) from exc
3134
super().__init__(path, content=content)
3235

3336

src/tox/config/types.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ class CircularChainError(ValueError):
1010
"""circular chain in config"""
1111

1212

13+
class MissingRequiredConfigKeyError(ValueError):
14+
"""missing required config key
15+
16+
Used by the two toml loaders in order to identify if config keys are present.
17+
"""
18+
19+
1320
class Command: # noqa: PLW1641
1421
"""A command to execute."""
1522

0 commit comments

Comments
 (0)