+ return False
+
+ def contains_uncollapsable_type_comments(self) -> bool:
+ ignored_ids = set()
+ try:
+ last_leaf = self.leaves[-1]
+ ignored_ids.add(id(last_leaf))
+ if last_leaf.type == token.COMMA or (
+ last_leaf.type == token.RPAR and not last_leaf.value
+ ):
+ # When trailing commas or optional parens are inserted by Black for
+ # consistency, comments after the previous last element are not moved
+ # (they don't have to, rendering will still be correct). So we ignore
+ # trailing commas and invisible.
+ last_leaf = self.leaves[-2]
+ ignored_ids.add(id(last_leaf))
+ 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():
+ for comment in comments:
+ if is_type_comment(comment):
+ if leaf_id not in ignored_ids or comment_seen:
+ return True
+
+ comment_seen = True
+
+ return False
+
+ def contains_unsplittable_type_ignore(self) -> bool:
+ if not self.leaves:
+ return False
+
+ # If a 'type: ignore' is attached to the end of a line, we
+ # can't split the line, because we can't know which of the
+ # subexpressions the ignore was meant to apply to.
+ #
+ # We only want this to apply to actual physical lines from the
+ # original source, though: we don't want the presence of a
+ # 'type: ignore' at the end of a multiline expression to
+ # justify pushing it all onto one line. Thus we
+ # (unfortunately) need to check the actual source lines and
+ # only report an unsplittable 'type: ignore' if this line was
+ # one line in the original code.
+
+ # Like in the type comment check above, we need to skip a black added
+ # trailing comma or invisible paren, since it will be the original leaf
+ # before it that has the original line number.
+ last_idx = -1
+ last_leaf = self.leaves[-1]
+ if len(self.leaves) > 2 and (
+ last_leaf.type == token.COMMA
+ or (last_leaf.type == token.RPAR and not last_leaf.value)
+ ):
+ last_idx = -2
+
+ if self.leaves[0].lineno == self.leaves[last_idx].lineno:
+ for node in self.leaves[last_idx:]:
+ for comment in self.comments.get(id(node), []):
+ if is_type_comment(comment, " ignore"):
+ return True
+
+ return False
+
+ def contains_multiline_strings(self) -> bool:
+ for leaf in self.leaves:
+ if is_multiline_string(leaf):
+ return True