From 5b0b79e128c17eeafe80100fd541a04c1d031e23 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 3 Dec 2022 11:37:51 +0300 Subject: [PATCH] [conf] Allow trailing commas in `ini` configuration of multiline values --- mypy/config_parser.py | 23 +++++++++++++++------- test-data/unit/check-custom-plugin.test | 9 +++++++++ test-data/unit/cmdline.test | 26 +++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 485d2f67f5de..190782a3bded 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -137,6 +137,15 @@ def check_follow_imports(choice: str) -> str: return choice +def split_commas(value: str) -> list[str]: + # Uses a bit smarter technique to allow last trailing comma + # and to remove last `""` item from the split. + items = value.split(",") + if items and items[-1] == "": + items.pop(-1) + return items + + # For most options, the type of the default value set in options.py is # sufficient, and we don't have to do anything here. This table # exists to specify types for values initialized to None or container @@ -151,13 +160,13 @@ def check_follow_imports(choice: str) -> str: "junit_xml": expand_path, "follow_imports": check_follow_imports, "no_site_packages": bool, - "plugins": lambda s: [p.strip() for p in s.split(",")], - "always_true": lambda s: [p.strip() for p in s.split(",")], - "always_false": lambda s: [p.strip() for p in s.split(",")], - "enable_incomplete_feature": lambda s: [p.strip() for p in s.split(",")], - "disable_error_code": lambda s: validate_codes([p.strip() for p in s.split(",")]), - "enable_error_code": lambda s: validate_codes([p.strip() for p in s.split(",")]), - "package_root": lambda s: [p.strip() for p in s.split(",")], + "plugins": lambda s: [p.strip() for p in split_commas(s)], + "always_true": lambda s: [p.strip() for p in split_commas(s)], + "always_false": lambda s: [p.strip() for p in split_commas(s)], + "enable_incomplete_feature": lambda s: [p.strip() for p in split_commas(s)], + "disable_error_code": lambda s: validate_codes([p.strip() for p in split_commas(s)]), + "enable_error_code": lambda s: validate_codes([p.strip() for p in split_commas(s)]), + "package_root": lambda s: [p.strip() for p in split_commas(s)], "cache_dir": expand_path, "python_executable": expand_path, "strict": bool, diff --git a/test-data/unit/check-custom-plugin.test b/test-data/unit/check-custom-plugin.test index a716109d345e..d7beea0390e7 100644 --- a/test-data/unit/check-custom-plugin.test +++ b/test-data/unit/check-custom-plugin.test @@ -163,6 +163,15 @@ reveal_type(f()) # N: Revealed type is "builtins.int" \[mypy] plugins=/test-data/unit/plugins/customentry.py:register +[case testCustomPluginEntryPointFileTrailingComma] +# flags: --config-file tmp/mypy.ini +def f() -> str: ... +reveal_type(f()) # N: Revealed type is "builtins.int" +[file mypy.ini] +\[mypy] +plugins = + /test-data/unit/plugins/customentry.py:register, + [case testCustomPluginEntryPoint] # flags: --config-file tmp/mypy.ini def f() -> str: ... diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index 92b0af6942bc..9eba9ea1e906 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -1570,3 +1570,29 @@ foo.py:1: error: "int" not callable 1() [out] foo/m.py:1: error: "int" not callable + +[case testCmdlineCfgEnableErrorCodeTrailingComma] +# cmd: mypy . +[file mypy.ini] +\[mypy] +enable_error_code = + truthy-bool, + redundant-expr, +[out] + +[case testCmdlineCfgDisableErrorCodeTrailingComma] +# cmd: mypy . +[file mypy.ini] +\[mypy] +disable_error_code = + misc, + override, +[out] + +[case testCmdlineCfgAlwaysTrueTrailingComma] +# cmd: mypy . +[file mypy.ini] +\[mypy] +always_true = + MY_VAR, +[out]