From 0c44220e216f6d253087f96341110c693d3ef2d4 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Tue, 17 Sep 2019 13:40:03 -0700 Subject: [PATCH] Don't allow type comments to be merged behind regular comments (#1027) Type comments only apply if they are the first comment on the line, which means that allowing them to be pushed behind a regular comment when joining lines is a semantic change (and, indeed, one that black catches and fails on). --- black.py | 18 ++++++++++++------ tests/data/comments6.py | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/black.py b/black.py index 71f42ef..a4f3688 100644 --- a/black.py +++ b/black.py @@ -1296,7 +1296,7 @@ class Line: return True return False - def contains_inner_type_comments(self) -> bool: + def contains_uncollapsable_type_comments(self) -> bool: ignored_ids = set() try: last_leaf = self.leaves[-1] @@ -1313,13 +1313,19 @@ class Line: except IndexError: return False + # A type comment is uncollapsable if it is attached to a leaf + # that isn't at the end of the line (since that could cause it + # to get associated to a different argument) or if there are + # comments before it (since that could cause it to get hidden + # behind a comment. + comment_seen = False for leaf_id, comments in self.comments.items(): - if leaf_id in ignored_ids: - continue - for comment in comments: if is_type_comment(comment): - return True + if leaf_id not in ignored_ids or comment_seen: + return True + + comment_seen = True return False @@ -2328,7 +2334,7 @@ def split_line( line_str = str(line).strip("\n") if ( - not line.contains_inner_type_comments() + not line.contains_uncollapsable_type_comments() and not line.should_explode and is_line_short_enough(line, line_length=line_length, line_str=line_str) ): diff --git a/tests/data/comments6.py b/tests/data/comments6.py index a2cd018..6e34b74 100644 --- a/tests/data/comments6.py +++ b/tests/data/comments6.py @@ -69,6 +69,20 @@ def f( ) # type: int +def f( + x, # not a type comment + y, # type: int +): + # type: (...) -> None + pass + + +def f( + x, # not a type comment +): # type: (int) -> None + pass + + def func( a=some_list[0], # type: int ): # type: () -> int -- 2.39.5