From 8bf04549ffd276a1bad6eb110e66e6557ee630d9 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+RedGuy12@users.noreply.github.com> Date: Sat, 27 Jan 2024 15:55:22 -0600 Subject: [PATCH] Consistently add trailing comma on typed parameters (#4164) Signed-off-by: RedGuy12 <61329810+RedGuy12@users.noreply.github.com> Co-authored-by: Jelle Zijlstra --- CHANGES.md | 2 ++ docs/the_black_code_style/future_style.md | 2 ++ src/black/files.py | 2 +- src/black/linegen.py | 10 +++++++- src/black/mode.py | 1 + src/blib2to3/pgen2/parse.py | 2 +- .../data/cases/typed_params_trailing_comma.py | 24 +++++++++++++++++++ 7 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 tests/data/cases/typed_params_trailing_comma.py diff --git a/CHANGES.md b/CHANGES.md index e4240eacfca..6278aed77d8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ +- Consistently add trailing comma on typed parameters (#4164) + ### Configuration diff --git a/docs/the_black_code_style/future_style.md b/docs/the_black_code_style/future_style.md index 1cdd25fdb7c..d5faae36911 100644 --- a/docs/the_black_code_style/future_style.md +++ b/docs/the_black_code_style/future_style.md @@ -26,6 +26,8 @@ Currently, the following features are included in the preview style: brackets ([see below](labels/hug-parens)) - `no_normalize_fmt_skip_whitespace`: whitespace before `# fmt: skip` comments is no longer normalized +- `typed_params_trailing_comma`: consistently add trailing commas to typed function + parameters (labels/unstable-features)= diff --git a/src/black/files.py b/src/black/files.py index 65951efdbe8..1eb8745572b 100644 --- a/src/black/files.py +++ b/src/black/files.py @@ -131,7 +131,7 @@ def parse_pyproject_toml(path_config: str) -> Dict[str, Any]: def infer_target_version( - pyproject_toml: Dict[str, Any] + pyproject_toml: Dict[str, Any], ) -> Optional[List[TargetVersion]]: """Infer Black's target version from the project metadata in pyproject.toml. diff --git a/src/black/linegen.py b/src/black/linegen.py index a276805f2fe..c74ff9c0b4b 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -48,6 +48,7 @@ is_one_sequence_between, is_one_tuple, is_parent_function_or_class, + is_part_of_annotation, is_rpar_token, is_stub_body, is_stub_suite, @@ -1041,7 +1042,14 @@ def bracket_split_build_line( no_commas = ( original.is_def and opening_bracket.value == "(" - and not any(leaf.type == token.COMMA for leaf in leaves) + and not any( + leaf.type == token.COMMA + and ( + Preview.typed_params_trailing_comma not in original.mode + or not is_part_of_annotation(leaf) + ) + for leaf in leaves + ) # In particular, don't add one within a parenthesized return annotation. # Unfortunately the indicator we're in a return annotation (RARROW) may # be defined directly in the parent node, the parent of the parent ... diff --git a/src/black/mode.py b/src/black/mode.py index 128d2b9f108..22352e7c6a8 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -176,6 +176,7 @@ class Preview(Enum): no_normalize_fmt_skip_whitespace = auto() wrap_long_dict_values_in_parens = auto() multiline_string_handling = auto() + typed_params_trailing_comma = auto() UNSTABLE_FEATURES: Set[Preview] = { diff --git a/src/blib2to3/pgen2/parse.py b/src/blib2to3/pgen2/parse.py index ad51a3dad08..ad1d795b51a 100644 --- a/src/blib2to3/pgen2/parse.py +++ b/src/blib2to3/pgen2/parse.py @@ -50,7 +50,7 @@ def lam_sub(grammar: Grammar, node: RawNode) -> NL: def stack_copy( - stack: List[Tuple[DFAS, int, RawNode]] + stack: List[Tuple[DFAS, int, RawNode]], ) -> List[Tuple[DFAS, int, RawNode]]: """Nodeless stack copy.""" return [(dfa, label, DUMMY_NODE) for dfa, label, _ in stack] diff --git a/tests/data/cases/typed_params_trailing_comma.py b/tests/data/cases/typed_params_trailing_comma.py new file mode 100644 index 00000000000..a53b908b18b --- /dev/null +++ b/tests/data/cases/typed_params_trailing_comma.py @@ -0,0 +1,24 @@ +# flags: --preview +def long_function_name_goes_here( + x: Callable[List[int]] +) -> Union[List[int], float, str, bytes, Tuple[int]]: + pass + + +def long_function_name_goes_here( + x: Callable[[str, Any], int] +) -> Union[List[int], float, str, bytes, Tuple[int]]: + pass + + +# output +def long_function_name_goes_here( + x: Callable[List[int]], +) -> Union[List[int], float, str, bytes, Tuple[int]]: + pass + + +def long_function_name_goes_here( + x: Callable[[str, Any], int], +) -> Union[List[int], float, str, bytes, Tuple[int]]: + pass