Ejemplo n.º 1
0
    def __str__(self):
        from vyper import ast as vy_ast
        from vyper.utils import annotate_source_code

        if not hasattr(self, "source_code"):
            if self.lineno is not None and self.col_offset is not None:
                return f"line {self.lineno}:{self.col_offset} {self.message}"
            else:
                return self.message

        msg = f"{self.message}\n"
        for node in self.nodes:
            try:
                source_annotation = annotate_source_code(
                    self.source_code,
                    node.lineno,
                    node.col_offset,
                    context_lines=VYPER_ERROR_CONTEXT_LINES,
                    line_numbers=VYPER_ERROR_LINE_NUMBERS,
                )
            except Exception:
                # necessary for certian types of syntax exceptions
                return msg

            if isinstance(node, vy_ast.VyperNode):
                fn_node = node.get_ancestor(vy_ast.FunctionDef)
                if fn_node:
                    msg += f"function '{fn_node.name}', "

            col_offset_str = "" if node.col_offset is None else str(
                node.col_offset)
            msg += f"line {node.lineno}:{col_offset_str} \n{source_annotation}\n"

        return msg
Ejemplo n.º 2
0
 def _annotated_source(self):
     # return source with context / line/col info
     return annotate_source_code(
         self.full_source_code,
         self.lineno,
         self.col_offset,
         context_lines=VYPER_ERROR_CONTEXT_LINES,
         line_numbers=VYPER_ERROR_LINE_NUMBERS,
     )
Ejemplo n.º 3
0
    def __repr__(self):
        cls = type(self)
        class_repr = f"{cls.__module__}.{cls.__qualname__}"

        source_annotation = annotate_source_code(
            self.full_source_code,
            self.lineno,
            self.col_offset,
            context_lines=VYPER_ERROR_CONTEXT_LINES,
            line_numbers=VYPER_ERROR_LINE_NUMBERS,
        )

        return f"{class_repr}:\n{source_annotation}"
Ejemplo n.º 4
0
    def __str__(self):
        from vyper import ast as vy_ast
        from vyper.utils import annotate_source_code

        if not hasattr(self, "annotations"):
            if self.lineno is not None and self.col_offset is not None:
                return f"line {self.lineno}:{self.col_offset} {self.message}"
            else:
                return self.message

        annotation_list = []
        for value in self.annotations:
            node = value[1] if isinstance(value, tuple) else value
            node_msg = ""

            try:
                source_annotation = annotate_source_code(
                    # add trailing space because EOF exceptions point one char beyond the length
                    f"{node.full_source_code} ",
                    node.lineno,
                    node.col_offset,
                    context_lines=VYPER_ERROR_CONTEXT_LINES,
                    line_numbers=VYPER_ERROR_LINE_NUMBERS,
                )
            except Exception:
                # necessary for certain types of syntax exceptions
                return self.message

            if isinstance(node, vy_ast.VyperNode):
                module_node = node.get_ancestor(vy_ast.Module)
                if module_node.get("name") not in (None, "<unknown>"):
                    node_msg = f'{node_msg}contract "{module_node.name}", '

                fn_node = node.get_ancestor(vy_ast.FunctionDef)
                if fn_node:
                    node_msg = f'{node_msg}function "{fn_node.name}", '

            col_offset_str = "" if node.col_offset is None else str(
                node.col_offset)
            node_msg = f"{node_msg}line {node.lineno}:{col_offset_str} \n{source_annotation}\n"

            if isinstance(value, tuple):
                # if annotation includes a message, apply it at the start and further indent
                node_msg = textwrap.indent(node_msg, "  ")
                node_msg = f"{value[0]}\n{node_msg}"

            node_msg = textwrap.indent(node_msg, "  ")
            annotation_list.append(node_msg)

        annotation_msg = "\n".join(annotation_list)
        return f"{self.message}\n{annotation_msg}"
