From 5441d3fe8da80e28b2ed20d6fd6976c596142d93 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Tue, 23 Jan 2024 14:12:10 -0600 Subject: [PATCH 01/10] raise error when toml config contains a typo --- src/black/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/black/__init__.py b/src/black/__init__.py index e3cbaab5f1d..57ccf723190 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -117,6 +117,10 @@ def from_configuration( FileMode = Mode +class InvalidConfigKey(Exception): + """Invalid configuration key found in pyproject toml.""" + + def read_pyproject_toml( ctx: click.Context, param: click.Parameter, value: Optional[str] ) -> Optional[str]: @@ -142,6 +146,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 @@ -181,6 +186,15 @@ def read_pyproject_toml( return value +def spellcheck_pyproject_toml_keys( + ctx: click.Context, config_keys: List[str], config_file_path: str +) -> None: + available_config_options = {param.name for param in ctx.command.params} + for key in config_keys: + if key not in available_config_options: + raise InvalidConfigKey(f"Invalid key {key} in {config_file_path}") + + def target_version_option_callback( c: click.Context, p: Union[click.Option, click.Parameter], v: Tuple[str, ...] ) -> List[TargetVersion]: From 510b6a980508deab63eb71ead312a3e03c893abc Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Tue, 23 Jan 2024 14:12:32 -0600 Subject: [PATCH 02/10] test cases --- tests/data/incorrect_spelling.toml | 2 ++ tests/test_black.py | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/data/incorrect_spelling.toml diff --git a/tests/data/incorrect_spelling.toml b/tests/data/incorrect_spelling.toml new file mode 100644 index 00000000000..909f1bf87b5 --- /dev/null +++ b/tests/data/incorrect_spelling.toml @@ -0,0 +1,2 @@ +[tool.black] +ine_length = 50 \ No newline at end of file diff --git a/tests/test_black.py b/tests/test_black.py index 2b5fab5d28d..413d59e66a6 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -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} @@ -1538,6 +1539,17 @@ 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" + with pytest.raises(black.InvalidConfigKey) as exc_info: + self.invokeBlack( + ["print('hello world')", "--verbose", "--config", str(test_toml_file)], + exit_code=123, + ignore_config=False, + ) + + exc_info.match(f"Invalid key ine_length in {test_toml_file}") + def test_parse_pyproject_toml_project_metadata(self) -> None: for test_toml, expected in [ ("only_black_pyproject.toml", ["py310"]), From 14fb847e629d15438fd148fb79c789173d7353e0 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Tue, 23 Jan 2024 14:12:54 -0600 Subject: [PATCH 03/10] update change log --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f29834a3f7f..0d8c4ee210a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,6 +29,7 @@ +- Raise an error 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) From 89a9d89d1988fb10eed183dcfe13f7d0168a757b Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Tue, 23 Jan 2024 21:37:35 -0600 Subject: [PATCH 04/10] account for escape characters in --config path --- tests/test_black.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_black.py b/tests/test_black.py index 413d59e66a6..f31ea31a0e7 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1548,7 +1548,7 @@ def test_spellcheck_pyproject_toml(self) -> None: ignore_config=False, ) - exc_info.match(f"Invalid key ine_length in {test_toml_file}") + exc_info.match(f'Invalid key ine_length in {re.escape(str(test_toml_file))}') def test_parse_pyproject_toml_project_metadata(self) -> None: for test_toml, expected in [ From 6a1e11b71c80ca244117635b31d1656929631689 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Tue, 23 Jan 2024 21:38:08 -0600 Subject: [PATCH 05/10] reformat test file --- tests/test_black.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_black.py b/tests/test_black.py index f31ea31a0e7..4e8cc41fe27 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1548,7 +1548,7 @@ def test_spellcheck_pyproject_toml(self) -> None: ignore_config=False, ) - exc_info.match(f'Invalid key ine_length in {re.escape(str(test_toml_file))}') + exc_info.match(f"Invalid key ine_length in {re.escape(str(test_toml_file))}") def test_parse_pyproject_toml_project_metadata(self) -> None: for test_toml, expected in [ From a350e0f16d704e6bdf9ce95932284905b458ef21 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Thu, 25 Jan 2024 10:34:32 -0600 Subject: [PATCH 06/10] switch to warning instead of exception, list all invalid keys --- src/black/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/black/__init__.py b/src/black/__init__.py index 57ccf723190..c468adad477 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -117,10 +117,6 @@ def from_configuration( FileMode = Mode -class InvalidConfigKey(Exception): - """Invalid configuration key found in pyproject toml.""" - - def read_pyproject_toml( ctx: click.Context, param: click.Parameter, value: Optional[str] ) -> Optional[str]: @@ -189,10 +185,16 @@ def read_pyproject_toml( 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: - raise InvalidConfigKey(f"Invalid key {key} in {config_file_path}") + 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( From d3669b3e20814a1557ed600645a44b3aea96ebf4 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Thu, 25 Jan 2024 10:35:09 -0600 Subject: [PATCH 07/10] update test case --- tests/data/incorrect_spelling.toml | 5 ++++- tests/test_black.py | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/data/incorrect_spelling.toml b/tests/data/incorrect_spelling.toml index 909f1bf87b5..560c9e27be2 100644 --- a/tests/data/incorrect_spelling.toml +++ b/tests/data/incorrect_spelling.toml @@ -1,2 +1,5 @@ [tool.black] -ine_length = 50 \ No newline at end of file +ine_length = 50 +target-ersion = ['py37'] +exclude='\.pyi?$' +include='\.py?$' \ No newline at end of file diff --git a/tests/test_black.py b/tests/test_black.py index 4e8cc41fe27..abfd47771f0 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1541,14 +1541,20 @@ def test_parse_pyproject_toml(self) -> None: def test_spellcheck_pyproject_toml(self) -> None: test_toml_file = THIS_DIR / "data" / "incorrect_spelling.toml" - with pytest.raises(black.InvalidConfigKey) as exc_info: - self.invokeBlack( - ["print('hello world')", "--verbose", "--config", str(test_toml_file)], - exit_code=123, - ignore_config=False, - ) + result = BlackRunner().invoke( + black.main, + [ + "--code=print('hello world')", + "--verbose", + f"--config={str(test_toml_file)}", + ] + ) - exc_info.match(f"Invalid key ine_length in {re.escape(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 [ From 1023291c7d28b438fa41c30f314d3ec4a40a7994 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Thu, 25 Jan 2024 10:37:05 -0600 Subject: [PATCH 08/10] reformat --- tests/test_black.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_black.py b/tests/test_black.py index abfd47771f0..dc4dd217acc 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1547,7 +1547,7 @@ def test_spellcheck_pyproject_toml(self) -> None: "--code=print('hello world')", "--verbose", f"--config={str(test_toml_file)}", - ] + ], ) assert ( From 3eac15567dbf53e465939913309ede3f573d5459 Mon Sep 17 00:00:00 2001 From: dankrzeminski32 Date: Thu, 25 Jan 2024 10:43:03 -0600 Subject: [PATCH 09/10] update change log --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 0d8c4ee210a..cea27d8416a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,7 +29,7 @@ -- Raise an error when toml config contains an invalid key (#4165) +- 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) From da6722792f69981c15f69cd30fd6079c776e4666 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 25 Jan 2024 16:24:08 -0800 Subject: [PATCH 10/10] Adjust message --- src/black/__init__.py | 3 ++- tests/test_black.py | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/black/__init__.py b/src/black/__init__.py index c468adad477..961ed9479a8 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -191,8 +191,9 @@ def spellcheck_pyproject_toml_keys( if key not in available_config_options: invalid_keys.append(key) if invalid_keys: + keys_str = ", ".join(map(repr, invalid_keys)) out( - f"Invalid config keys detected: {invalid_keys} in {config_file_path}", + f"Invalid config keys detected: {keys_str} (in {config_file_path})", fg="red", ) diff --git a/tests/test_black.py b/tests/test_black.py index dc4dd217acc..a979a95b674 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1551,9 +1551,8 @@ def test_spellcheck_pyproject_toml(self) -> None: ) assert ( - r"Invalid config keys detected: ['ine_length', 'target_ersion'] in " - + str(test_toml_file) - in result.stderr + r"Invalid config keys detected: 'ine_length', 'target_ersion' (in" + rf" {test_toml_file})" in result.stderr ) def test_parse_pyproject_toml_project_metadata(self) -> None: