Skip to content

Commit

Permalink
Improve pyproject.toml validation messages (#3487)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Aug 6, 2022
2 parents ef6fd97 + 7119ff1 commit 33fe15c
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 22 deletions.
2 changes: 2 additions & 0 deletions changelog.d/3487.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Modified ``pyproject.toml`` validation exception handling to
make relevant debugging information easier to spot.
12 changes: 8 additions & 4 deletions setuptools/config/pyprojecttoml.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ def validate(config: dict, filepath: _Path) -> bool:
try:
return validator.validate(config)
except validator.ValidationError as ex:
_logger.error(f"configuration error: {ex.summary}") # type: ignore
_logger.debug(ex.details) # type: ignore
error = ValueError(f"invalid pyproject.toml config: {ex.name}") # type: ignore
raise error from None
summary = f"configuration error: {ex.summary}"
if ex.name.strip("`") != "project":
# Probably it is just a field missing/misnamed, not worthy the verbosity...
_logger.debug(summary)
_logger.debug(ex.details)

error = f"invalid pyproject.toml config: {ex.name}."
raise ValueError(f"{error}\n{summary}") from None


def apply_configuration(
Expand Down
23 changes: 5 additions & 18 deletions setuptools/tests/config/test_pyprojecttoml.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import logging
import re
from configparser import ConfigParser
from inspect import cleandoc
Expand Down Expand Up @@ -307,7 +306,7 @@ def test_ignore_unrelated_config(tmp_path, example):


@pytest.mark.parametrize(
"example, error_msg, value_shown_in_debug",
"example, error_msg",
[
(
"""
Expand All @@ -316,30 +315,18 @@ def test_ignore_unrelated_config(tmp_path, example):
version = "1.2"
requires = ['pywin32; platform_system=="Windows"' ]
""",
"configuration error: `project` must not contain {'requires'} properties",
'"requires": ["pywin32; platform_system==\\"Windows\\""]',
"configuration error: .project. must not contain ..requires.. properties",
),
],
)
def test_invalid_example(tmp_path, caplog, example, error_msg, value_shown_in_debug):
caplog.set_level(logging.DEBUG)
def test_invalid_example(tmp_path, example, error_msg):
pyproject = tmp_path / "pyproject.toml"
pyproject.write_text(cleandoc(example))

caplog.clear()
with pytest.raises(ValueError, match="invalid pyproject.toml"):
pattern = re.compile(f"invalid pyproject.toml.*{error_msg}.*", re.M | re.S)
with pytest.raises(ValueError, match=pattern):
read_configuration(pyproject)

# Make sure the logs give guidance to the user
error_log = caplog.record_tuples[0]
assert error_log[1] == logging.ERROR
assert error_msg in error_log[2]

debug_log = caplog.record_tuples[1]
assert debug_log[1] == logging.DEBUG
debug_msg = "".join(line.strip() for line in debug_log[2].splitlines())
assert value_shown_in_debug in debug_msg


@pytest.mark.parametrize("config", ("", "[tool.something]\nvalue = 42"))
def test_empty(tmp_path, config):
Expand Down

0 comments on commit 33fe15c

Please sign in to comment.