Ejemplo n.º 1
0
    def _pygmented_scope_lines(self) -> Optional[Tuple[int, List[str]]]:
        # noinspection PyUnresolvedReferences
        from pygments.formatters import HtmlFormatter

        formatter = self.options.pygments_formatter
        scope = self.scope
        assert_(formatter, ValueError("Must set a pygments formatter in Options"))
        assert_(scope)

        if isinstance(formatter, HtmlFormatter):
            formatter.nowrap = True

        atok = self.source.asttokens()
        node = self.executing.node
        if node and getattr(formatter.style, "for_executing_node", False):
            scope_start = atok.get_text_range(scope)[0]
            start, end = atok.get_text_range(node)
            start -= scope_start
            end -= scope_start
            ranges = [(start, end)]
        else:
            ranges = []

        code = atok.get_text(scope)
        lines = _pygmented_with_ranges(formatter, code, ranges)

        start_line = line_range(scope)[0]

        return start_line, lines
Ejemplo n.º 2
0
 def variables_by_lineno(self):
     result = defaultdict(list)
     for var in self.variables:
         for node in var.nodes:
             for lineno in range(*line_range(node)):
                 result[lineno].append((var, node))
     return result
Ejemplo n.º 3
0
def check_pieces(source):
    pieces = source.pieces

    assert pieces == sorted(pieces, key=lambda p: (p.start, p.stop))

    stmts = sorted({
        line_range(node)
        for node in ast.walk(source.tree) if isinstance(node, ast.stmt)
        if not isinstance(getattr(node, 'body', None), list)
    })
    if not stmts:
        return

    stmts_iter = iter(stmts)
    stmt = next(stmts_iter)
    for piece in pieces:
        contains_stmt = stmt[0] <= piece.start < piece.stop <= stmt[1]
        before_stmt = piece.start < piece.stop <= stmt[0] < stmt[1]
        assert contains_stmt ^ before_stmt
        if contains_stmt:
            try:
                stmt = next(stmts_iter)
            except StopIteration:
                break

    blank_linenos = set(range(1, len(source.lines) + 1)).difference(*pieces)

    for lineno in blank_linenos:
        assert not source.lines[lineno - 1].strip(), lineno
Ejemplo n.º 4
0
    def scope_pieces(self):
        if not self.source.tree:
            return []

        scope_start, scope_end = line_range(self.scope)
        return [(start, end) for (start, end) in self.source.pieces
                if scope_start <= start and end <= scope_end]
Ejemplo n.º 5
0
    def range_from_node(self, node: ast.AST,
                        data: Any) -> Optional[RangeInLine]:
        """
        If the given node overlaps with this line, return a RangeInLine
        with the correct start and end and the given data.
        Otherwise, return None.
        """
        start, end = line_range(node)
        end -= 1
        if not (start <= self.lineno <= end):
            return None
        if start == self.lineno:
            try:
                range_start = node.first_token.start[1]
            except AttributeError:
                range_start = node.col_offset
        else:
            range_start = 0

        if end == self.lineno:
            try:
                range_end = node.last_token.end[1]
            except AttributeError:
                try:
                    range_end = node.end_col_offset
                except AttributeError:
                    return None
        else:
            range_end = len(self.text)

        return RangeInLine(range_start, range_end, data)
Ejemplo n.º 6
0
    def scope_pieces(self) -> List[range]:
        """
        All the pieces (ranges of lines) contained in this object's .scope.
        """
        if not self.scope:
            return []

        scope_start, scope_end = line_range(self.scope)
        return [
            piece for piece in self.source.pieces
            if scope_start <= piece.start and piece.stop <= scope_end
        ]
Ejemplo n.º 7
0
 def variables_by_lineno(self) -> Mapping[int, List[Tuple[Variable, ast.AST]]]:
     """
     A mapping from 1-based line numbers to lists of pairs:
         - A Variable object
         - A specific AST node from the variable's .nodes list that's
             in the line at that line number.
     """
     result = defaultdict(list)
     for var in self.variables:
         for node in var.nodes:
             for lineno in range(*line_range(node)):
                 result[lineno].append((var, node))
     return result
Ejemplo n.º 8
0
    def _raw_split_into_pieces(self, stmt):
        self.asttokens()
        start, end = line_range(stmt)

        for name, body in ast.iter_fields(stmt):
            if isinstance(body, list) and body and isinstance(
                    body[0], (ast.stmt, ast.ExceptHandler)):
                for sub_stmt in body:
                    for inner_start, inner_end in self._raw_split_into_pieces(
                            sub_stmt):
                        yield start, inner_start
                        yield inner_start, inner_end
                        start = inner_end

        yield start, end
Ejemplo n.º 9
0
    def variable_ranges(self):
        result = []
        for variable, node in self.frame_info.variables_by_lineno[self.lineno]:
            start, end = line_range(node)
            end -= 1
            assert start <= self.lineno <= end
            if start == self.lineno:
                range_start = node.first_token.start[1]
            else:
                range_start = 0

            if end == self.lineno:
                range_end = node.last_token.end[1]
            else:
                range_end = len(self.text)

            result.append(Range(
                range_start,
                range_end,
                (variable, node),
            ))

        return result