Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise exception on invalid toml configuration #4165

Merged
merged 11 commits into from
Jan 26, 2024
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ release:

<!-- Changes to how Black can be configured -->

- Print warning when toml config contains an invalid key (#4165)
- Fix symlink handling, properly catch and ignore symlinks that point outside of root
(#4161)
- Fix cache mtime logic that resulted in false positive cache hits (#4128)
Expand Down
16 changes: 16 additions & 0 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def read_pyproject_toml(
if not config:
return None
else:
spellcheck_pyproject_toml_keys(ctx, list(config), value)
# Sanitize the values to be Click friendly. For more information please see:
# https://github.com/psf/black/issues/1458
# https://github.com/pallets/click/issues/1567
Expand Down Expand Up @@ -181,6 +182,21 @@ def read_pyproject_toml(
return value


def spellcheck_pyproject_toml_keys(
ctx: click.Context, config_keys: List[str], config_file_path: str
) -> None:
invalid_keys: List[str] = []
available_config_options = {param.name for param in ctx.command.params}
for key in config_keys:
if key not in available_config_options:
invalid_keys.append(key)
if invalid_keys:
out(
f"Invalid config keys detected: {invalid_keys} in {config_file_path}",
fg="red",
)


def target_version_option_callback(
c: click.Context, p: Union[click.Option, click.Parameter], v: Tuple[str, ...]
) -> List[TargetVersion]:
Expand Down
5 changes: 5 additions & 0 deletions tests/data/incorrect_spelling.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[tool.black]
ine_length = 50
target-ersion = ['py37']
exclude='\.pyi?$'
include='\.py?$'
18 changes: 18 additions & 0 deletions tests/test_black.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class FakeContext(click.Context):
def __init__(self) -> None:
self.default_map: Dict[str, Any] = {}
self.params: Dict[str, Any] = {}
self.command: click.Command = black.main
# Dummy root, since most of the tests don't care about it
self.obj: Dict[str, Any] = {"root": PROJECT_ROOT}

Expand Down Expand Up @@ -1538,6 +1539,23 @@ def test_parse_pyproject_toml(self) -> None:
self.assertEqual(config["exclude"], r"\.pyi?$")
self.assertEqual(config["include"], r"\.py?$")

def test_spellcheck_pyproject_toml(self) -> None:
test_toml_file = THIS_DIR / "data" / "incorrect_spelling.toml"
result = BlackRunner().invoke(
black.main,
[
"--code=print('hello world')",
"--verbose",
f"--config={str(test_toml_file)}",
],
)

assert (
r"Invalid config keys detected: ['ine_length', 'target_ersion'] in "
+ str(test_toml_file)
in result.stderr
)

def test_parse_pyproject_toml_project_metadata(self) -> None:
for test_toml, expected in [
("only_black_pyproject.toml", ["py310"]),
Expand Down