Repository: codespell-project/codespell

Issue:
Docs request: how to put `check-filenames` and `ignore-words-list` into `pyproject.toml`
How can I put `check-filenames`, `check-hidden`, and `ignore-words-list` into `pyproject.toml`?

In the tests there doesn't seem to be a case for this: https://github.com/codespell-project/codespell/blob/v2.2.4/codespell_lib/tests/test_basic.py#L1028

From a GitHub Search, there's no results either: `tool.codespell filename:pyproject.toml`

And none of the below keys are working for me:

```toml
[tool.codespell]

check-filenames = true
check-hidden = true
ignore-words-list = ["acn"]
```

```
> codespell .
usage: codespell [-h] [--version] [-d] [-c] [-w] [-D DICTIONARY] [--builtin BUILTIN-LIST] [--ignore-regex IGNORE_REGEX] [-I FILE] [-L WORDS] [--uri-ignore-words-list WORDS] [-r REGEX] [--uri-regex URI_REGEX] [-s] [--count] [-S SKIP]
                 [-x FILE] [-i INTERACTIVE] [-q QUIET_LEVEL] [-e] [-f] [-H] [-A LINES] [-B LINES] [-C LINES] [--config CONFIG] [--toml TOML]
                 [files ...]
codespell: error: unrecognized arguments: True
```

From https://stackoverflow.com/questions/75377334/toml-how-to-have-key-without-value it seems keys without values aren't possible in `.toml`.

---

Related: https://github.com/codespell-project/codespell/issues/2718

Here is my old `.codespellrc`:

```rc
[codespell]
check-filenames =
check-hidden =
ignore-words-list = acn
```



Discussion:
`ignore-words-list` expects a “_comma separated list of words_”. Try:
```
ignore-words-list = "acn"
```
```toml
[tool.codespell]

ignore-words-list = "acn"
```

Works for me when invoking `codespell` from the command line or with this `pre-commit` config:

```yaml
- repo: https://github.com/codespell-project/codespell
  rev: v2.2.4
  hooks:
  - id: codespell
    additional_dependencies:
      - tomli
```

Yaay, thank you!

---

How about `check-filenames` and `check-hidden`?
> How about `check-filenames` and `check-hidden`?

Following the convention in https://github.com/codespell-project/codespell#using-a-config-file where `--count` in the command line corresponds to `count = ` in the `.codespellrc` file and `count = ''` in the `pyproject.toml` file, I tried this:

```toml
[tool.codespell]
ignore-words-list = "acn"
check-filenames = ""
check-hidden = ""
```

And it looks like it works as intended.

Shouldn't these work as well?
```toml
check-filenames = true
check-hidden = true
```
I wonder whether this should be considered a bug.

Resolving patch:
diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py
--- a/codespell_lib/_codespell.py
+++ b/codespell_lib/_codespell.py
@@ -23,7 +23,7 @@
 import re
 import sys
 import textwrap
-from typing import Dict, List, Match, Optional, Pattern, Sequence, Set, Tuple
+from typing import Any, Dict, List, Match, Optional, Pattern, Sequence, Set, Tuple
 
 # autogenerated by setuptools_scm
 from ._version import __version__ as VERSION  # type: ignore  # noqa: N812
@@ -301,6 +301,11 @@ def _split_lines(self, text: str, width: int) -> List[str]:
         return out
 
 
+def _toml_to_parseconfig(toml_dict: Dict[str, Any]) -> Dict[str, Any]:
+    """Convert a dict read from a TOML file to the parseconfig.read_dict() format."""
+    return {k: "" if v is True else v for k, v in toml_dict.items() if v is not False}
+
+
 def parse_options(
     args: Sequence[str],
 ) -> Tuple[argparse.Namespace, argparse.ArgumentParser, List[str]]:
@@ -566,6 +571,8 @@ def parse_options(
             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)
 
     # Collect which config files are going to be used


Test patch:
diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py
--- a/codespell_lib/tests/test_basic.py
+++ b/codespell_lib/tests/test_basic.py
@@ -1068,14 +1068,16 @@ def test_config_toml(
     d.mkdir()
     (d / "bad.txt").write_text("abandonned donn\n")
     (d / "good.txt").write_text("good")
+    (d / "abandonned.txt").write_text("")
 
-    # Should fail when checking both.
-    result = cs.main(d, count=True, std=True)
+    # Should fail when checking all files.
+    result = cs.main(d, "--check-filenames", count=True, std=True)
     assert isinstance(result, tuple)
     code, stdout, _ = result
     # Code in this case is not exit code, but count of misspellings.
-    assert code == 2
+    assert code == 3
     assert "bad.txt" in stdout
+    assert "abandonned.txt" in stdout
 
     if kind == "cfg":
         conffile = tmp_path / "setup.cfg"
@@ -1097,16 +1099,18 @@ def test_config_toml(
             """\
 [tool.codespell]
 skip = 'bad.txt,whatever.txt'
-count = false
+check-filenames = false
+count = true
 """
         )
 
-    # Should pass when skipping bad.txt
-    result = cs.main(d, *args, count=True, std=True)
+    # Should pass when skipping bad.txt or abandonned.txt
+    result = cs.main(d, *args, std=True)
     assert isinstance(result, tuple)
     code, stdout, _ = result
     assert code == 0
     assert "bad.txt" not in stdout
+    assert "abandonned.txt" not in stdout
 
     # And both should automatically work if they're in cwd
     cwd = Path.cwd()
@@ -1119,6 +1123,7 @@ def test_config_toml(
         os.chdir(cwd)
     assert code == 0
     assert "bad.txt" not in stdout
+    assert "abandonned.txt" not in stdout
 
 
 @contextlib.contextmanager