Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)