Commits

Ian Cordasco committed 806577c

Migrate yaml.error

Comments (0)

Files changed (2)

 from io import StringIO
 
-from .error import *
+from .error import Mark, YAMLError, MarkedYAMLError
 
 from .tokens import *
 from .events import *
 __all__ = (
     'BaseDumper', 'Dumper', 'SafeDumper',
     'BaseLoader', 'Loader', 'SafeLoader',
+    'Mark', 'YAMLError', 'MarkedYAMLError',
 )
 
 try:
+CHAR_LIST = b'\0\r\n\xc2\x85\xe2\x80\xa8\xe2\x80\xa9'.decode('utf-8')
+
+__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
+
+
+class Mark:
+    def __init__(self, name, index, line, column, buffer, pointer):
+        self.name = name
+        self.index = index
+        self.line = line
+        self.column = column
+        self.buffer = buffer
+        self.pointer = pointer
+
+    def get_snippet(self, indent=4, max_length=75):
+        if self.buffer is None:
+            return None
+        head = ''
+        start = self.pointer
+        while start > 0 and self.buffer[start - 1] not in CHAR_LIST:
+            start -= 1
+            if self.pointer-start > max_length/2-1:
+                head = ' ... '
+                start += 5
+                break
+        tail = ''
+        end = self.pointer
+        while end < len(self.buffer) and self.buffer[end] not in CHAR_LIST:
+            end += 1
+            if (end - self.pointer) > ((max_length / 2) - 1):
+                tail = ' ... '
+                end -= 5
+                break
+        snippet = self.buffer[start:end]
+        return ((' ' * indent) + head + snippet + tail + '\n'
+                + (' ' * (indent + self.pointer - start + len(head))) + '^')
+
+    def __str__(self):
+        snippet = self.get_snippet()
+        where = ("  in \"%s\", line %d, column %d"
+                 % (self.name, self.line + 1, self.column + 1))
+        if snippet is not None:
+            where += ":\n" + snippet
+        return where
+
+
+class YAMLError(Exception):
+    pass
+
+
+class MarkedYAMLError(YAMLError):
+    def __init__(self, context=None, context_mark=None,
+                 problem=None, problem_mark=None, note=None):
+        self.context = context
+        self.context_mark = context_mark
+        self.problem = problem
+        self.problem_mark = problem_mark
+        self.note = note
+
+    def __str__(self):
+        lines = []
+        if self.context is not None:
+            lines.append(self.context)
+        if (self.context_mark is not None
+            and (self.problem is None or self.problem_mark is None
+                 or self.context_mark.name != self.problem_mark.name
+                 or self.context_mark.line != self.problem_mark.line
+                 or self.context_mark.column != self.problem_mark.column)):
+            lines.append(str(self.context_mark))
+        if self.problem is not None:
+            lines.append(self.problem)
+        if self.problem_mark is not None:
+            lines.append(str(self.problem_mark))
+        if self.note is not None:
+            lines.append(self.note)
+        return '\n'.join(lines)