Ejemplo n.º 1
0
    def append_comment(self, comment: Leaf) -> bool:
        """Add an inline or standalone comment to the line."""
        if (comment.type == STANDALONE_COMMENT
                and self.bracket_tracker.any_open_brackets()):
            comment.prefix = ""
            return False

        if comment.type != token.COMMENT:
            return False

        if not self.leaves:
            comment.type = STANDALONE_COMMENT
            comment.prefix = ""
            return False

        last_leaf = self.leaves[-1]
        if (last_leaf.type == token.RPAR and not last_leaf.value
                and last_leaf.parent
                and len(list(last_leaf.parent.leaves())) <= 3
                and not is_type_comment(comment)):
            # Comments on an optional parens wrapping a single leaf should belong to
            # the wrapped node except if it's a type comment. Pinning the comment like
            # this avoids unstable formatting caused by comment migration.
            if len(self.leaves) < 2:
                comment.type = STANDALONE_COMMENT
                comment.prefix = ""
                return False

            last_leaf = self.leaves[-2]
        self.comments.setdefault(id(last_leaf), []).append(comment)
        return True
Ejemplo n.º 2
0
def normalize_prefix(leaf: Leaf) -> None:
    """Leave existing extra newlines for imports.  Remove everything else."""
    if is_import(leaf):
        spl = leaf.prefix.split('#', 1)
        nl_count = spl[0].count('\n')
        leaf.prefix = '\n' * nl_count
        return

    leaf.prefix = ''
Ejemplo n.º 3
0
def normalize_prefix(leaf: Leaf) -> None:
    """Leave existing extra newlines for imports.  Remove everything else."""
    if is_import(leaf):
        spl = leaf.prefix.split('#', 1)
        nl_count = spl[0].count('\n')
        if len(spl) > 1:
            # Skip one newline since it was for a standalone comment.
            nl_count -= 1
        leaf.prefix = '\n' * nl_count
        return

    leaf.prefix = ''
Ejemplo n.º 4
0
def normalize_prefix(leaf: Leaf, *, inside_brackets: bool) -> None:
    """Leave existing extra newlines if not `inside_brackets`. Remove everything
    else.

    Note: don't use backslashes for formatting or you'll lose your voting rights.
    """
    if not inside_brackets:
        spl = leaf.prefix.split("#")
        if "\\" not in spl[0]:
            nl_count = spl[-1].count("\n")
            if len(spl) > 1:
                nl_count -= 1
            leaf.prefix = "\n" * nl_count
            return

    leaf.prefix = ""
Ejemplo n.º 5
0
def generate_ignored_nodes(leaf: Leaf, comment: ProtoComment) -> Iterator[LN]:
    """Starting from the container of `leaf`, generate all leaves until `# fmt: on`.

    If comment is skip, returns leaf only.
    Stops at the end of the block.
    """
    container: Optional[LN] = container_of(leaf)
    if comment.value in FMT_SKIP:
        prev_sibling = leaf.prev_sibling
        if comment.value in leaf.prefix and prev_sibling is not None:
            leaf.prefix = leaf.prefix.replace(comment.value, "")
            siblings = [prev_sibling]
            while ("\n" not in prev_sibling.prefix
                   and prev_sibling.prev_sibling is not None):
                prev_sibling = prev_sibling.prev_sibling
                siblings.insert(0, prev_sibling)
            for sibling in siblings:
                yield sibling
        elif leaf.parent is not None:
            yield leaf.parent
        return
    while container is not None and container.type != token.ENDMARKER:
        if is_fmt_on(container):
            return

        # fix for fmt: on in children
        if contains_fmt_on_at_column(container, leaf.column):
            for child in container.children:
                if contains_fmt_on_at_column(child, leaf.column):
                    return
                yield child
        else:
            yield container
            container = container.next_sibling
Ejemplo n.º 6
0
    def maybe_adapt_standalone_comment(self, comment: Leaf) -> bool:
        """Hack a standalone comment to act as a trailing comment for line splitting.

        If this line has brackets and a standalone `comment`, we need to adapt
        it to be able to still reformat the line.

        This is not perfect, the line to which the standalone comment gets
        appended will appear "too long" when splitting.
        """
        if not (comment.type == STANDALONE_COMMENT
                and self.bracket_tracker.any_open_brackets()):
            return False

        comment.type = token.COMMENT
        comment.prefix = '\n' + '    ' * (self.depth + 1)
        return self.append_comment(comment)
Ejemplo n.º 7
0
    def append_comment(self, comment: Leaf) -> bool:
        if comment.type != token.COMMENT:
            return False

        try:
            after = id(self.last_non_delimiter())
        except LookupError:
            comment.type = STANDALONE_COMMENT
            comment.prefix = ''
            return False

        else:
            if after in self.comments:
                self.comments[after].value += str(comment)
            else:
                self.comments[after] = comment
            return True
Ejemplo n.º 8
0
def generate_ignored_nodes(leaf: Leaf, comment: ProtoComment, *,
                           preview: bool) -> Iterator[LN]:
    """Starting from the container of `leaf`, generate all leaves until `# fmt: on`.

    If comment is skip, returns leaf only.
    Stops at the end of the block.
    """
    container: Optional[LN] = container_of(leaf)
    if comment.value in FMT_SKIP:
        prev_sibling = leaf.prev_sibling
        # Need to properly format the leaf prefix to compare it to comment.value,
        # which is also formatted
        comments = list_comments(leaf.prefix,
                                 is_endmarker=False,
                                 preview=preview)
        if comments and comment.value == comments[
                0].value and prev_sibling is not None:
            leaf.prefix = ""
            siblings = [prev_sibling]
            while ("\n" not in prev_sibling.prefix
                   and prev_sibling.prev_sibling is not None):
                prev_sibling = prev_sibling.prev_sibling
                siblings.insert(0, prev_sibling)
            for sibling in siblings:
                yield sibling
        elif leaf.parent is not None:
            yield leaf.parent
        return
    while container is not None and container.type != token.ENDMARKER:
        if is_fmt_on(container, preview=preview):
            return

        # fix for fmt: on in children
        if contains_fmt_on_at_column(container, leaf.column, preview=preview):
            for child in container.children:
                if contains_fmt_on_at_column(child,
                                             leaf.column,
                                             preview=preview):
                    return
                yield child
        else:
            yield container
            container = container.next_sibling