def visit_default(self, node: LN) -> Iterator[Line]: """Default `visit_*()` implementation. Recurses to children of `node`.""" if isinstance(node, Leaf): any_open_brackets = self.current_line.bracket_tracker.any_open_brackets() for comment in generate_comments(node): if any_open_brackets: # any comment within brackets is subject to splitting self.current_line.append(comment) elif comment.type == token.COMMENT: # regular trailing comment self.current_line.append(comment) yield from self.line() else: # regular standalone comment yield from self.line() self.current_line.append(comment) yield from self.line() normalize_prefix(node, inside_brackets=any_open_brackets) if self.mode.string_normalization and node.type == token.STRING: node.value = normalize_string_prefix(node.value) node.value = normalize_string_quotes(node.value) if node.type == token.NUMBER: normalize_numeric_literal(node) if node.type not in WHITESPACE: self.current_line.append(node) yield from super().visit_default(node)
def visit_default(self, node: LN) -> Iterator[Line]: """Default `visit_*()` implementation. Recurses to children of `node`.""" if isinstance(node, Leaf): any_open_brackets = self.current_line.bracket_tracker.any_open_brackets() append_blank_lines = ( any_open_brackets and self.mode.keep_blank_lines_in_brackets ) try: last_leaf: Optional[Leaf] = self.current_line.leaves[-1] except IndexError: last_leaf = None for comment in generate_comments(node): if ( append_blank_lines and last_leaf and last_leaf.type not in OPENING_BRACKETS ): newlines = comment.prefix.count("\n") if last_leaf and last_leaf.type in COMMENTS: newlines += 1 if newlines > 1: self.current_line.append(Leaf(STANDALONE_COMMENT, "")) if any_open_brackets: # any comment within brackets is subject to splitting self.current_line.append(comment) last_leaf = comment elif comment.type == token.COMMENT: # regular trailing comment self.current_line.append(comment) yield from self.line() else: # regular standalone comment yield from self.line() self.current_line.append(comment) yield from self.line() if ( append_blank_lines and last_leaf and last_leaf.type not in OPENING_BRACKETS and node.type not in CLOSING_BRACKETS and node.prefix.split("#")[-1].count("\n") > 1 ): self.current_line.append(Leaf(STANDALONE_COMMENT, "")) normalize_prefix(node, inside_brackets=any_open_brackets) if self.mode.string_normalization and node.type == token.STRING: node.value = normalize_string_prefix(node.value) node.value = normalize_string_quotes(node.value) if node.type == token.NUMBER: normalize_numeric_literal(node) if node.type not in WHITESPACE: self.current_line.append(node) yield from super().visit_default(node)
def visit_STRING(self, leaf: Leaf) -> Iterator[Line]: if is_docstring(leaf) and "\\\n" not in leaf.value: # We're ignoring docstrings with backslash newline escapes because changing # indentation of those changes the AST representation of the code. docstring = normalize_string_prefix(leaf.value) prefix = get_string_prefix(docstring) docstring = docstring[len(prefix):] # Remove the prefix quote_char = docstring[0] # A natural way to remove the outer quotes is to do: # docstring = docstring.strip(quote_char) # but that breaks on """""x""" (which is '""x'). # So we actually need to remove the first character and the next two # characters but only if they are the same as the first. quote_len = 1 if docstring[1] != quote_char else 3 docstring = docstring[quote_len:-quote_len] docstring_started_empty = not docstring if is_multiline_string(leaf): indent_style = " " * 4 if not self.mode.use_tabs else "\t" indent = indent_style * self.current_line.depth docstring = fix_docstring(docstring, indent, not self.mode.use_tabs) else: docstring = docstring.strip() if docstring: # Add some padding if the docstring starts / ends with a quote mark. if docstring[0] == quote_char: docstring = " " + docstring if docstring[-1] == quote_char: docstring += " " if docstring[-1] == "\\": backslash_count = len(docstring) - len( docstring.rstrip("\\")) if backslash_count % 2: # Odd number of tailing backslashes, add some padding to # avoid escaping the closing string quote. docstring += " " elif not docstring_started_empty: docstring = " " # We could enforce triple quotes at this point. quote = quote_char * quote_len leaf.value = prefix + quote + docstring + quote yield from self.visit_default(leaf)