diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py index 8ebb19de43..994c5c4a66 100644 --- a/codespell_lib/_codespell.py +++ b/codespell_lib/_codespell.py @@ -712,10 +712,12 @@ def convert_arg_line_to_args(self, arg_line: str) -> list[str]: if tomllib is not None: for toml_file in toml_files: with open(toml_file, "rb") as f: - data = tomllib.load(f).get("tool", {}) - if "codespell" in data: - data["codespell"] = _toml_to_parseconfig(data["codespell"]) - config.read_dict(data) + data = tomllib.load(f).get("tool", {}).get("codespell") + if data is not None: + if not isinstance(data, dict): + msg = f"{toml_file}: [tool.codespell] must be a table" + raise configparser.Error(msg) + config.read_dict({"codespell": _toml_to_parseconfig(data)}) # Collect which config files are going to be used used_cfg_files = [] diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py index d1c66a18a5..930f09f14a 100644 --- a/codespell_lib/tests/test_basic.py +++ b/codespell_lib/tests/test_basic.py @@ -1428,7 +1428,10 @@ def test_ill_formed_ini_config_file( assert "ill-formed config file" in stderr -@pytest.mark.parametrize("kind", ["cfg", "cfg_multiline", "toml", "toml_list"]) +@pytest.mark.parametrize( + "kind", + ["cfg", "cfg_multiline", "toml", "toml_list", "toml_sibling_array"], +) def test_config_toml( tmp_path: Path, capsys: pytest.CaptureFixture[str], @@ -1482,13 +1485,23 @@ def test_config_toml( check-filenames = false count = true """ - else: - assert kind == "toml_list" + elif kind == "toml_list": text = """\ [tool.codespell] skip = ['bad.txt', 'whatever.txt'] check-filenames = false count = true +""" + else: + assert kind == "toml_sibling_array" + text = """\ +[tool.codespell] +skip = 'bad.txt,whatever.txt' +check-filenames = false +count = true + +[[tool.dynamic-metadata]] +provider = 'scikit_build_core.metadata.version' """ tomlfile.write_text(text) @@ -1514,6 +1527,22 @@ def test_config_toml( assert "abandonned.txt" not in stdout +def test_config_toml_codespell_array( + tmp_path: Path, + capsys: pytest.CaptureFixture[str], +) -> None: + if sys.version_info < (3, 11): + pytest.importorskip("tomli") + tomlfile = tmp_path / "pyproject.toml" + tomlfile.write_text("[[tool.codespell]]\nskip = 'bad.txt'\n") + + result = cs.main("--toml", tomlfile, std=True) + assert isinstance(result, tuple) + code, _, stderr = result + assert code == EX_CONFIG + assert "[tool.codespell] must be a table" in stderr + + @contextlib.contextmanager def FakeStdin(text: str) -> Generator[None, None, None]: oldin = sys.stdin