From 017efa1a9feb242251faa6773105bdb45590bc8d Mon Sep 17 00:00:00 2001 From: Amethyst Reese Date: Sun, 2 Feb 2025 16:44:51 -0800 Subject: [PATCH] Better error message when pyproject.toml is broken Fixes: #135 --- pyproject.toml | 10 +++++----- thx/config.py | 5 ++++- thx/tests/config.py | 10 ++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1322e56..61a79cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,21 +32,21 @@ dependencies = [ dev = [ "aioitertools==v0.11.0", "click==8.1.7", - "packaging==24.2", + "packaging==24.0", "rich==13.7.1", "tomli==2.0.1", "trailrunner==1.4.0", "typing_extensions == 4.12.0", "watchdog==4.0.1", - "attribution==1.8.0", + "attribution==1.7.1", "black==24.4.2", "build>=1.2", - "coverage==7.6.10", + "coverage==7.5.3", "flit==3.9.0", - "flake8==7.1.1", + "flake8==7.0.0", "mypy==1.10.0", - "ufmt==2.8.0", + "ufmt==2.6.0", "usort==1.0.8.post1", ] docs = [ diff --git a/thx/config.py b/thx/config.py index 7f4cacd..13e328b 100644 --- a/thx/config.py +++ b/thx/config.py @@ -132,7 +132,10 @@ def load_config(path: Optional[Path] = None) -> Config: return Config(root=path) content = pyproject.read_text() - data = tomli.loads(content).get("tool", {}).get("thx", {}) + try: + data = tomli.loads(content).get("tool", {}).get("thx", {}) + except tomli.TOMLDecodeError as error: + raise ConfigError(f"failure parsing pyproject.toml: {str(error)}") from error default: List[str] = ensure_listish(data.pop("default", None), "tool.thx.default") jobs: List[Job] = parse_jobs(data.pop("jobs", {})) diff --git a/thx/tests/config.py b/thx/tests/config.py index d98ba05..b354d87 100644 --- a/thx/tests/config.py +++ b/thx/tests/config.py @@ -72,6 +72,16 @@ def test_no_config(self) -> None: result = load_config(td) self.assertEqual(expected, result) + def test_broken_config(self) -> None: + with fake_pyproject( + """ + [tool.black] + line_length = 37[] # should cause parse failure + """ + ) as td: + with self.assertRaisesRegex(ConfigError, "failure parsing pyproject.toml"): + load_config(td) + def test_empty_config(self) -> None: with fake_pyproject( """