summaryrefslogtreecommitdiff
path: root/error.py
blob: 5015828969a459d5212831b3d1a4befad522320a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# coding: utf-8

from __future__ import absolute_import

import warnings

from ruamel.yaml.compat import utf8

__all__ = ['FileMark', 'StringMark', 'CommentMark',
           'YAMLError', 'MarkedYAMLError', 'ReusedAnchorWarning',
           'UnsafeLoaderWarning']


class StreamMark(object):
    __slots__ = 'name', 'index', 'line', 'column',

    def __init__(self, name, index, line, column):
        self.name = name
        self.index = index
        self.line = line
        self.column = column

    def __str__(self):
        where = "  in \"%s\", line %d, column %d"   \
                % (self.name, self.line+1, self.column+1)
        return where


class FileMark(StreamMark):
    __slots__ = ()


class StringMark(StreamMark):
    __slots__ = 'name', 'index', 'line', 'column', 'buffer', 'pointer',

    def __init__(self, name, index, line, column, buffer, pointer):
        StreamMark.__init__(self, name, index, line, column)
        self.buffer = buffer
        self.pointer = pointer

    def get_snippet(self, indent=4, max_length=75):
        if self.buffer is None:  # always False
            return None
        head = ''
        start = self.pointer
        while (start > 0 and
               self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029'):
            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 u'\0\r\n\x85\u2028\u2029'):
            end += 1
            if end-self.pointer > max_length/2-1:
                tail = ' ... '
                end -= 5
                break
        snippet = utf8(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 CommentMark(object):
    __slots__ = 'column',

    def __init__(self, column):
        self.column = column


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)


class ReusedAnchorWarning(Warning):
    pass


class UnsafeLoaderWarning(Warning):
    text = """
The default 'Loader' for 'load(stream)' without further arguments can be unsafe.
Use 'load(stream, Loader=ruamel.yaml.Loader)' explicitly if that is OK.
Alternatively include the following in your code:

  import warnings
  warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)

In most other cases you should consider using 'safe_load(stream)'"""
    pass

warnings.simplefilter('once', UnsafeLoaderWarning)