Ejemplo n.º 5
0
    def __str__(self):
        lineno, col_offset = self.lineno, self.col_offset

        if lineno is not None and hasattr(self, 'source_code'):
            from vyper.utils import annotate_source_code

            source_annotation = annotate_source_code(
                self.source_code,
                lineno,
                col_offset,
                context_lines=VYPER_ERROR_CONTEXT_LINES,
                line_numbers=VYPER_ERROR_LINE_NUMBERS,
            )
            col_offset_str = '' if col_offset is None else str(col_offset)
            return f'line {lineno}:{col_offset_str} {self.message}\n{source_annotation}'

        elif lineno is not None and col_offset is not None:
            return f'line {lineno}:{col_offset} {self.message}'

        return self.message
Ejemplo n.º 6
0
def test_annotate_source_code_marks_positions_in_source_code():
    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      22,
                                      col_offset=16,
                                      context_lines=0,
                                      line_numbers=False)
    assert (annotation == r"""
    def __str__(self):
----------------^
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      22,
                                      col_offset=15,
                                      context_lines=1,
                                      line_numbers=False)
    assert (annotation == r"""

    def __str__(self):
---------------^
        output = self.message
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      22,
                                      col_offset=20,
                                      context_lines=2,
                                      line_numbers=False)
    assert (annotation == r"""
                self.col_offset = col_offset

    def __str__(self):
--------------------^
        output = self.message

"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      1,
                                      col_offset=5,
                                      context_lines=3,
                                      line_numbers=True)
    assert (annotation == r"""
---> 1 # Attempts to display the line and column of violating code.
------------^
     2 class ParserException(Exception):
     3     def __init__(self, message='Error Message not found.', item=None):
     4         self.message = message
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      36,
                                      col_offset=8,
                                      context_lines=4,
                                      line_numbers=True)
    assert (annotation == r"""
     32
     33         elif self.lineno is not None and self.col_offset is not None:
     34             output = f'line {self.lineno}:{self.col_offset} {output}'
     35
---> 36         return output
----------------^
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      15,
                                      col_offset=8,
                                      context_lines=11,
                                      line_numbers=True)
    assert (annotation == r"""
      4         self.message = message
      5         self.lineno = None
      6         self.col_offset = None
      7
      8         if isinstance(item, tuple):  # is a position.
      9             self.lineno, self.col_offset = item
     10         elif item and hasattr(item, 'lineno'):
     11             self.set_err_pos(item.lineno, item.col_offset)
     12             if hasattr(item, 'source_code'):
     13                 self.source_code = item.source_code.splitlines()
     14
---> 15     def set_err_pos(self, lineno, col_offset):
----------------^
     16         if not self.lineno:
     17             self.lineno = lineno
     18
     19             if not self.col_offset:
     20                 self.col_offset = col_offset
     21
     22     def __str__(self):
     23         output = self.message
     24
     25         if self.lineno and hasattr(self, 'source_code'):
     26
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      15,
                                      col_offset=None,
                                      context_lines=3,
                                      line_numbers=True)
    assert (annotation == r"""
     12             if hasattr(item, 'source_code'):
     13                 self.source_code = item.source_code.splitlines()
     14
---> 15     def set_err_pos(self, lineno, col_offset):
     16         if not self.lineno:
     17             self.lineno = lineno
     18
"""[1:-1])

    annotation = annotate_source_code(TEST_SOURCE_CODE,
                                      15,
                                      col_offset=None,
                                      context_lines=2,
                                      line_numbers=False)
    assert (annotation == r"""
                self.source_code = item.source_code.splitlines()

    def set_err_pos(self, lineno, col_offset):
        if not self.lineno:
            self.lineno = lineno
"""[1:-1])
Ejemplo n.º 7
0
def test_annotate_source_code_raises_value_errors(bad_lineno):
    with pytest.raises(ValueError, match="Line number is out of range"):
        annotate_source_code(TEST_SOURCE_CODE, bad_lineno)