@cryptotaxi247 / netdata-1 / commits / 313f18b7e

remove pyyaml2 (#18404)

Ilya Mashchenko committed Aug 24, 2024 at 20:14 UTC 313f18b7e381952d93fe8b37a68ec77227ea7ba6
19 files changed +2 -5855
.codacy.yml
-1
@@ -1,6 +1,5 @@
1 ---
2 exclude_paths:
3 - - src/collectors/python.d.plugin/python_modules/pyyaml2/**
3 - src/collectors/python.d.plugin/python_modules/pyyaml3/**
4 - src/collectors/python.d.plugin/python_modules/urllib3/**
5 - src/collectors/python.d.plugin/python_modules/third_party/**
src/collectors/python.d.plugin/python_modules/bases/loaders.py
+2 -12
@@ -3,27 +3,17 @@
3 # Author: Ilya Mashchenko (ilyam8)
4 # SPDX-License-Identifier: GPL-3.0-or-later
5
6 -
7 -from sys import version_info
8 -
9 -PY_VERSION = version_info[:2]
10 -
6 try:
12 - if PY_VERSION > (3, 1):
13 - from pyyaml3 import SafeLoader as YamlSafeLoader
14 - else:
15 - from pyyaml2 import SafeLoader as YamlSafeLoader
7 + from pyyaml3 import SafeLoader as YamlSafeLoader
8 except ImportError:
9 from yaml import SafeLoader as YamlSafeLoader
10
19 -
11 try:
12 from collections import OrderedDict
13 except ImportError:
14 from third_party.ordereddict import OrderedDict
15
25 -
26 -DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map' if PY_VERSION > (3, 1) else u'tag:yaml.org,2002:map'
16 +DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
17
18
19 def dict_constructor(loader, node):
src/collectors/python.d.plugin/python_modules/pyyaml2/__init__.py deleted
-316
@@ -1,316 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -from error import *
4 -
5 -from tokens import *
6 -from events import *
7 -from nodes import *
8 -
9 -from loader import *
10 -from dumper import *
11 -
12 -__version__ = '3.11'
13 -
14 -try:
15 - from cyaml import *
16 - __with_libyaml__ = True
17 -except ImportError:
18 - __with_libyaml__ = False
19 -
20 -def scan(stream, Loader=Loader):
21 - """
22 - Scan a YAML stream and produce scanning tokens.
23 - """
24 - loader = Loader(stream)
25 - try:
26 - while loader.check_token():
27 - yield loader.get_token()
28 - finally:
29 - loader.dispose()
30 -
31 -def parse(stream, Loader=Loader):
32 - """
33 - Parse a YAML stream and produce parsing events.
34 - """
35 - loader = Loader(stream)
36 - try:
37 - while loader.check_event():
38 - yield loader.get_event()
39 - finally:
40 - loader.dispose()
41 -
42 -def compose(stream, Loader=Loader):
43 - """
44 - Parse the first YAML document in a stream
45 - and produce the corresponding representation tree.
46 - """
47 - loader = Loader(stream)
48 - try:
49 - return loader.get_single_node()
50 - finally:
51 - loader.dispose()
52 -
53 -def compose_all(stream, Loader=Loader):
54 - """
55 - Parse all YAML documents in a stream
56 - and produce corresponding representation trees.
57 - """
58 - loader = Loader(stream)
59 - try:
60 - while loader.check_node():
61 - yield loader.get_node()
62 - finally:
63 - loader.dispose()
64 -
65 -def load(stream, Loader=Loader):
66 - """
67 - Parse the first YAML document in a stream
68 - and produce the corresponding Python object.
69 - """
70 - loader = Loader(stream)
71 - try:
72 - return loader.get_single_data()
73 - finally:
74 - loader.dispose()
75 -
76 -def load_all(stream, Loader=Loader):
77 - """
78 - Parse all YAML documents in a stream
79 - and produce corresponding Python objects.
80 - """
81 - loader = Loader(stream)
82 - try:
83 - while loader.check_data():
84 - yield loader.get_data()
85 - finally:
86 - loader.dispose()
87 -
88 -def safe_load(stream):
89 - """
90 - Parse the first YAML document in a stream
91 - and produce the corresponding Python object.
92 - Resolve only basic YAML tags.
93 - """
94 - return load(stream, SafeLoader)
95 -
96 -def safe_load_all(stream):
97 - """
98 - Parse all YAML documents in a stream
99 - and produce corresponding Python objects.
100 - Resolve only basic YAML tags.
101 - """
102 - return load_all(stream, SafeLoader)
103 -
104 -def emit(events, stream=None, Dumper=Dumper,
105 - canonical=None, indent=None, width=None,
106 - allow_unicode=None, line_break=None):
107 - """
108 - Emit YAML parsing events into a stream.
109 - If stream is None, return the produced string instead.
110 - """
111 - getvalue = None
112 - if stream is None:
113 - from StringIO import StringIO
114 - stream = StringIO()
115 - getvalue = stream.getvalue
116 - dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
117 - allow_unicode=allow_unicode, line_break=line_break)
118 - try:
119 - for event in events:
120 - dumper.emit(event)
121 - finally:
122 - dumper.dispose()
123 - if getvalue:
124 - return getvalue()
125 -
126 -def serialize_all(nodes, stream=None, Dumper=Dumper,
127 - canonical=None, indent=None, width=None,
128 - allow_unicode=None, line_break=None,
129 - encoding='utf-8', explicit_start=None, explicit_end=None,
130 - version=None, tags=None):
131 - """
132 - Serialize a sequence of representation trees into a YAML stream.
133 - If stream is None, return the produced string instead.
134 - """
135 - getvalue = None
136 - if stream is None:
137 - if encoding is None:
138 - from StringIO import StringIO
139 - else:
140 - from cStringIO import StringIO
141 - stream = StringIO()
142 - getvalue = stream.getvalue
143 - dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
144 - allow_unicode=allow_unicode, line_break=line_break,
145 - encoding=encoding, version=version, tags=tags,
146 - explicit_start=explicit_start, explicit_end=explicit_end)
147 - try:
148 - dumper.open()
149 - for node in nodes:
150 - dumper.serialize(node)
151 - dumper.close()
152 - finally:
153 - dumper.dispose()
154 - if getvalue:
155 - return getvalue()
156 -
157 -def serialize(node, stream=None, Dumper=Dumper, **kwds):
158 - """
159 - Serialize a representation tree into a YAML stream.
160 - If stream is None, return the produced string instead.
161 - """
162 - return serialize_all([node], stream, Dumper=Dumper, **kwds)
163 -
164 -def dump_all(documents, stream=None, Dumper=Dumper,
165 - default_style=None, default_flow_style=None,
166 - canonical=None, indent=None, width=None,
167 - allow_unicode=None, line_break=None,
168 - encoding='utf-8', explicit_start=None, explicit_end=None,
169 - version=None, tags=None):
170 - """
171 - Serialize a sequence of Python objects into a YAML stream.
172 - If stream is None, return the produced string instead.
173 - """
174 - getvalue = None
175 - if stream is None:
176 - if encoding is None:
177 - from StringIO import StringIO
178 - else:
179 - from cStringIO import StringIO
180 - stream = StringIO()
181 - getvalue = stream.getvalue
182 - dumper = Dumper(stream, default_style=default_style,
183 - default_flow_style=default_flow_style,
184 - canonical=canonical, indent=indent, width=width,
185 - allow_unicode=allow_unicode, line_break=line_break,
186 - encoding=encoding, version=version, tags=tags,
187 - explicit_start=explicit_start, explicit_end=explicit_end)
188 - try:
189 - dumper.open()
190 - for data in documents:
191 - dumper.represent(data)
192 - dumper.close()
193 - finally:
194 - dumper.dispose()
195 - if getvalue:
196 - return getvalue()
197 -
198 -def dump(data, stream=None, Dumper=Dumper, **kwds):
199 - """
200 - Serialize a Python object into a YAML stream.
201 - If stream is None, return the produced string instead.
202 - """
203 - return dump_all([data], stream, Dumper=Dumper, **kwds)
204 -
205 -def safe_dump_all(documents, stream=None, **kwds):
206 - """
207 - Serialize a sequence of Python objects into a YAML stream.
208 - Produce only basic YAML tags.
209 - If stream is None, return the produced string instead.
210 - """
211 - return dump_all(documents, stream, Dumper=SafeDumper, **kwds)
212 -
213 -def safe_dump(data, stream=None, **kwds):
214 - """
215 - Serialize a Python object into a YAML stream.
216 - Produce only basic YAML tags.
217 - If stream is None, return the produced string instead.
218 - """
219 - return dump_all([data], stream, Dumper=SafeDumper, **kwds)
220 -
221 -def add_implicit_resolver(tag, regexp, first=None,
222 - Loader=Loader, Dumper=Dumper):
223 - """
224 - Add an implicit scalar detector.
225 - If an implicit scalar value matches the given regexp,
226 - the corresponding tag is assigned to the scalar.
227 - first is a sequence of possible initial characters or None.
228 - """
229 - Loader.add_implicit_resolver(tag, regexp, first)
230 - Dumper.add_implicit_resolver(tag, regexp, first)
231 -
232 -def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper):
233 - """
234 - Add a path based resolver for the given tag.
235 - A path is a list of keys that forms a path
236 - to a node in the representation tree.
237 - Keys can be string values, integers, or None.
238 - """
239 - Loader.add_path_resolver(tag, path, kind)
240 - Dumper.add_path_resolver(tag, path, kind)
241 -
242 -def add_constructor(tag, constructor, Loader=Loader):
243 - """
244 - Add a constructor for the given tag.
245 - Constructor is a function that accepts a Loader instance
246 - and a node object and produces the corresponding Python object.
247 - """
248 - Loader.add_constructor(tag, constructor)
249 -
250 -def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader):
251 - """
252 - Add a multi-constructor for the given tag prefix.
253 - Multi-constructor is called for a node if its tag starts with tag_prefix.
254 - Multi-constructor accepts a Loader instance, a tag suffix,
255 - and a node object and produces the corresponding Python object.
256 - """
257 - Loader.add_multi_constructor(tag_prefix, multi_constructor)
258 -
259 -def add_representer(data_type, representer, Dumper=Dumper):
260 - """
261 - Add a representer for the given type.
262 - Representer is a function accepting a Dumper instance
263 - and an instance of the given data type
264 - and producing the corresponding representation node.
265 - """
266 - Dumper.add_representer(data_type, representer)
267 -
268 -def add_multi_representer(data_type, multi_representer, Dumper=Dumper):
269 - """
270 - Add a representer for the given type.
271 - Multi-representer is a function accepting a Dumper instance
272 - and an instance of the given data type or subtype
273 - and producing the corresponding representation node.
274 - """
275 - Dumper.add_multi_representer(data_type, multi_representer)
276 -
277 -class YAMLObjectMetaclass(type):
278 - """
279 - The metaclass for YAMLObject.
280 - """
281 - def __init__(cls, name, bases, kwds):
282 - super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
283 - if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
284 - cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
285 - cls.yaml_dumper.add_representer(cls, cls.to_yaml)
286 -
287 -class YAMLObject(object):
288 - """
289 - An object that can dump itself to a YAML stream
290 - and load itself from a YAML stream.
291 - """
292 -
293 - __metaclass__ = YAMLObjectMetaclass
294 - __slots__ = () # no direct instantiation, so allow immutable subclasses
295 -
296 - yaml_loader = Loader
297 - yaml_dumper = Dumper
298 -
299 - yaml_tag = None
300 - yaml_flow_style = None
301 -
302 - def from_yaml(cls, loader, node):
303 - """
304 - Convert a representation node to a Python object.
305 - """
306 - return loader.construct_yaml_object(node, cls)
307 - from_yaml = classmethod(from_yaml)
308 -
309 - def to_yaml(cls, dumper, data):
310 - """
311 - Convert a Python object to a representation node.
312 - """
313 - return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
314 - flow_style=cls.yaml_flow_style)
315 - to_yaml = classmethod(to_yaml)
316 -
src/collectors/python.d.plugin/python_modules/pyyaml2/composer.py deleted
-140
@@ -1,140 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['Composer', 'ComposerError']
4 -
5 -from error import MarkedYAMLError
6 -from events import *
7 -from nodes import *
8 -
9 -class ComposerError(MarkedYAMLError):
10 - pass
11 -
12 -class Composer(object):
13 -
14 - def __init__(self):
15 - self.anchors = {}
16 -
17 - def check_node(self):
18 - # Drop the STREAM-START event.
19 - if self.check_event(StreamStartEvent):
20 - self.get_event()
21 -
22 - # If there are more documents available?
23 - return not self.check_event(StreamEndEvent)
24 -
25 - def get_node(self):
26 - # Get the root node of the next document.
27 - if not self.check_event(StreamEndEvent):
28 - return self.compose_document()
29 -
30 - def get_single_node(self):
31 - # Drop the STREAM-START event.
32 - self.get_event()
33 -
34 - # Compose a document if the stream is not empty.
35 - document = None
36 - if not self.check_event(StreamEndEvent):
37 - document = self.compose_document()
38 -
39 - # Ensure that the stream contains no more documents.
40 - if not self.check_event(StreamEndEvent):
41 - event = self.get_event()
42 - raise ComposerError("expected a single document in the stream",
43 - document.start_mark, "but found another document",
44 - event.start_mark)
45 -
46 - # Drop the STREAM-END event.
47 - self.get_event()
48 -
49 - return document
50 -
51 - def compose_document(self):
52 - # Drop the DOCUMENT-START event.
53 - self.get_event()
54 -
55 - # Compose the root node.
56 - node = self.compose_node(None, None)
57 -
58 - # Drop the DOCUMENT-END event.
59 - self.get_event()
60 -
61 - self.anchors = {}
62 - return node
63 -
64 - def compose_node(self, parent, index):
65 - if self.check_event(AliasEvent):
66 - event = self.get_event()
67 - anchor = event.anchor
68 - if anchor not in self.anchors:
69 - raise ComposerError(None, None, "found undefined alias %r"
70 - % anchor.encode('utf-8'), event.start_mark)
71 - return self.anchors[anchor]
72 - event = self.peek_event()
73 - anchor = event.anchor
74 - if anchor is not None:
75 - if anchor in self.anchors:
76 - raise ComposerError("found duplicate anchor %r; first occurence"
77 - % anchor.encode('utf-8'), self.anchors[anchor].start_mark,
78 - "second occurence", event.start_mark)
79 - self.descend_resolver(parent, index)
80 - if self.check_event(ScalarEvent):
81 - node = self.compose_scalar_node(anchor)
82 - elif self.check_event(SequenceStartEvent):
83 - node = self.compose_sequence_node(anchor)
84 - elif self.check_event(MappingStartEvent):
85 - node = self.compose_mapping_node(anchor)
86 - self.ascend_resolver()
87 - return node
88 -
89 - def compose_scalar_node(self, anchor):
90 - event = self.get_event()
91 - tag = event.tag
92 - if tag is None or tag == u'!':
93 - tag = self.resolve(ScalarNode, event.value, event.implicit)
94 - node = ScalarNode(tag, event.value,
95 - event.start_mark, event.end_mark, style=event.style)
96 - if anchor is not None:
97 - self.anchors[anchor] = node
98 - return node
99 -
100 - def compose_sequence_node(self, anchor):
101 - start_event = self.get_event()
102 - tag = start_event.tag
103 - if tag is None or tag == u'!':
104 - tag = self.resolve(SequenceNode, None, start_event.implicit)
105 - node = SequenceNode(tag, [],
106 - start_event.start_mark, None,
107 - flow_style=start_event.flow_style)
108 - if anchor is not None:
109 - self.anchors[anchor] = node
110 - index = 0
111 - while not self.check_event(SequenceEndEvent):
112 - node.value.append(self.compose_node(node, index))
113 - index += 1
114 - end_event = self.get_event()
115 - node.end_mark = end_event.end_mark
116 - return node
117 -
118 - def compose_mapping_node(self, anchor):
119 - start_event = self.get_event()
120 - tag = start_event.tag
121 - if tag is None or tag == u'!':
122 - tag = self.resolve(MappingNode, None, start_event.implicit)
123 - node = MappingNode(tag, [],
124 - start_event.start_mark, None,
125 - flow_style=start_event.flow_style)
126 - if anchor is not None:
127 - self.anchors[anchor] = node
128 - while not self.check_event(MappingEndEvent):
129 - #key_event = self.peek_event()
130 - item_key = self.compose_node(node, None)
131 - #if item_key in node.value:
132 - # raise ComposerError("while composing a mapping", start_event.start_mark,
133 - # "found duplicate key", key_event.start_mark)
134 - item_value = self.compose_node(node, item_key)
135 - #node.value[item_key] = item_value
136 - node.value.append((item_key, item_value))
137 - end_event = self.get_event()
138 - node.end_mark = end_event.end_mark
139 - return node
140 -
src/collectors/python.d.plugin/python_modules/pyyaml2/constructor.py deleted
-676
@@ -1,676 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
4 - 'ConstructorError']
5 -
6 -from error import *
7 -from nodes import *
8 -
9 -import datetime
10 -
11 -import binascii, re, sys, types
12 -
13 -class ConstructorError(MarkedYAMLError):
14 - pass
15 -
16 -class BaseConstructor(object):
17 -
18 - yaml_constructors = {}
19 - yaml_multi_constructors = {}
20 -
21 - def __init__(self):
22 - self.constructed_objects = {}
23 - self.recursive_objects = {}
24 - self.state_generators = []
25 - self.deep_construct = False
26 -
27 - def check_data(self):
28 - # If there are more documents available?
29 - return self.check_node()
30 -
31 - def get_data(self):
32 - # Construct and return the next document.
33 - if self.check_node():
34 - return self.construct_document(self.get_node())
35 -
36 - def get_single_data(self):
37 - # Ensure that the stream contains a single document and construct it.
38 - node = self.get_single_node()
39 - if node is not None:
40 - return self.construct_document(node)
41 - return None
42 -
43 - def construct_document(self, node):
44 - data = self.construct_object(node)
45 - while self.state_generators:
46 - state_generators = self.state_generators
47 - self.state_generators = []
48 - for generator in state_generators:
49 - for dummy in generator:
50 - pass
51 - self.constructed_objects = {}
52 - self.recursive_objects = {}
53 - self.deep_construct = False
54 - return data
55 -
56 - def construct_object(self, node, deep=False):
57 - if node in self.constructed_objects:
58 - return self.constructed_objects[node]
59 - if deep:
60 - old_deep = self.deep_construct
61 - self.deep_construct = True
62 - if node in self.recursive_objects:
63 - raise ConstructorError(None, None,
64 - "found unconstructable recursive node", node.start_mark)
65 - self.recursive_objects[node] = None
66 - constructor = None
67 - tag_suffix = None
68 - if node.tag in self.yaml_constructors:
69 - constructor = self.yaml_constructors[node.tag]
70 - else:
71 - for tag_prefix in self.yaml_multi_constructors:
72 - if node.tag.startswith(tag_prefix):
73 - tag_suffix = node.tag[len(tag_prefix):]
74 - constructor = self.yaml_multi_constructors[tag_prefix]
75 - break
76 - else:
77 - if None in self.yaml_multi_constructors:
78 - tag_suffix = node.tag
79 - constructor = self.yaml_multi_constructors[None]
80 - elif None in self.yaml_constructors:
81 - constructor = self.yaml_constructors[None]
82 - elif isinstance(node, ScalarNode):
83 - constructor = self.__class__.construct_scalar
84 - elif isinstance(node, SequenceNode):
85 - constructor = self.__class__.construct_sequence
86 - elif isinstance(node, MappingNode):
87 - constructor = self.__class__.construct_mapping
88 - if tag_suffix is None:
89 - data = constructor(self, node)
90 - else:
91 - data = constructor(self, tag_suffix, node)
92 - if isinstance(data, types.GeneratorType):
93 - generator = data
94 - data = generator.next()
95 - if self.deep_construct:
96 - for dummy in generator:
97 - pass
98 - else:
99 - self.state_generators.append(generator)
100 - self.constructed_objects[node] = data
101 - del self.recursive_objects[node]
102 - if deep:
103 - self.deep_construct = old_deep
104 - return data
105 -
106 - def construct_scalar(self, node):
107 - if not isinstance(node, ScalarNode):
108 - raise ConstructorError(None, None,
109 - "expected a scalar node, but found %s" % node.id,
110 - node.start_mark)
111 - return node.value
112 -
113 - def construct_sequence(self, node, deep=False):
114 - if not isinstance(node, SequenceNode):
115 - raise ConstructorError(None, None,
116 - "expected a sequence node, but found %s" % node.id,
117 - node.start_mark)
118 - return [self.construct_object(child, deep=deep)
119 - for child in node.value]
120 -
121 - def construct_mapping(self, node, deep=False):
122 - if not isinstance(node, MappingNode):
123 - raise ConstructorError(None, None,
124 - "expected a mapping node, but found %s" % node.id,
125 - node.start_mark)
126 - mapping = {}
127 - for key_node, value_node in node.value:
128 - key = self.construct_object(key_node, deep=deep)
129 - try:
130 - hash(key)
131 - except TypeError, exc:
132 - raise ConstructorError("while constructing a mapping", node.start_mark,
133 - "found unacceptable key (%s)" % exc, key_node.start_mark)
134 - value = self.construct_object(value_node, deep=deep)
135 - mapping[key] = value
136 - return mapping
137 -
138 - def construct_pairs(self, node, deep=False):
139 - if not isinstance(node, MappingNode):
140 - raise ConstructorError(None, None,
141 - "expected a mapping node, but found %s" % node.id,
142 - node.start_mark)
143 - pairs = []
144 - for key_node, value_node in node.value:
145 - key = self.construct_object(key_node, deep=deep)
146 - value = self.construct_object(value_node, deep=deep)
147 - pairs.append((key, value))
148 - return pairs
149 -
150 - def add_constructor(cls, tag, constructor):
151 - if not 'yaml_constructors' in cls.__dict__:
152 - cls.yaml_constructors = cls.yaml_constructors.copy()
153 - cls.yaml_constructors[tag] = constructor
154 - add_constructor = classmethod(add_constructor)
155 -
156 - def add_multi_constructor(cls, tag_prefix, multi_constructor):
157 - if not 'yaml_multi_constructors' in cls.__dict__:
158 - cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
159 - cls.yaml_multi_constructors[tag_prefix] = multi_constructor
160 - add_multi_constructor = classmethod(add_multi_constructor)
161 -
162 -class SafeConstructor(BaseConstructor):
163 -
164 - def construct_scalar(self, node):
165 - if isinstance(node, MappingNode):
166 - for key_node, value_node in node.value:
167 - if key_node.tag == u'tag:yaml.org,2002:value':
168 - return self.construct_scalar(value_node)
169 - return BaseConstructor.construct_scalar(self, node)
170 -
171 - def flatten_mapping(self, node):
172 - merge = []
173 - index = 0
174 - while index < len(node.value):
175 - key_node, value_node = node.value[index]
176 - if key_node.tag == u'tag:yaml.org,2002:merge':
177 - del node.value[index]
178 - if isinstance(value_node, MappingNode):
179 - self.flatten_mapping(value_node)
180 - merge.extend(value_node.value)
181 - elif isinstance(value_node, SequenceNode):
182 - submerge = []
183 - for subnode in value_node.value:
184 - if not isinstance(subnode, MappingNode):
185 - raise ConstructorError("while constructing a mapping",
186 - node.start_mark,
187 - "expected a mapping for merging, but found %s"
188 - % subnode.id, subnode.start_mark)
189 - self.flatten_mapping(subnode)
190 - submerge.append(subnode.value)
191 - submerge.reverse()
192 - for value in submerge:
193 - merge.extend(value)
194 - else:
195 - raise ConstructorError("while constructing a mapping", node.start_mark,
196 - "expected a mapping or list of mappings for merging, but found %s"
197 - % value_node.id, value_node.start_mark)
198 - elif key_node.tag == u'tag:yaml.org,2002:value':
199 - key_node.tag = u'tag:yaml.org,2002:str'
200 - index += 1
201 - else:
202 - index += 1
203 - if merge:
204 - node.value = merge + node.value
205 -
206 - def construct_mapping(self, node, deep=False):
207 - if isinstance(node, MappingNode):
208 - self.flatten_mapping(node)
209 - return BaseConstructor.construct_mapping(self, node, deep=deep)
210 -
211 - def construct_yaml_null(self, node):
212 - self.construct_scalar(node)
213 - return None
214 -
215 - bool_values = {
216 - u'yes': True,
217 - u'no': False,
218 - u'true': True,
219 - u'false': False,
220 - u'on': True,
221 - u'off': False,
222 - }
223 -
224 - def construct_yaml_bool(self, node):
225 - value = self.construct_scalar(node)
226 - return self.bool_values[value.lower()]
227 -
228 - def construct_yaml_int(self, node):
229 - value = str(self.construct_scalar(node))
230 - value = value.replace('_', '')
231 - sign = +1
232 - if value[0] == '-':
233 - sign = -1
234 - if value[0] in '+-':
235 - value = value[1:]
236 - if value == '0':
237 - return 0
238 - elif value.startswith('0b'):
239 - return sign*int(value[2:], 2)
240 - elif value.startswith('0x'):
241 - return sign*int(value[2:], 16)
242 - elif value[0] == '0':
243 - return sign*int(value, 8)
244 - elif ':' in value:
245 - digits = [int(part) for part in value.split(':')]
246 - digits.reverse()
247 - base = 1
248 - value = 0
249 - for digit in digits:
250 - value += digit*base
251 - base *= 60
252 - return sign*value
253 - else:
254 - return sign*int(value)
255 -
256 - inf_value = 1e300
257 - while inf_value != inf_value*inf_value:
258 - inf_value *= inf_value
259 - nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99).
260 -
261 - def construct_yaml_float(self, node):
262 - value = str(self.construct_scalar(node))
263 - value = value.replace('_', '').lower()
264 - sign = +1
265 - if value[0] == '-':
266 - sign = -1
267 - if value[0] in '+-':
268 - value = value[1:]
269 - if value == '.inf':
270 - return sign*self.inf_value
271 - elif value == '.nan':
272 - return self.nan_value
273 - elif ':' in value:
274 - digits = [float(part) for part in value.split(':')]
275 - digits.reverse()
276 - base = 1
277 - value = 0.0
278 - for digit in digits:
279 - value += digit*base
280 - base *= 60
281 - return sign*value
282 - else:
283 - return sign*float(value)
284 -
285 - def construct_yaml_binary(self, node):
286 - value = self.construct_scalar(node)
287 - try:
288 - return str(value).decode('base64')
289 - except (binascii.Error, UnicodeEncodeError), exc:
290 - raise ConstructorError(None, None,
291 - "failed to decode base64 data: %s" % exc, node.start_mark)
292 -
293 - timestamp_regexp = re.compile(
294 - ur'''^(?P<year>[0-9][0-9][0-9][0-9])
295 - -(?P<month>[0-9][0-9]?)
296 - -(?P<day>[0-9][0-9]?)
297 - (?:(?:[Tt]|[ \t]+)
298 - (?P<hour>[0-9][0-9]?)
299 - :(?P<minute>[0-9][0-9])
300 - :(?P<second>[0-9][0-9])
301 - (?:\.(?P<fraction>[0-9]*))?
302 - (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
303 - (?::(?P<tz_minute>[0-9][0-9]))?))?)?$''', re.X)
304 -
305 - def construct_yaml_timestamp(self, node):
306 - value = self.construct_scalar(node)
307 - match = self.timestamp_regexp.match(node.value)
308 - values = match.groupdict()
309 - year = int(values['year'])
310 - month = int(values['month'])
311 - day = int(values['day'])
312 - if not values['hour']:
313 - return datetime.date(year, month, day)
314 - hour = int(values['hour'])
315 - minute = int(values['minute'])
316 - second = int(values['second'])
317 - fraction = 0
318 - if values['fraction']:
319 - fraction = values['fraction'][:6]
320 - while len(fraction) < 6:
321 - fraction += '0'
322 - fraction = int(fraction)
323 - delta = None
324 - if values['tz_sign']:
325 - tz_hour = int(values['tz_hour'])
326 - tz_minute = int(values['tz_minute'] or 0)
327 - delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
328 - if values['tz_sign'] == '-':
329 - delta = -delta
330 - data = datetime.datetime(year, month, day, hour, minute, second, fraction)
331 - if delta:
332 - data -= delta
333 - return data
334 -
335 - def construct_yaml_omap(self, node):
336 - # Note: we do not check for duplicate keys, because it's too
337 - # CPU-expensive.
338 - omap = []
339 - yield omap
340 - if not isinstance(node, SequenceNode):
341 - raise ConstructorError("while constructing an ordered map", node.start_mark,
342 - "expected a sequence, but found %s" % node.id, node.start_mark)
343 - for subnode in node.value:
344 - if not isinstance(subnode, MappingNode):
345 - raise ConstructorError("while constructing an ordered map", node.start_mark,
346 - "expected a mapping of length 1, but found %s" % subnode.id,
347 - subnode.start_mark)
348 - if len(subnode.value) != 1:
349 - raise ConstructorError("while constructing an ordered map", node.start_mark,
350 - "expected a single mapping item, but found %d items" % len(subnode.value),
351 - subnode.start_mark)
352 - key_node, value_node = subnode.value[0]
353 - key = self.construct_object(key_node)
354 - value = self.construct_object(value_node)
355 - omap.append((key, value))
356 -
357 - def construct_yaml_pairs(self, node):
358 - # Note: the same code as `construct_yaml_omap`.
359 - pairs = []
360 - yield pairs
361 - if not isinstance(node, SequenceNode):
362 - raise ConstructorError("while constructing pairs", node.start_mark,
363 - "expected a sequence, but found %s" % node.id, node.start_mark)
364 - for subnode in node.value:
365 - if not isinstance(subnode, MappingNode):
366 - raise ConstructorError("while constructing pairs", node.start_mark,
367 - "expected a mapping of length 1, but found %s" % subnode.id,
368 - subnode.start_mark)
369 - if len(subnode.value) != 1:
370 - raise ConstructorError("while constructing pairs", node.start_mark,
371 - "expected a single mapping item, but found %d items" % len(subnode.value),
372 - subnode.start_mark)
373 - key_node, value_node = subnode.value[0]
374 - key = self.construct_object(key_node)
375 - value = self.construct_object(value_node)
376 - pairs.append((key, value))
377 -
378 - def construct_yaml_set(self, node):
379 - data = set()
380 - yield data
381 - value = self.construct_mapping(node)
382 - data.update(value)
383 -
384 - def construct_yaml_str(self, node):
385 - value = self.construct_scalar(node)
386 - try:
387 - return value.encode('ascii')
388 - except UnicodeEncodeError:
389 - return value
390 -
391 - def construct_yaml_seq(self, node):
392 - data = []
393 - yield data
394 - data.extend(self.construct_sequence(node))
395 -
396 - def construct_yaml_map(self, node):
397 - data = {}
398 - yield data
399 - value = self.construct_mapping(node)
400 - data.update(value)
401 -
402 - def construct_yaml_object(self, node, cls):
403 - data = cls.__new__(cls)
404 - yield data
405 - if hasattr(data, '__setstate__'):
406 - state = self.construct_mapping(node, deep=True)
407 - data.__setstate__(state)
408 - else:
409 - state = self.construct_mapping(node)
410 - data.__dict__.update(state)
411 -
412 - def construct_undefined(self, node):
413 - raise ConstructorError(None, None,
414 - "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'),
415 - node.start_mark)
416 -
417 -SafeConstructor.add_constructor(
418 - u'tag:yaml.org,2002:null',
419 - SafeConstructor.construct_yaml_null)
420 -
421 -SafeConstructor.add_constructor(
422 - u'tag:yaml.org,2002:bool',
423 - SafeConstructor.construct_yaml_bool)
424 -
425 -SafeConstructor.add_constructor(
426 - u'tag:yaml.org,2002:int',
427 - SafeConstructor.construct_yaml_int)
428 -
429 -SafeConstructor.add_constructor(
430 - u'tag:yaml.org,2002:float',
431 - SafeConstructor.construct_yaml_float)
432 -
433 -SafeConstructor.add_constructor(
434 - u'tag:yaml.org,2002:binary',
435 - SafeConstructor.construct_yaml_binary)
436 -
437 -SafeConstructor.add_constructor(
438 - u'tag:yaml.org,2002:timestamp',
439 - SafeConstructor.construct_yaml_timestamp)
440 -
441 -SafeConstructor.add_constructor(
442 - u'tag:yaml.org,2002:omap',
443 - SafeConstructor.construct_yaml_omap)
444 -
445 -SafeConstructor.add_constructor(
446 - u'tag:yaml.org,2002:pairs',
447 - SafeConstructor.construct_yaml_pairs)
448 -
449 -SafeConstructor.add_constructor(
450 - u'tag:yaml.org,2002:set',
451 - SafeConstructor.construct_yaml_set)
452 -
453 -SafeConstructor.add_constructor(
454 - u'tag:yaml.org,2002:str',
455 - SafeConstructor.construct_yaml_str)
456 -
457 -SafeConstructor.add_constructor(
458 - u'tag:yaml.org,2002:seq',
459 - SafeConstructor.construct_yaml_seq)
460 -
461 -SafeConstructor.add_constructor(
462 - u'tag:yaml.org,2002:map',
463 - SafeConstructor.construct_yaml_map)
464 -
465 -SafeConstructor.add_constructor(None,
466 - SafeConstructor.construct_undefined)
467 -
468 -class Constructor(SafeConstructor):
469 -
470 - def construct_python_str(self, node):
471 - return self.construct_scalar(node).encode('utf-8')
472 -
473 - def construct_python_unicode(self, node):
474 - return self.construct_scalar(node)
475 -
476 - def construct_python_long(self, node):
477 - return long(self.construct_yaml_int(node))
478 -
479 - def construct_python_complex(self, node):
480 - return complex(self.construct_scalar(node))
481 -
482 - def construct_python_tuple(self, node):
483 - return tuple(self.construct_sequence(node))
484 -
485 - def find_python_module(self, name, mark):
486 - if not name:
487 - raise ConstructorError("while constructing a Python module", mark,
488 - "expected non-empty name appended to the tag", mark)
489 - try:
490 - __import__(name)
491 - except ImportError, exc:
492 - raise ConstructorError("while constructing a Python module", mark,
493 - "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark)
494 - return sys.modules[name]
495 -
496 - def find_python_name(self, name, mark):
497 - if not name:
498 - raise ConstructorError("while constructing a Python object", mark,
499 - "expected non-empty name appended to the tag", mark)
500 - if u'.' in name:
501 - module_name, object_name = name.rsplit('.', 1)
502 - else:
503 - module_name = '__builtin__'
504 - object_name = name
505 - try:
506 - __import__(module_name)
507 - except ImportError, exc:
508 - raise ConstructorError("while constructing a Python object", mark,
509 - "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark)
510 - module = sys.modules[module_name]
511 - if not hasattr(module, object_name):
512 - raise ConstructorError("while constructing a Python object", mark,
513 - "cannot find %r in the module %r" % (object_name.encode('utf-8'),
514 - module.__name__), mark)
515 - return getattr(module, object_name)
516 -
517 - def construct_python_name(self, suffix, node):
518 - value = self.construct_scalar(node)
519 - if value:
520 - raise ConstructorError("while constructing a Python name", node.start_mark,
521 - "expected the empty value, but found %r" % value.encode('utf-8'),
522 - node.start_mark)
523 - return self.find_python_name(suffix, node.start_mark)
524 -
525 - def construct_python_module(self, suffix, node):
526 - value = self.construct_scalar(node)
527 - if value:
528 - raise ConstructorError("while constructing a Python module", node.start_mark,
529 - "expected the empty value, but found %r" % value.encode('utf-8'),
530 - node.start_mark)
531 - return self.find_python_module(suffix, node.start_mark)
532 -
533 - class classobj: pass
534 -
535 - def make_python_instance(self, suffix, node,
536 - args=None, kwds=None, newobj=False):
537 - if not args:
538 - args = []
539 - if not kwds:
540 - kwds = {}
541 - cls = self.find_python_name(suffix, node.start_mark)
542 - if newobj and isinstance(cls, type(self.classobj)) \
543 - and not args and not kwds:
544 - instance = self.classobj()
545 - instance.__class__ = cls
546 - return instance
547 - elif newobj and isinstance(cls, type):
548 - return cls.__new__(cls, *args, **kwds)
549 - else:
550 - return cls(*args, **kwds)
551 -
552 - def set_python_instance_state(self, instance, state):
553 - if hasattr(instance, '__setstate__'):
554 - instance.__setstate__(state)
555 - else:
556 - slotstate = {}
557 - if isinstance(state, tuple) and len(state) == 2:
558 - state, slotstate = state
559 - if hasattr(instance, '__dict__'):
560 - instance.__dict__.update(state)
561 - elif state:
562 - slotstate.update(state)
563 - for key, value in slotstate.items():
564 - setattr(object, key, value)
565 -
566 - def construct_python_object(self, suffix, node):
567 - # Format:
568 - # !!python/object:module.name { ... state ... }
569 - instance = self.make_python_instance(suffix, node, newobj=True)
570 - yield instance
571 - deep = hasattr(instance, '__setstate__')
572 - state = self.construct_mapping(node, deep=deep)
573 - self.set_python_instance_state(instance, state)
574 -
575 - def construct_python_object_apply(self, suffix, node, newobj=False):
576 - # Format:
577 - # !!python/object/apply # (or !!python/object/new)
578 - # args: [ ... arguments ... ]
579 - # kwds: { ... keywords ... }
580 - # state: ... state ...
581 - # listitems: [ ... listitems ... ]
582 - # dictitems: { ... dictitems ... }
583 - # or short format:
584 - # !!python/object/apply [ ... arguments ... ]
585 - # The difference between !!python/object/apply and !!python/object/new
586 - # is how an object is created, check make_python_instance for details.
587 - if isinstance(node, SequenceNode):
588 - args = self.construct_sequence(node, deep=True)
589 - kwds = {}
590 - state = {}
591 - listitems = []
592 - dictitems = {}
593 - else:
594 - value = self.construct_mapping(node, deep=True)
595 - args = value.get('args', [])
596 - kwds = value.get('kwds', {})
597 - state = value.get('state', {})
598 - listitems = value.get('listitems', [])
599 - dictitems = value.get('dictitems', {})
600 - instance = self.make_python_instance(suffix, node, args, kwds, newobj)
601 - if state:
602 - self.set_python_instance_state(instance, state)
603 - if listitems:
604 - instance.extend(listitems)
605 - if dictitems:
606 - for key in dictitems:
607 - instance[key] = dictitems[key]
608 - return instance
609 -
610 - def construct_python_object_new(self, suffix, node):
611 - return self.construct_python_object_apply(suffix, node, newobj=True)
612 -
613 -Constructor.add_constructor(
614 - u'tag:yaml.org,2002:python/none',
615 - Constructor.construct_yaml_null)
616 -
617 -Constructor.add_constructor(
618 - u'tag:yaml.org,2002:python/bool',
619 - Constructor.construct_yaml_bool)
620 -
621 -Constructor.add_constructor(
622 - u'tag:yaml.org,2002:python/str',
623 - Constructor.construct_python_str)
624 -
625 -Constructor.add_constructor(
626 - u'tag:yaml.org,2002:python/unicode',
627 - Constructor.construct_python_unicode)
628 -
629 -Constructor.add_constructor(
630 - u'tag:yaml.org,2002:python/int',
631 - Constructor.construct_yaml_int)
632 -
633 -Constructor.add_constructor(
634 - u'tag:yaml.org,2002:python/long',
635 - Constructor.construct_python_long)
636 -
637 -Constructor.add_constructor(
638 - u'tag:yaml.org,2002:python/float',
639 - Constructor.construct_yaml_float)
640 -
641 -Constructor.add_constructor(
642 - u'tag:yaml.org,2002:python/complex',
643 - Constructor.construct_python_complex)
644 -
645 -Constructor.add_constructor(
646 - u'tag:yaml.org,2002:python/list',
647 - Constructor.construct_yaml_seq)
648 -
649 -Constructor.add_constructor(
650 - u'tag:yaml.org,2002:python/tuple',
651 - Constructor.construct_python_tuple)
652 -
653 -Constructor.add_constructor(
654 - u'tag:yaml.org,2002:python/dict',
655 - Constructor.construct_yaml_map)
656 -
657 -Constructor.add_multi_constructor(
658 - u'tag:yaml.org,2002:python/name:',
659 - Constructor.construct_python_name)
660 -
661 -Constructor.add_multi_constructor(
662 - u'tag:yaml.org,2002:python/module:',
663 - Constructor.construct_python_module)
664 -
665 -Constructor.add_multi_constructor(
666 - u'tag:yaml.org,2002:python/object:',
667 - Constructor.construct_python_object)
668 -
669 -Constructor.add_multi_constructor(
670 - u'tag:yaml.org,2002:python/object/apply:',
671 - Constructor.construct_python_object_apply)
672 -
673 -Constructor.add_multi_constructor(
674 - u'tag:yaml.org,2002:python/object/new:',
675 - Constructor.construct_python_object_new)
676 -
src/collectors/python.d.plugin/python_modules/pyyaml2/cyaml.py deleted
-86
@@ -1,86 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader',
4 - 'CBaseDumper', 'CSafeDumper', 'CDumper']
5 -
6 -from _yaml import CParser, CEmitter
7 -
8 -from constructor import *
9 -
10 -from serializer import *
11 -from representer import *
12 -
13 -from resolver import *
14 -
15 -class CBaseLoader(CParser, BaseConstructor, BaseResolver):
16 -
17 - def __init__(self, stream):
18 - CParser.__init__(self, stream)
19 - BaseConstructor.__init__(self)
20 - BaseResolver.__init__(self)
21 -
22 -class CSafeLoader(CParser, SafeConstructor, Resolver):
23 -
24 - def __init__(self, stream):
25 - CParser.__init__(self, stream)
26 - SafeConstructor.__init__(self)
27 - Resolver.__init__(self)
28 -
29 -class CLoader(CParser, Constructor, Resolver):
30 -
31 - def __init__(self, stream):
32 - CParser.__init__(self, stream)
33 - Constructor.__init__(self)
34 - Resolver.__init__(self)
35 -
36 -class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver):
37 -
38 - def __init__(self, stream,
39 - default_style=None, default_flow_style=None,
40 - canonical=None, indent=None, width=None,
41 - allow_unicode=None, line_break=None,
42 - encoding=None, explicit_start=None, explicit_end=None,
43 - version=None, tags=None):
44 - CEmitter.__init__(self, stream, canonical=canonical,
45 - indent=indent, width=width, encoding=encoding,
46 - allow_unicode=allow_unicode, line_break=line_break,
47 - explicit_start=explicit_start, explicit_end=explicit_end,
48 - version=version, tags=tags)
49 - Representer.__init__(self, default_style=default_style,
50 - default_flow_style=default_flow_style)
51 - Resolver.__init__(self)
52 -
53 -class CSafeDumper(CEmitter, SafeRepresenter, Resolver):
54 -
55 - def __init__(self, stream,
56 - default_style=None, default_flow_style=None,
57 - canonical=None, indent=None, width=None,
58 - allow_unicode=None, line_break=None,
59 - encoding=None, explicit_start=None, explicit_end=None,
60 - version=None, tags=None):
61 - CEmitter.__init__(self, stream, canonical=canonical,
62 - indent=indent, width=width, encoding=encoding,
63 - allow_unicode=allow_unicode, line_break=line_break,
64 - explicit_start=explicit_start, explicit_end=explicit_end,
65 - version=version, tags=tags)
66 - SafeRepresenter.__init__(self, default_style=default_style,
67 - default_flow_style=default_flow_style)
68 - Resolver.__init__(self)
69 -
70 -class CDumper(CEmitter, Serializer, Representer, Resolver):
71 -
72 - def __init__(self, stream,
73 - default_style=None, default_flow_style=None,
74 - canonical=None, indent=None, width=None,
75 - allow_unicode=None, line_break=None,
76 - encoding=None, explicit_start=None, explicit_end=None,
77 - version=None, tags=None):
78 - CEmitter.__init__(self, stream, canonical=canonical,
79 - indent=indent, width=width, encoding=encoding,
80 - allow_unicode=allow_unicode, line_break=line_break,
81 - explicit_start=explicit_start, explicit_end=explicit_end,
82 - version=version, tags=tags)
83 - Representer.__init__(self, default_style=default_style,
84 - default_flow_style=default_flow_style)
85 - Resolver.__init__(self)
86 -
src/collectors/python.d.plugin/python_modules/pyyaml2/dumper.py deleted
-63
@@ -1,63 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
4 -
5 -from emitter import *
6 -from serializer import *
7 -from representer import *
8 -from resolver import *
9 -
10 -class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
11 -
12 - def __init__(self, stream,
13 - default_style=None, default_flow_style=None,
14 - canonical=None, indent=None, width=None,
15 - allow_unicode=None, line_break=None,
16 - encoding=None, explicit_start=None, explicit_end=None,
17 - version=None, tags=None):
18 - Emitter.__init__(self, stream, canonical=canonical,
19 - indent=indent, width=width,
20 - allow_unicode=allow_unicode, line_break=line_break)
21 - Serializer.__init__(self, encoding=encoding,
22 - explicit_start=explicit_start, explicit_end=explicit_end,
23 - version=version, tags=tags)
24 - Representer.__init__(self, default_style=default_style,
25 - default_flow_style=default_flow_style)
26 - Resolver.__init__(self)
27 -
28 -class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
29 -
30 - def __init__(self, stream,
31 - default_style=None, default_flow_style=None,
32 - canonical=None, indent=None, width=None,
33 - allow_unicode=None, line_break=None,
34 - encoding=None, explicit_start=None, explicit_end=None,
35 - version=None, tags=None):
36 - Emitter.__init__(self, stream, canonical=canonical,
37 - indent=indent, width=width,
38 - allow_unicode=allow_unicode, line_break=line_break)
39 - Serializer.__init__(self, encoding=encoding,
40 - explicit_start=explicit_start, explicit_end=explicit_end,
41 - version=version, tags=tags)
42 - SafeRepresenter.__init__(self, default_style=default_style,
43 - default_flow_style=default_flow_style)
44 - Resolver.__init__(self)
45 -
46 -class Dumper(Emitter, Serializer, Representer, Resolver):
47 -
48 - def __init__(self, stream,
49 - default_style=None, default_flow_style=None,
50 - canonical=None, indent=None, width=None,
51 - allow_unicode=None, line_break=None,
52 - encoding=None, explicit_start=None, explicit_end=None,
53 - version=None, tags=None):
54 - Emitter.__init__(self, stream, canonical=canonical,
55 - indent=indent, width=width,
56 - allow_unicode=allow_unicode, line_break=line_break)
57 - Serializer.__init__(self, encoding=encoding,
58 - explicit_start=explicit_start, explicit_end=explicit_end,
59 - version=version, tags=tags)
60 - Representer.__init__(self, default_style=default_style,
61 - default_flow_style=default_flow_style)
62 - Resolver.__init__(self)
63 -
src/collectors/python.d.plugin/python_modules/pyyaml2/emitter.py deleted
-1141
@@ -1,1141 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -# Emitter expects events obeying the following grammar:
4 -# stream ::= STREAM-START document* STREAM-END
5 -# document ::= DOCUMENT-START node DOCUMENT-END
6 -# node ::= SCALAR | sequence | mapping
7 -# sequence ::= SEQUENCE-START node* SEQUENCE-END
8 -# mapping ::= MAPPING-START (node node)* MAPPING-END
9 -
10 -__all__ = ['Emitter', 'EmitterError']
11 -
12 -from error import YAMLError
13 -from events import *
14 -
15 -class EmitterError(YAMLError):
16 - pass
17 -
18 -class ScalarAnalysis(object):
19 - def __init__(self, scalar, empty, multiline,
20 - allow_flow_plain, allow_block_plain,
21 - allow_single_quoted, allow_double_quoted,
22 - allow_block):
23 - self.scalar = scalar
24 - self.empty = empty
25 - self.multiline = multiline
26 - self.allow_flow_plain = allow_flow_plain
27 - self.allow_block_plain = allow_block_plain
28 - self.allow_single_quoted = allow_single_quoted
29 - self.allow_double_quoted = allow_double_quoted
30 - self.allow_block = allow_block
31 -
32 -class Emitter(object):
33 -
34 - DEFAULT_TAG_PREFIXES = {
35 - u'!' : u'!',
36 - u'tag:yaml.org,2002:' : u'!!',
37 - }
38 -
39 - def __init__(self, stream, canonical=None, indent=None, width=None,
40 - allow_unicode=None, line_break=None):
41 -
42 - # The stream should have the methods `write` and possibly `flush`.
43 - self.stream = stream
44 -
45 - # Encoding can be overriden by STREAM-START.
46 - self.encoding = None
47 -
48 - # Emitter is a state machine with a stack of states to handle nested
49 - # structures.
50 - self.states = []
51 - self.state = self.expect_stream_start
52 -
53 - # Current event and the event queue.
54 - self.events = []
55 - self.event = None
56 -
57 - # The current indentation level and the stack of previous indents.
58 - self.indents = []
59 - self.indent = None
60 -
61 - # Flow level.
62 - self.flow_level = 0
63 -
64 - # Contexts.
65 - self.root_context = False
66 - self.sequence_context = False
67 - self.mapping_context = False
68 - self.simple_key_context = False
69 -
70 - # Characteristics of the last emitted character:
71 - # - current position.
72 - # - is it a whitespace?
73 - # - is it an indention character
74 - # (indentation space, '-', '?', or ':')?
75 - self.line = 0
76 - self.column = 0
77 - self.whitespace = True
78 - self.indention = True
79 -
80 - # Whether the document requires an explicit document indicator
81 - self.open_ended = False
82 -
83 - # Formatting details.
84 - self.canonical = canonical
85 - self.allow_unicode = allow_unicode
86 - self.best_indent = 2
87 - if indent and 1 < indent < 10:
88 - self.best_indent = indent
89 - self.best_width = 80
90 - if width and width > self.best_indent*2:
91 - self.best_width = width
92 - self.best_line_break = u'\n'
93 - if line_break in [u'\r', u'\n', u'\r\n']:
94 - self.best_line_break = line_break
95 -
96 - # Tag prefixes.
97 - self.tag_prefixes = None
98 -
99 - # Prepared anchor and tag.
100 - self.prepared_anchor = None
101 - self.prepared_tag = None
102 -
103 - # Scalar analysis and style.
104 - self.analysis = None
105 - self.style = None
106 -
107 - def dispose(self):
108 - # Reset the state attributes (to clear self-references)
109 - self.states = []
110 - self.state = None
111 -
112 - def emit(self, event):
113 - self.events.append(event)
114 - while not self.need_more_events():
115 - self.event = self.events.pop(0)
116 - self.state()
117 - self.event = None
118 -
119 - # In some cases, we wait for a few next events before emitting.
120 -
121 - def need_more_events(self):
122 - if not self.events:
123 - return True
124 - event = self.events[0]
125 - if isinstance(event, DocumentStartEvent):
126 - return self.need_events(1)
127 - elif isinstance(event, SequenceStartEvent):
128 - return self.need_events(2)
129 - elif isinstance(event, MappingStartEvent):
130 - return self.need_events(3)
131 - else:
132 - return False
133 -
134 - def need_events(self, count):
135 - level = 0
136 - for event in self.events[1:]:
137 - if isinstance(event, (DocumentStartEvent, CollectionStartEvent)):
138 - level += 1
139 - elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)):
140 - level -= 1
141 - elif isinstance(event, StreamEndEvent):
142 - level = -1
143 - if level < 0:
144 - return False
145 - return (len(self.events) < count+1)
146 -
147 - def increase_indent(self, flow=False, indentless=False):
148 - self.indents.append(self.indent)
149 - if self.indent is None:
150 - if flow:
151 - self.indent = self.best_indent
152 - else:
153 - self.indent = 0
154 - elif not indentless:
155 - self.indent += self.best_indent
156 -
157 - # States.
158 -
159 - # Stream handlers.
160 -
161 - def expect_stream_start(self):
162 - if isinstance(self.event, StreamStartEvent):
163 - if self.event.encoding and not getattr(self.stream, 'encoding', None):
164 - self.encoding = self.event.encoding
165 - self.write_stream_start()
166 - self.state = self.expect_first_document_start
167 - else:
168 - raise EmitterError("expected StreamStartEvent, but got %s"
169 - % self.event)
170 -
171 - def expect_nothing(self):
172 - raise EmitterError("expected nothing, but got %s" % self.event)
173 -
174 - # Document handlers.
175 -
176 - def expect_first_document_start(self):
177 - return self.expect_document_start(first=True)
178 -
179 - def expect_document_start(self, first=False):
180 - if isinstance(self.event, DocumentStartEvent):
181 - if (self.event.version or self.event.tags) and self.open_ended:
182 - self.write_indicator(u'...', True)
183 - self.write_indent()
184 - if self.event.version:
185 - version_text = self.prepare_version(self.event.version)
186 - self.write_version_directive(version_text)
187 - self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy()
188 - if self.event.tags:
189 - handles = self.event.tags.keys()
190 - handles.sort()
191 - for handle in handles:
192 - prefix = self.event.tags[handle]
193 - self.tag_prefixes[prefix] = handle
194 - handle_text = self.prepare_tag_handle(handle)
195 - prefix_text = self.prepare_tag_prefix(prefix)
196 - self.write_tag_directive(handle_text, prefix_text)
197 - implicit = (first and not self.event.explicit and not self.canonical
198 - and not self.event.version and not self.event.tags
199 - and not self.check_empty_document())
200 - if not implicit:
201 - self.write_indent()
202 - self.write_indicator(u'---', True)
203 - if self.canonical:
204 - self.write_indent()
205 - self.state = self.expect_document_root
206 - elif isinstance(self.event, StreamEndEvent):
207 - if self.open_ended:
208 - self.write_indicator(u'...', True)
209 - self.write_indent()
210 - self.write_stream_end()
211 - self.state = self.expect_nothing
212 - else:
213 - raise EmitterError("expected DocumentStartEvent, but got %s"
214 - % self.event)
215 -
216 - def expect_document_end(self):
217 - if isinstance(self.event, DocumentEndEvent):
218 - self.write_indent()
219 - if self.event.explicit:
220 - self.write_indicator(u'...', True)
221 - self.write_indent()
222 - self.flush_stream()
223 - self.state = self.expect_document_start
224 - else:
225 - raise EmitterError("expected DocumentEndEvent, but got %s"
226 - % self.event)
227 -
228 - def expect_document_root(self):
229 - self.states.append(self.expect_document_end)
230 - self.expect_node(root=True)
231 -
232 - # Node handlers.
233 -
234 - def expect_node(self, root=False, sequence=False, mapping=False,
235 - simple_key=False):
236 - self.root_context = root
237 - self.sequence_context = sequence
238 - self.mapping_context = mapping
239 - self.simple_key_context = simple_key
240 - if isinstance(self.event, AliasEvent):
241 - self.expect_alias()
242 - elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)):
243 - self.process_anchor(u'&')
244 - self.process_tag()
245 - if isinstance(self.event, ScalarEvent):
246 - self.expect_scalar()
247 - elif isinstance(self.event, SequenceStartEvent):
248 - if self.flow_level or self.canonical or self.event.flow_style \
249 - or self.check_empty_sequence():
250 - self.expect_flow_sequence()
251 - else:
252 - self.expect_block_sequence()
253 - elif isinstance(self.event, MappingStartEvent):
254 - if self.flow_level or self.canonical or self.event.flow_style \
255 - or self.check_empty_mapping():
256 - self.expect_flow_mapping()
257 - else:
258 - self.expect_block_mapping()
259 - else:
260 - raise EmitterError("expected NodeEvent, but got %s" % self.event)
261 -
262 - def expect_alias(self):
263 - if self.event.anchor is None:
264 - raise EmitterError("anchor is not specified for alias")
265 - self.process_anchor(u'*')
266 - self.state = self.states.pop()
267 -
268 - def expect_scalar(self):
269 - self.increase_indent(flow=True)
270 - self.process_scalar()
271 - self.indent = self.indents.pop()
272 - self.state = self.states.pop()
273 -
274 - # Flow sequence handlers.
275 -
276 - def expect_flow_sequence(self):
277 - self.write_indicator(u'[', True, whitespace=True)
278 - self.flow_level += 1
279 - self.increase_indent(flow=True)
280 - self.state = self.expect_first_flow_sequence_item
281 -
282 - def expect_first_flow_sequence_item(self):
283 - if isinstance(self.event, SequenceEndEvent):
284 - self.indent = self.indents.pop()
285 - self.flow_level -= 1
286 - self.write_indicator(u']', False)
287 - self.state = self.states.pop()
288 - else:
289 - if self.canonical or self.column > self.best_width:
290 - self.write_indent()
291 - self.states.append(self.expect_flow_sequence_item)
292 - self.expect_node(sequence=True)
293 -
294 - def expect_flow_sequence_item(self):
295 - if isinstance(self.event, SequenceEndEvent):
296 - self.indent = self.indents.pop()
297 - self.flow_level -= 1
298 - if self.canonical:
299 - self.write_indicator(u',', False)
300 - self.write_indent()
301 - self.write_indicator(u']', False)
302 - self.state = self.states.pop()
303 - else:
304 - self.write_indicator(u',', False)
305 - if self.canonical or self.column > self.best_width:
306 - self.write_indent()
307 - self.states.append(self.expect_flow_sequence_item)
308 - self.expect_node(sequence=True)
309 -
310 - # Flow mapping handlers.
311 -
312 - def expect_flow_mapping(self):
313 - self.write_indicator(u'{', True, whitespace=True)
314 - self.flow_level += 1
315 - self.increase_indent(flow=True)
316 - self.state = self.expect_first_flow_mapping_key
317 -
318 - def expect_first_flow_mapping_key(self):
319 - if isinstance(self.event, MappingEndEvent):
320 - self.indent = self.indents.pop()
321 - self.flow_level -= 1
322 - self.write_indicator(u'}', False)
323 - self.state = self.states.pop()
324 - else:
325 - if self.canonical or self.column > self.best_width:
326 - self.write_indent()
327 - if not self.canonical and self.check_simple_key():
328 - self.states.append(self.expect_flow_mapping_simple_value)
329 - self.expect_node(mapping=True, simple_key=True)
330 - else:
331 - self.write_indicator(u'?', True)
332 - self.states.append(self.expect_flow_mapping_value)
333 - self.expect_node(mapping=True)
334 -
335 - def expect_flow_mapping_key(self):
336 - if isinstance(self.event, MappingEndEvent):
337 - self.indent = self.indents.pop()
338 - self.flow_level -= 1
339 - if self.canonical:
340 - self.write_indicator(u',', False)
341 - self.write_indent()
342 - self.write_indicator(u'}', False)
343 - self.state = self.states.pop()
344 - else:
345 - self.write_indicator(u',', False)
346 - if self.canonical or self.column > self.best_width:
347 - self.write_indent()
348 - if not self.canonical and self.check_simple_key():
349 - self.states.append(self.expect_flow_mapping_simple_value)
350 - self.expect_node(mapping=True, simple_key=True)
351 - else:
352 - self.write_indicator(u'?', True)
353 - self.states.append(self.expect_flow_mapping_value)
354 - self.expect_node(mapping=True)
355 -
356 - def expect_flow_mapping_simple_value(self):
357 - self.write_indicator(u':', False)
358 - self.states.append(self.expect_flow_mapping_key)
359 - self.expect_node(mapping=True)
360 -
361 - def expect_flow_mapping_value(self):
362 - if self.canonical or self.column > self.best_width:
363 - self.write_indent()
364 - self.write_indicator(u':', True)
365 - self.states.append(self.expect_flow_mapping_key)
366 - self.expect_node(mapping=True)
367 -
368 - # Block sequence handlers.
369 -
370 - def expect_block_sequence(self):
371 - indentless = (self.mapping_context and not self.indention)
372 - self.increase_indent(flow=False, indentless=indentless)
373 - self.state = self.expect_first_block_sequence_item
374 -
375 - def expect_first_block_sequence_item(self):
376 - return self.expect_block_sequence_item(first=True)
377 -
378 - def expect_block_sequence_item(self, first=False):
379 - if not first and isinstance(self.event, SequenceEndEvent):
380 - self.indent = self.indents.pop()
381 - self.state = self.states.pop()
382 - else:
383 - self.write_indent()
384 - self.write_indicator(u'-', True, indention=True)
385 - self.states.append(self.expect_block_sequence_item)
386 - self.expect_node(sequence=True)
387 -
388 - # Block mapping handlers.
389 -
390 - def expect_block_mapping(self):
391 - self.increase_indent(flow=False)
392 - self.state = self.expect_first_block_mapping_key
393 -
394 - def expect_first_block_mapping_key(self):
395 - return self.expect_block_mapping_key(first=True)
396 -
397 - def expect_block_mapping_key(self, first=False):
398 - if not first and isinstance(self.event, MappingEndEvent):
399 - self.indent = self.indents.pop()
400 - self.state = self.states.pop()
401 - else:
402 - self.write_indent()
403 - if self.check_simple_key():
404 - self.states.append(self.expect_block_mapping_simple_value)
405 - self.expect_node(mapping=True, simple_key=True)
406 - else:
407 - self.write_indicator(u'?', True, indention=True)
408 - self.states.append(self.expect_block_mapping_value)
409 - self.expect_node(mapping=True)
410 -
411 - def expect_block_mapping_simple_value(self):
412 - self.write_indicator(u':', False)
413 - self.states.append(self.expect_block_mapping_key)
414 - self.expect_node(mapping=True)
415 -
416 - def expect_block_mapping_value(self):
417 - self.write_indent()
418 - self.write_indicator(u':', True, indention=True)
419 - self.states.append(self.expect_block_mapping_key)
420 - self.expect_node(mapping=True)
421 -
422 - # Checkers.
423 -
424 - def check_empty_sequence(self):
425 - return (isinstance(self.event, SequenceStartEvent) and self.events
426 - and isinstance(self.events[0], SequenceEndEvent))
427 -
428 - def check_empty_mapping(self):
429 - return (isinstance(self.event, MappingStartEvent) and self.events
430 - and isinstance(self.events[0], MappingEndEvent))
431 -
432 - def check_empty_document(self):
433 - if not isinstance(self.event, DocumentStartEvent) or not self.events:
434 - return False
435 - event = self.events[0]
436 - return (isinstance(event, ScalarEvent) and event.anchor is None
437 - and event.tag is None and event.implicit and event.value == u'')
438 -
439 - def check_simple_key(self):
440 - length = 0
441 - if isinstance(self.event, NodeEvent) and self.event.anchor is not None:
442 - if self.prepared_anchor is None:
443 - self.prepared_anchor = self.prepare_anchor(self.event.anchor)
444 - length += len(self.prepared_anchor)
445 - if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \
446 - and self.event.tag is not None:
447 - if self.prepared_tag is None:
448 - self.prepared_tag = self.prepare_tag(self.event.tag)
449 - length += len(self.prepared_tag)
450 - if isinstance(self.event, ScalarEvent):
451 - if self.analysis is None:
452 - self.analysis = self.analyze_scalar(self.event.value)
453 - length += len(self.analysis.scalar)
454 - return (length < 128 and (isinstance(self.event, AliasEvent)
455 - or (isinstance(self.event, ScalarEvent)
456 - and not self.analysis.empty and not self.analysis.multiline)
457 - or self.check_empty_sequence() or self.check_empty_mapping()))
458 -
459 - # Anchor, Tag, and Scalar processors.
460 -
461 - def process_anchor(self, indicator):
462 - if self.event.anchor is None:
463 - self.prepared_anchor = None
464 - return
465 - if self.prepared_anchor is None:
466 - self.prepared_anchor = self.prepare_anchor(self.event.anchor)
467 - if self.prepared_anchor:
468 - self.write_indicator(indicator+self.prepared_anchor, True)
469 - self.prepared_anchor = None
470 -
471 - def process_tag(self):
472 - tag = self.event.tag
473 - if isinstance(self.event, ScalarEvent):
474 - if self.style is None:
475 - self.style = self.choose_scalar_style()
476 - if ((not self.canonical or tag is None) and
477 - ((self.style == '' and self.event.implicit[0])
478 - or (self.style != '' and self.event.implicit[1]))):
479 - self.prepared_tag = None
480 - return
481 - if self.event.implicit[0] and tag is None:
482 - tag = u'!'
483 - self.prepared_tag = None
484 - else:
485 - if (not self.canonical or tag is None) and self.event.implicit:
486 - self.prepared_tag = None
487 - return
488 - if tag is None:
489 - raise EmitterError("tag is not specified")
490 - if self.prepared_tag is None:
491 - self.prepared_tag = self.prepare_tag(tag)
492 - if self.prepared_tag:
493 - self.write_indicator(self.prepared_tag, True)
494 - self.prepared_tag = None
495 -
496 - def choose_scalar_style(self):
497 - if self.analysis is None:
498 - self.analysis = self.analyze_scalar(self.event.value)
499 - if self.event.style == '"' or self.canonical:
500 - return '"'
501 - if not self.event.style and self.event.implicit[0]:
502 - if (not (self.simple_key_context and
503 - (self.analysis.empty or self.analysis.multiline))
504 - and (self.flow_level and self.analysis.allow_flow_plain
505 - or (not self.flow_level and self.analysis.allow_block_plain))):
506 - return ''
507 - if self.event.style and self.event.style in '|>':
508 - if (not self.flow_level and not self.simple_key_context
509 - and self.analysis.allow_block):
510 - return self.event.style
511 - if not self.event.style or self.event.style == '\'':
512 - if (self.analysis.allow_single_quoted and
513 - not (self.simple_key_context and self.analysis.multiline)):
514 - return '\''
515 - return '"'
516 -
517 - def process_scalar(self):
518 - if self.analysis is None:
519 - self.analysis = self.analyze_scalar(self.event.value)
520 - if self.style is None:
521 - self.style = self.choose_scalar_style()
522 - split = (not self.simple_key_context)
523 - #if self.analysis.multiline and split \
524 - # and (not self.style or self.style in '\'\"'):
525 - # self.write_indent()
526 - if self.style == '"':
527 - self.write_double_quoted(self.analysis.scalar, split)
528 - elif self.style == '\'':
529 - self.write_single_quoted(self.analysis.scalar, split)
530 - elif self.style == '>':
531 - self.write_folded(self.analysis.scalar)
532 - elif self.style == '|':
533 - self.write_literal(self.analysis.scalar)
534 - else:
535 - self.write_plain(self.analysis.scalar, split)
536 - self.analysis = None
537 - self.style = None
538 -
539 - # Analyzers.
540 -
541 - def prepare_version(self, version):
542 - major, minor = version
543 - if major != 1:
544 - raise EmitterError("unsupported YAML version: %d.%d" % (major, minor))
545 - return u'%d.%d' % (major, minor)
546 -
547 - def prepare_tag_handle(self, handle):
548 - if not handle:
549 - raise EmitterError("tag handle must not be empty")
550 - if handle[0] != u'!' or handle[-1] != u'!':
551 - raise EmitterError("tag handle must start and end with '!': %r"
552 - % (handle.encode('utf-8')))
553 - for ch in handle[1:-1]:
554 - if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
555 - or ch in u'-_'):
556 - raise EmitterError("invalid character %r in the tag handle: %r"
557 - % (ch.encode('utf-8'), handle.encode('utf-8')))
558 - return handle
559 -
560 - def prepare_tag_prefix(self, prefix):
561 - if not prefix:
562 - raise EmitterError("tag prefix must not be empty")
563 - chunks = []
564 - start = end = 0
565 - if prefix[0] == u'!':
566 - end = 1
567 - while end < len(prefix):
568 - ch = prefix[end]
569 - if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
570 - or ch in u'-;/?!:@&=+$,_.~*\'()[]':
571 - end += 1
572 - else:
573 - if start < end:
574 - chunks.append(prefix[start:end])
575 - start = end = end+1
576 - data = ch.encode('utf-8')
577 - for ch in data:
578 - chunks.append(u'%%%02X' % ord(ch))
579 - if start < end:
580 - chunks.append(prefix[start:end])
581 - return u''.join(chunks)
582 -
583 - def prepare_tag(self, tag):
584 - if not tag:
585 - raise EmitterError("tag must not be empty")
586 - if tag == u'!':
587 - return tag
588 - handle = None
589 - suffix = tag
590 - prefixes = self.tag_prefixes.keys()
591 - prefixes.sort()
592 - for prefix in prefixes:
593 - if tag.startswith(prefix) \
594 - and (prefix == u'!' or len(prefix) < len(tag)):
595 - handle = self.tag_prefixes[prefix]
596 - suffix = tag[len(prefix):]
597 - chunks = []
598 - start = end = 0
599 - while end < len(suffix):
600 - ch = suffix[end]
601 - if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
602 - or ch in u'-;/?:@&=+$,_.~*\'()[]' \
603 - or (ch == u'!' and handle != u'!'):
604 - end += 1
605 - else:
606 - if start < end:
607 - chunks.append(suffix[start:end])
608 - start = end = end+1
609 - data = ch.encode('utf-8')
610 - for ch in data:
611 - chunks.append(u'%%%02X' % ord(ch))
612 - if start < end:
613 - chunks.append(suffix[start:end])
614 - suffix_text = u''.join(chunks)
615 - if handle:
616 - return u'%s%s' % (handle, suffix_text)
617 - else:
618 - return u'!<%s>' % suffix_text
619 -
620 - def prepare_anchor(self, anchor):
621 - if not anchor:
622 - raise EmitterError("anchor must not be empty")
623 - for ch in anchor:
624 - if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
625 - or ch in u'-_'):
626 - raise EmitterError("invalid character %r in the anchor: %r"
627 - % (ch.encode('utf-8'), anchor.encode('utf-8')))
628 - return anchor
629 -
630 - def analyze_scalar(self, scalar):
631 -
632 - # Empty scalar is a special case.
633 - if not scalar:
634 - return ScalarAnalysis(scalar=scalar, empty=True, multiline=False,
635 - allow_flow_plain=False, allow_block_plain=True,
636 - allow_single_quoted=True, allow_double_quoted=True,
637 - allow_block=False)
638 -
639 - # Indicators and special characters.
640 - block_indicators = False
641 - flow_indicators = False
642 - line_breaks = False
643 - special_characters = False
644 -
645 - # Important whitespace combinations.
646 - leading_space = False
647 - leading_break = False
648 - trailing_space = False
649 - trailing_break = False
650 - break_space = False
651 - space_break = False
652 -
653 - # Check document indicators.
654 - if scalar.startswith(u'---') or scalar.startswith(u'...'):
655 - block_indicators = True
656 - flow_indicators = True
657 -
658 - # First character or preceded by a whitespace.
659 - preceeded_by_whitespace = True
660 -
661 - # Last character or followed by a whitespace.
662 - followed_by_whitespace = (len(scalar) == 1 or
663 - scalar[1] in u'\0 \t\r\n\x85\u2028\u2029')
664 -
665 - # The previous character is a space.
666 - previous_space = False
667 -
668 - # The previous character is a break.
669 - previous_break = False
670 -
671 - index = 0
672 - while index < len(scalar):
673 - ch = scalar[index]
674 -
675 - # Check for indicators.
676 - if index == 0:
677 - # Leading indicators are special characters.
678 - if ch in u'#,[]{}&*!|>\'\"%@`':
679 - flow_indicators = True
680 - block_indicators = True
681 - if ch in u'?:':
682 - flow_indicators = True
683 - if followed_by_whitespace:
684 - block_indicators = True
685 - if ch == u'-' and followed_by_whitespace:
686 - flow_indicators = True
687 - block_indicators = True
688 - else:
689 - # Some indicators cannot appear within a scalar as well.
690 - if ch in u',?[]{}':
691 - flow_indicators = True
692 - if ch == u':':
693 - flow_indicators = True
694 - if followed_by_whitespace:
695 - block_indicators = True
696 - if ch == u'#' and preceeded_by_whitespace:
697 - flow_indicators = True
698 - block_indicators = True
699 -
700 - # Check for line breaks, special, and unicode characters.
701 - if ch in u'\n\x85\u2028\u2029':
702 - line_breaks = True
703 - if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'):
704 - if (ch == u'\x85' or u'\xA0' <= ch <= u'\uD7FF'
705 - or u'\uE000' <= ch <= u'\uFFFD') and ch != u'\uFEFF':
706 - unicode_characters = True
707 - if not self.allow_unicode:
708 - special_characters = True
709 - else:
710 - special_characters = True
711 -
712 - # Detect important whitespace combinations.
713 - if ch == u' ':
714 - if index == 0:
715 - leading_space = True
716 - if index == len(scalar)-1:
717 - trailing_space = True
718 - if previous_break:
719 - break_space = True
720 - previous_space = True
721 - previous_break = False
722 - elif ch in u'\n\x85\u2028\u2029':
723 - if index == 0:
724 - leading_break = True
725 - if index == len(scalar)-1:
726 - trailing_break = True
727 - if previous_space:
728 - space_break = True
729 - previous_space = False
730 - previous_break = True
731 - else:
732 - previous_space = False
733 - previous_break = False
734 -
735 - # Prepare for the next character.
736 - index += 1
737 - preceeded_by_whitespace = (ch in u'\0 \t\r\n\x85\u2028\u2029')
738 - followed_by_whitespace = (index+1 >= len(scalar) or
739 - scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029')
740 -
741 - # Let's decide what styles are allowed.
742 - allow_flow_plain = True
743 - allow_block_plain = True
744 - allow_single_quoted = True
745 - allow_double_quoted = True
746 - allow_block = True
747 -
748 - # Leading and trailing whitespaces are bad for plain scalars.
749 - if (leading_space or leading_break
750 - or trailing_space or trailing_break):
751 - allow_flow_plain = allow_block_plain = False
752 -
753 - # We do not permit trailing spaces for block scalars.
754 - if trailing_space:
755 - allow_block = False
756 -
757 - # Spaces at the beginning of a new line are only acceptable for block
758 - # scalars.
759 - if break_space:
760 - allow_flow_plain = allow_block_plain = allow_single_quoted = False
761 -
762 - # Spaces followed by breaks, as well as special character are only
763 - # allowed for double quoted scalars.
764 - if space_break or special_characters:
765 - allow_flow_plain = allow_block_plain = \
766 - allow_single_quoted = allow_block = False
767 -
768 - # Although the plain scalar writer supports breaks, we never emit
769 - # multiline plain scalars.
770 - if line_breaks:
771 - allow_flow_plain = allow_block_plain = False
772 -
773 - # Flow indicators are forbidden for flow plain scalars.
774 - if flow_indicators:
775 - allow_flow_plain = False
776 -
777 - # Block indicators are forbidden for block plain scalars.
778 - if block_indicators:
779 - allow_block_plain = False
780 -
781 - return ScalarAnalysis(scalar=scalar,
782 - empty=False, multiline=line_breaks,
783 - allow_flow_plain=allow_flow_plain,
784 - allow_block_plain=allow_block_plain,
785 - allow_single_quoted=allow_single_quoted,
786 - allow_double_quoted=allow_double_quoted,
787 - allow_block=allow_block)
788 -
789 - # Writers.
790 -
791 - def flush_stream(self):
792 - if hasattr(self.stream, 'flush'):
793 - self.stream.flush()
794 -
795 - def write_stream_start(self):
796 - # Write BOM if needed.
797 - if self.encoding and self.encoding.startswith('utf-16'):
798 - self.stream.write(u'\uFEFF'.encode(self.encoding))
799 -
800 - def write_stream_end(self):
801 - self.flush_stream()
802 -
803 - def write_indicator(self, indicator, need_whitespace,
804 - whitespace=False, indention=False):
805 - if self.whitespace or not need_whitespace:
806 - data = indicator
807 - else:
808 - data = u' '+indicator
809 - self.whitespace = whitespace
810 - self.indention = self.indention and indention
811 - self.column += len(data)
812 - self.open_ended = False
813 - if self.encoding:
814 - data = data.encode(self.encoding)
815 - self.stream.write(data)
816 -
817 - def write_indent(self):
818 - indent = self.indent or 0
819 - if not self.indention or self.column > indent \
820 - or (self.column == indent and not self.whitespace):
821 - self.write_line_break()
822 - if self.column < indent:
823 - self.whitespace = True
824 - data = u' '*(indent-self.column)
825 - self.column = indent
826 - if self.encoding:
827 - data = data.encode(self.encoding)
828 - self.stream.write(data)
829 -
830 - def write_line_break(self, data=None):
831 - if data is None:
832 - data = self.best_line_break
833 - self.whitespace = True
834 - self.indention = True
835 - self.line += 1
836 - self.column = 0
837 - if self.encoding:
838 - data = data.encode(self.encoding)
839 - self.stream.write(data)
840 -
841 - def write_version_directive(self, version_text):
842 - data = u'%%YAML %s' % version_text
843 - if self.encoding:
844 - data = data.encode(self.encoding)
845 - self.stream.write(data)
846 - self.write_line_break()
847 -
848 - def write_tag_directive(self, handle_text, prefix_text):
849 - data = u'%%TAG %s %s' % (handle_text, prefix_text)
850 - if self.encoding:
851 - data = data.encode(self.encoding)
852 - self.stream.write(data)
853 - self.write_line_break()
854 -
855 - # Scalar streams.
856 -
857 - def write_single_quoted(self, text, split=True):
858 - self.write_indicator(u'\'', True)
859 - spaces = False
860 - breaks = False
861 - start = end = 0
862 - while end <= len(text):
863 - ch = None
864 - if end < len(text):
865 - ch = text[end]
866 - if spaces:
867 - if ch is None or ch != u' ':
868 - if start+1 == end and self.column > self.best_width and split \
869 - and start != 0 and end != len(text):
870 - self.write_indent()
871 - else:
872 - data = text[start:end]
873 - self.column += len(data)
874 - if self.encoding:
875 - data = data.encode(self.encoding)
876 - self.stream.write(data)
877 - start = end
878 - elif breaks:
879 - if ch is None or ch not in u'\n\x85\u2028\u2029':
880 - if text[start] == u'\n':
881 - self.write_line_break()
882 - for br in text[start:end]:
883 - if br == u'\n':
884 - self.write_line_break()
885 - else:
886 - self.write_line_break(br)
887 - self.write_indent()
888 - start = end
889 - else:
890 - if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u'\'':
891 - if start < end:
892 - data = text[start:end]
893 - self.column += len(data)
894 - if self.encoding:
895 - data = data.encode(self.encoding)
896 - self.stream.write(data)
897 - start = end
898 - if ch == u'\'':
899 - data = u'\'\''
900 - self.column += 2
901 - if self.encoding:
902 - data = data.encode(self.encoding)
903 - self.stream.write(data)
904 - start = end + 1
905 - if ch is not None:
906 - spaces = (ch == u' ')
907 - breaks = (ch in u'\n\x85\u2028\u2029')
908 - end += 1
909 - self.write_indicator(u'\'', False)
910 -
911 - ESCAPE_REPLACEMENTS = {
912 - u'\0': u'0',
913 - u'\x07': u'a',
914 - u'\x08': u'b',
915 - u'\x09': u't',
916 - u'\x0A': u'n',
917 - u'\x0B': u'v',
918 - u'\x0C': u'f',
919 - u'\x0D': u'r',
920 - u'\x1B': u'e',
921 - u'\"': u'\"',
922 - u'\\': u'\\',
923 - u'\x85': u'N',
924 - u'\xA0': u'_',
925 - u'\u2028': u'L',
926 - u'\u2029': u'P',
927 - }
928 -
929 - def write_double_quoted(self, text, split=True):
930 - self.write_indicator(u'"', True)
931 - start = end = 0
932 - while end <= len(text):
933 - ch = None
934 - if end < len(text):
935 - ch = text[end]
936 - if ch is None or ch in u'"\\\x85\u2028\u2029\uFEFF' \
937 - or not (u'\x20' <= ch <= u'\x7E'
938 - or (self.allow_unicode
939 - and (u'\xA0' <= ch <= u'\uD7FF'
940 - or u'\uE000' <= ch <= u'\uFFFD'))):
941 - if start < end:
942 - data = text[start:end]
943 - self.column += len(data)
944 - if self.encoding:
945 - data = data.encode(self.encoding)
946 - self.stream.write(data)
947 - start = end
948 - if ch is not None:
949 - if ch in self.ESCAPE_REPLACEMENTS:
950 - data = u'\\'+self.ESCAPE_REPLACEMENTS[ch]
951 - elif ch <= u'\xFF':
952 - data = u'\\x%02X' % ord(ch)
953 - elif ch <= u'\uFFFF':
954 - data = u'\\u%04X' % ord(ch)
955 - else:
956 - data = u'\\U%08X' % ord(ch)
957 - self.column += len(data)
958 - if self.encoding:
959 - data = data.encode(self.encoding)
960 - self.stream.write(data)
961 - start = end+1
962 - if 0 < end < len(text)-1 and (ch == u' ' or start >= end) \
963 - and self.column+(end-start) > self.best_width and split:
964 - data = text[start:end]+u'\\'
965 - if start < end:
966 - start = end
967 - self.column += len(data)
968 - if self.encoding:
969 - data = data.encode(self.encoding)
970 - self.stream.write(data)
971 - self.write_indent()
972 - self.whitespace = False
973 - self.indention = False
974 - if text[start] == u' ':
975 - data = u'\\'
976 - self.column += len(data)
977 - if self.encoding:
978 - data = data.encode(self.encoding)
979 - self.stream.write(data)
980 - end += 1
981 - self.write_indicator(u'"', False)
982 -
983 - def determine_block_hints(self, text):
984 - hints = u''
985 - if text:
986 - if text[0] in u' \n\x85\u2028\u2029':
987 - hints += unicode(self.best_indent)
988 - if text[-1] not in u'\n\x85\u2028\u2029':
989 - hints += u'-'
990 - elif len(text) == 1 or text[-2] in u'\n\x85\u2028\u2029':
991 - hints += u'+'
992 - return hints
993 -
994 - def write_folded(self, text):
995 - hints = self.determine_block_hints(text)
996 - self.write_indicator(u'>'+hints, True)
997 - if hints[-1:] == u'+':
998 - self.open_ended = True
999 - self.write_line_break()
1000 - leading_space = True
1001 - spaces = False
1002 - breaks = True
1003 - start = end = 0
1004 - while end <= len(text):
1005 - ch = None
1006 - if end < len(text):
1007 - ch = text[end]
1008 - if breaks:
1009 - if ch is None or ch not in u'\n\x85\u2028\u2029':
1010 - if not leading_space and ch is not None and ch != u' ' \
1011 - and text[start] == u'\n':
1012 - self.write_line_break()
1013 - leading_space = (ch == u' ')
1014 - for br in text[start:end]:
1015 - if br == u'\n':
1016 - self.write_line_break()
1017 - else:
1018 - self.write_line_break(br)
1019 - if ch is not None:
1020 - self.write_indent()
1021 - start = end
1022 - elif spaces:
1023 - if ch != u' ':
1024 - if start+1 == end and self.column > self.best_width:
1025 - self.write_indent()
1026 - else:
1027 - data = text[start:end]
1028 - self.column += len(data)
1029 - if self.encoding:
1030 - data = data.encode(self.encoding)
1031 - self.stream.write(data)
1032 - start = end
1033 - else:
1034 - if ch is None or ch in u' \n\x85\u2028\u2029':
1035 - data = text[start:end]
1036 - self.column += len(data)
1037 - if self.encoding:
1038 - data = data.encode(self.encoding)
1039 - self.stream.write(data)
1040 - if ch is None:
1041 - self.write_line_break()
1042 - start = end
1043 - if ch is not None:
1044 - breaks = (ch in u'\n\x85\u2028\u2029')
1045 - spaces = (ch == u' ')
1046 - end += 1
1047 -
1048 - def write_literal(self, text):
1049 - hints = self.determine_block_hints(text)
1050 - self.write_indicator(u'|'+hints, True)
1051 - if hints[-1:] == u'+':
1052 - self.open_ended = True
1053 - self.write_line_break()
1054 - breaks = True
1055 - start = end = 0
1056 - while end <= len(text):
1057 - ch = None
1058 - if end < len(text):
1059 - ch = text[end]
1060 - if breaks:
1061 - if ch is None or ch not in u'\n\x85\u2028\u2029':
1062 - for br in text[start:end]:
1063 - if br == u'\n':
1064 - self.write_line_break()
1065 - else:
1066 - self.write_line_break(br)
1067 - if ch is not None:
1068 - self.write_indent()
1069 - start = end
1070 - else:
1071 - if ch is None or ch in u'\n\x85\u2028\u2029':
1072 - data = text[start:end]
1073 - if self.encoding:
1074 - data = data.encode(self.encoding)
1075 - self.stream.write(data)
1076 - if ch is None:
1077 - self.write_line_break()
1078 - start = end
1079 - if ch is not None:
1080 - breaks = (ch in u'\n\x85\u2028\u2029')
1081 - end += 1
1082 -
1083 - def write_plain(self, text, split=True):
1084 - if self.root_context:
1085 - self.open_ended = True
1086 - if not text:
1087 - return
1088 - if not self.whitespace:
1089 - data = u' '
1090 - self.column += len(data)
1091 - if self.encoding:
1092 - data = data.encode(self.encoding)
1093 - self.stream.write(data)
1094 - self.whitespace = False
1095 - self.indention = False
1096 - spaces = False
1097 - breaks = False
1098 - start = end = 0
1099 - while end <= len(text):
1100 - ch = None
1101 - if end < len(text):
1102 - ch = text[end]
1103 - if spaces:
1104 - if ch != u' ':
1105 - if start+1 == end and self.column > self.best_width and split:
1106 - self.write_indent()
1107 - self.whitespace = False
1108 - self.indention = False
1109 - else:
1110 - data = text[start:end]
1111 - self.column += len(data)
1112 - if self.encoding:
1113 - data = data.encode(self.encoding)
1114 - self.stream.write(data)
1115 - start = end
1116 - elif breaks:
1117 - if ch not in u'\n\x85\u2028\u2029':
1118 - if text[start] == u'\n':
1119 - self.write_line_break()
1120 - for br in text[start:end]:
1121 - if br == u'\n':
1122 - self.write_line_break()
1123 - else:
1124 - self.write_line_break(br)
1125 - self.write_indent()
1126 - self.whitespace = False
1127 - self.indention = False
1128 - start = end
1129 - else:
1130 - if ch is None or ch in u' \n\x85\u2028\u2029':
1131 - data = text[start:end]
1132 - self.column += len(data)
1133 - if self.encoding:
1134 - data = data.encode(self.encoding)
1135 - self.stream.write(data)
1136 - start = end
1137 - if ch is not None:
1138 - spaces = (ch == u' ')
1139 - breaks = (ch in u'\n\x85\u2028\u2029')
1140 - end += 1
1141 -
src/collectors/python.d.plugin/python_modules/pyyaml2/error.py deleted
-76
@@ -1,76 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
4 -
5 -class Mark(object):
6 -
7 - def __init__(self, name, index, line, column, buffer, pointer):
8 - self.name = name
9 - self.index = index
10 - self.line = line
11 - self.column = column
12 - self.buffer = buffer
13 - self.pointer = pointer
14 -
15 - def get_snippet(self, indent=4, max_length=75):
16 - if self.buffer is None:
17 - return None
18 - head = ''
19 - start = self.pointer
20 - while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029':
21 - start -= 1
22 - if self.pointer-start > max_length/2-1:
23 - head = ' ... '
24 - start += 5
25 - break
26 - tail = ''
27 - end = self.pointer
28 - while end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029':
29 - end += 1
30 - if end-self.pointer > max_length/2-1:
31 - tail = ' ... '
32 - end -= 5
33 - break
34 - snippet = self.buffer[start:end].encode('utf-8')
35 - return ' '*indent + head + snippet + tail + '\n' \
36 - + ' '*(indent+self.pointer-start+len(head)) + '^'
37 -
38 - def __str__(self):
39 - snippet = self.get_snippet()
40 - where = " in \"%s\", line %d, column %d" \
41 - % (self.name, self.line+1, self.column+1)
42 - if snippet is not None:
43 - where += ":\n"+snippet
44 - return where
45 -
46 -class YAMLError(Exception):
47 - pass
48 -
49 -class MarkedYAMLError(YAMLError):
50 -
51 - def __init__(self, context=None, context_mark=None,
52 - problem=None, problem_mark=None, note=None):
53 - self.context = context
54 - self.context_mark = context_mark
55 - self.problem = problem
56 - self.problem_mark = problem_mark
57 - self.note = note
58 -
59 - def __str__(self):
60 - lines = []
61 - if self.context is not None:
62 - lines.append(self.context)
63 - if self.context_mark is not None \
64 - and (self.problem is None or self.problem_mark is None
65 - or self.context_mark.name != self.problem_mark.name
66 - or self.context_mark.line != self.problem_mark.line
67 - or self.context_mark.column != self.problem_mark.column):
68 - lines.append(str(self.context_mark))
69 - if self.problem is not None:
70 - lines.append(self.problem)
71 - if self.problem_mark is not None:
72 - lines.append(str(self.problem_mark))
73 - if self.note is not None:
74 - lines.append(self.note)
75 - return '\n'.join(lines)
76 -
src/collectors/python.d.plugin/python_modules/pyyaml2/events.py deleted
-87
@@ -1,87 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -# Abstract classes.
4 -
5 -class Event(object):
6 - def __init__(self, start_mark=None, end_mark=None):
7 - self.start_mark = start_mark
8 - self.end_mark = end_mark
9 - def __repr__(self):
10 - attributes = [key for key in ['anchor', 'tag', 'implicit', 'value']
11 - if hasattr(self, key)]
12 - arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
13 - for key in attributes])
14 - return '%s(%s)' % (self.__class__.__name__, arguments)
15 -
16 -class NodeEvent(Event):
17 - def __init__(self, anchor, start_mark=None, end_mark=None):
18 - self.anchor = anchor
19 - self.start_mark = start_mark
20 - self.end_mark = end_mark
21 -
22 -class CollectionStartEvent(NodeEvent):
23 - def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None,
24 - flow_style=None):
25 - self.anchor = anchor
26 - self.tag = tag
27 - self.implicit = implicit
28 - self.start_mark = start_mark
29 - self.end_mark = end_mark
30 - self.flow_style = flow_style
31 -
32 -class CollectionEndEvent(Event):
33 - pass
34 -
35 -# Implementations.
36 -
37 -class StreamStartEvent(Event):
38 - def __init__(self, start_mark=None, end_mark=None, encoding=None):
39 - self.start_mark = start_mark
40 - self.end_mark = end_mark
41 - self.encoding = encoding
42 -
43 -class StreamEndEvent(Event):
44 - pass
45 -
46 -class DocumentStartEvent(Event):
47 - def __init__(self, start_mark=None, end_mark=None,
48 - explicit=None, version=None, tags=None):
49 - self.start_mark = start_mark
50 - self.end_mark = end_mark
51 - self.explicit = explicit
52 - self.version = version
53 - self.tags = tags
54 -
55 -class DocumentEndEvent(Event):
56 - def __init__(self, start_mark=None, end_mark=None,
57 - explicit=None):
58 - self.start_mark = start_mark
59 - self.end_mark = end_mark
60 - self.explicit = explicit
61 -
62 -class AliasEvent(NodeEvent):
63 - pass
64 -
65 -class ScalarEvent(NodeEvent):
66 - def __init__(self, anchor, tag, implicit, value,
67 - start_mark=None, end_mark=None, style=None):
68 - self.anchor = anchor
69 - self.tag = tag
70 - self.implicit = implicit
71 - self.value = value
72 - self.start_mark = start_mark
73 - self.end_mark = end_mark
74 - self.style = style
75 -
76 -class SequenceStartEvent(CollectionStartEvent):
77 - pass
78 -
79 -class SequenceEndEvent(CollectionEndEvent):
80 - pass
81 -
82 -class MappingStartEvent(CollectionStartEvent):
83 - pass
84 -
85 -class MappingEndEvent(CollectionEndEvent):
86 - pass
87 -
src/collectors/python.d.plugin/python_modules/pyyaml2/loader.py deleted
-41
@@ -1,41 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['BaseLoader', 'SafeLoader', 'Loader']
4 -
5 -from reader import *
6 -from scanner import *
7 -from parser import *
8 -from composer import *
9 -from constructor import *
10 -from resolver import *
11 -
12 -class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
13 -
14 - def __init__(self, stream):
15 - Reader.__init__(self, stream)
16 - Scanner.__init__(self)
17 - Parser.__init__(self)
18 - Composer.__init__(self)
19 - BaseConstructor.__init__(self)
20 - BaseResolver.__init__(self)
21 -
22 -class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver):
23 -
24 - def __init__(self, stream):
25 - Reader.__init__(self, stream)
26 - Scanner.__init__(self)
27 - Parser.__init__(self)
28 - Composer.__init__(self)
29 - SafeConstructor.__init__(self)
30 - Resolver.__init__(self)
31 -
32 -class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
33 -
34 - def __init__(self, stream):
35 - Reader.__init__(self, stream)
36 - Scanner.__init__(self)
37 - Parser.__init__(self)
38 - Composer.__init__(self)
39 - Constructor.__init__(self)
40 - Resolver.__init__(self)
41 -
src/collectors/python.d.plugin/python_modules/pyyaml2/nodes.py deleted
-50
@@ -1,50 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -class Node(object):
4 - def __init__(self, tag, value, start_mark, end_mark):
5 - self.tag = tag
6 - self.value = value
7 - self.start_mark = start_mark
8 - self.end_mark = end_mark
9 - def __repr__(self):
10 - value = self.value
11 - #if isinstance(value, list):
12 - # if len(value) == 0:
13 - # value = '<empty>'
14 - # elif len(value) == 1:
15 - # value = '<1 item>'
16 - # else:
17 - # value = '<%d items>' % len(value)
18 - #else:
19 - # if len(value) > 75:
20 - # value = repr(value[:70]+u' ... ')
21 - # else:
22 - # value = repr(value)
23 - value = repr(value)
24 - return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value)
25 -
26 -class ScalarNode(Node):
27 - id = 'scalar'
28 - def __init__(self, tag, value,
29 - start_mark=None, end_mark=None, style=None):
30 - self.tag = tag
31 - self.value = value
32 - self.start_mark = start_mark
33 - self.end_mark = end_mark
34 - self.style = style
35 -
36 -class CollectionNode(Node):
37 - def __init__(self, tag, value,
38 - start_mark=None, end_mark=None, flow_style=None):
39 - self.tag = tag
40 - self.value = value
41 - self.start_mark = start_mark
42 - self.end_mark = end_mark
43 - self.flow_style = flow_style
44 -
45 -class SequenceNode(CollectionNode):
46 - id = 'sequence'
47 -
48 -class MappingNode(CollectionNode):
49 - id = 'mapping'
50 -
src/collectors/python.d.plugin/python_modules/pyyaml2/parser.py deleted
-590
@@ -1,590 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -# The following YAML grammar is LL(1) and is parsed by a recursive descent
4 -# parser.
5 -#
6 -# stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
7 -# implicit_document ::= block_node DOCUMENT-END*
8 -# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
9 -# block_node_or_indentless_sequence ::=
10 -# ALIAS
11 -# | properties (block_content | indentless_block_sequence)?
12 -# | block_content
13 -# | indentless_block_sequence
14 -# block_node ::= ALIAS
15 -# | properties block_content?
16 -# | block_content
17 -# flow_node ::= ALIAS
18 -# | properties flow_content?
19 -# | flow_content
20 -# properties ::= TAG ANCHOR? | ANCHOR TAG?
21 -# block_content ::= block_collection | flow_collection | SCALAR
22 -# flow_content ::= flow_collection | SCALAR
23 -# block_collection ::= block_sequence | block_mapping
24 -# flow_collection ::= flow_sequence | flow_mapping
25 -# block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
26 -# indentless_sequence ::= (BLOCK-ENTRY block_node?)+
27 -# block_mapping ::= BLOCK-MAPPING_START
28 -# ((KEY block_node_or_indentless_sequence?)?
29 -# (VALUE block_node_or_indentless_sequence?)?)*
30 -# BLOCK-END
31 -# flow_sequence ::= FLOW-SEQUENCE-START
32 -# (flow_sequence_entry FLOW-ENTRY)*
33 -# flow_sequence_entry?
34 -# FLOW-SEQUENCE-END
35 -# flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
36 -# flow_mapping ::= FLOW-MAPPING-START
37 -# (flow_mapping_entry FLOW-ENTRY)*
38 -# flow_mapping_entry?
39 -# FLOW-MAPPING-END
40 -# flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
41 -#
42 -# FIRST sets:
43 -#
44 -# stream: { STREAM-START }
45 -# explicit_document: { DIRECTIVE DOCUMENT-START }
46 -# implicit_document: FIRST(block_node)
47 -# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
48 -# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
49 -# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
50 -# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
51 -# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
52 -# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
53 -# block_sequence: { BLOCK-SEQUENCE-START }
54 -# block_mapping: { BLOCK-MAPPING-START }
55 -# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY }
56 -# indentless_sequence: { ENTRY }
57 -# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
58 -# flow_sequence: { FLOW-SEQUENCE-START }
59 -# flow_mapping: { FLOW-MAPPING-START }
60 -# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
61 -# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
62 -
63 -__all__ = ['Parser', 'ParserError']
64 -
65 -from error import MarkedYAMLError
66 -from tokens import *
67 -from events import *
68 -from scanner import *
69 -
70 -class ParserError(MarkedYAMLError):
71 - pass
72 -
73 -class Parser(object):
74 - # Since writing a recursive-descendant parser is a straightforward task, we
75 - # do not give many comments here.
76 -
77 - DEFAULT_TAGS = {
78 - u'!': u'!',
79 - u'!!': u'tag:yaml.org,2002:',
80 - }
81 -
82 - def __init__(self):
83 - self.current_event = None
84 - self.yaml_version = None
85 - self.tag_handles = {}
86 - self.states = []
87 - self.marks = []
88 - self.state = self.parse_stream_start
89 -
90 - def dispose(self):
91 - # Reset the state attributes (to clear self-references)
92 - self.states = []
93 - self.state = None
94 -
95 - def check_event(self, *choices):
96 - # Check the type of the next event.
97 - if self.current_event is None:
98 - if self.state:
99 - self.current_event = self.state()
100 - if self.current_event is not None:
101 - if not choices:
102 - return True
103 - for choice in choices:
104 - if isinstance(self.current_event, choice):
105 - return True
106 - return False
107 -
108 - def peek_event(self):
109 - # Get the next event.
110 - if self.current_event is None:
111 - if self.state:
112 - self.current_event = self.state()
113 - return self.current_event
114 -
115 - def get_event(self):
116 - # Get the next event and proceed further.
117 - if self.current_event is None:
118 - if self.state:
119 - self.current_event = self.state()
120 - value = self.current_event
121 - self.current_event = None
122 - return value
123 -
124 - # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
125 - # implicit_document ::= block_node DOCUMENT-END*
126 - # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
127 -
128 - def parse_stream_start(self):
129 -
130 - # Parse the stream start.
131 - token = self.get_token()
132 - event = StreamStartEvent(token.start_mark, token.end_mark,
133 - encoding=token.encoding)
134 -
135 - # Prepare the next state.
136 - self.state = self.parse_implicit_document_start
137 -
138 - return event
139 -
140 - def parse_implicit_document_start(self):
141 -
142 - # Parse an implicit document.
143 - if not self.check_token(DirectiveToken, DocumentStartToken,
144 - StreamEndToken):
145 - self.tag_handles = self.DEFAULT_TAGS
146 - token = self.peek_token()
147 - start_mark = end_mark = token.start_mark
148 - event = DocumentStartEvent(start_mark, end_mark,
149 - explicit=False)
150 -
151 - # Prepare the next state.
152 - self.states.append(self.parse_document_end)
153 - self.state = self.parse_block_node
154 -
155 - return event
156 -
157 - else:
158 - return self.parse_document_start()
159 -
160 - def parse_document_start(self):
161 -
162 - # Parse any extra document end indicators.
163 - while self.check_token(DocumentEndToken):
164 - self.get_token()
165 -
166 - # Parse an explicit document.
167 - if not self.check_token(StreamEndToken):
168 - token = self.peek_token()
169 - start_mark = token.start_mark
170 - version, tags = self.process_directives()
171 - if not self.check_token(DocumentStartToken):
172 - raise ParserError(None, None,
173 - "expected '<document start>', but found %r"
174 - % self.peek_token().id,
175 - self.peek_token().start_mark)
176 - token = self.get_token()
177 - end_mark = token.end_mark
178 - event = DocumentStartEvent(start_mark, end_mark,
179 - explicit=True, version=version, tags=tags)
180 - self.states.append(self.parse_document_end)
181 - self.state = self.parse_document_content
182 - else:
183 - # Parse the end of the stream.
184 - token = self.get_token()
185 - event = StreamEndEvent(token.start_mark, token.end_mark)
186 - assert not self.states
187 - assert not self.marks
188 - self.state = None
189 - return event
190 -
191 - def parse_document_end(self):
192 -
193 - # Parse the document end.
194 - token = self.peek_token()
195 - start_mark = end_mark = token.start_mark
196 - explicit = False
197 - if self.check_token(DocumentEndToken):
198 - token = self.get_token()
199 - end_mark = token.end_mark
200 - explicit = True
201 - event = DocumentEndEvent(start_mark, end_mark,
202 - explicit=explicit)
203 -
204 - # Prepare the next state.
205 - self.state = self.parse_document_start
206 -
207 - return event
208 -
209 - def parse_document_content(self):
210 - if self.check_token(DirectiveToken,
211 - DocumentStartToken, DocumentEndToken, StreamEndToken):
212 - event = self.process_empty_scalar(self.peek_token().start_mark)
213 - self.state = self.states.pop()
214 - return event
215 - else:
216 - return self.parse_block_node()
217 -
218 - def process_directives(self):
219 - self.yaml_version = None
220 - self.tag_handles = {}
221 - while self.check_token(DirectiveToken):
222 - token = self.get_token()
223 - if token.name == u'YAML':
224 - if self.yaml_version is not None:
225 - raise ParserError(None, None,
226 - "found duplicate YAML directive", token.start_mark)
227 - major, minor = token.value
228 - if major != 1:
229 - raise ParserError(None, None,
230 - "found incompatible YAML document (version 1.* is required)",
231 - token.start_mark)
232 - self.yaml_version = token.value
233 - elif token.name == u'TAG':
234 - handle, prefix = token.value
235 - if handle in self.tag_handles:
236 - raise ParserError(None, None,
237 - "duplicate tag handle %r" % handle.encode('utf-8'),
238 - token.start_mark)
239 - self.tag_handles[handle] = prefix
240 - if self.tag_handles:
241 - value = self.yaml_version, self.tag_handles.copy()
242 - else:
243 - value = self.yaml_version, None
244 - for key in self.DEFAULT_TAGS:
245 - if key not in self.tag_handles:
246 - self.tag_handles[key] = self.DEFAULT_TAGS[key]
247 - return value
248 -
249 - # block_node_or_indentless_sequence ::= ALIAS
250 - # | properties (block_content | indentless_block_sequence)?
251 - # | block_content
252 - # | indentless_block_sequence
253 - # block_node ::= ALIAS
254 - # | properties block_content?
255 - # | block_content
256 - # flow_node ::= ALIAS
257 - # | properties flow_content?
258 - # | flow_content
259 - # properties ::= TAG ANCHOR? | ANCHOR TAG?
260 - # block_content ::= block_collection | flow_collection | SCALAR
261 - # flow_content ::= flow_collection | SCALAR
262 - # block_collection ::= block_sequence | block_mapping
263 - # flow_collection ::= flow_sequence | flow_mapping
264 -
265 - def parse_block_node(self):
266 - return self.parse_node(block=True)
267 -
268 - def parse_flow_node(self):
269 - return self.parse_node()
270 -
271 - def parse_block_node_or_indentless_sequence(self):
272 - return self.parse_node(block=True, indentless_sequence=True)
273 -
274 - def parse_node(self, block=False, indentless_sequence=False):
275 - if self.check_token(AliasToken):
276 - token = self.get_token()
277 - event = AliasEvent(token.value, token.start_mark, token.end_mark)
278 - self.state = self.states.pop()
279 - else:
280 - anchor = None
281 - tag = None
282 - start_mark = end_mark = tag_mark = None
283 - if self.check_token(AnchorToken):
284 - token = self.get_token()
285 - start_mark = token.start_mark
286 - end_mark = token.end_mark
287 - anchor = token.value
288 - if self.check_token(TagToken):
289 - token = self.get_token()
290 - tag_mark = token.start_mark
291 - end_mark = token.end_mark
292 - tag = token.value
293 - elif self.check_token(TagToken):
294 - token = self.get_token()
295 - start_mark = tag_mark = token.start_mark
296 - end_mark = token.end_mark
297 - tag = token.value
298 - if self.check_token(AnchorToken):
299 - token = self.get_token()
300 - end_mark = token.end_mark
301 - anchor = token.value
302 - if tag is not None:
303 - handle, suffix = tag
304 - if handle is not None:
305 - if handle not in self.tag_handles:
306 - raise ParserError("while parsing a node", start_mark,
307 - "found undefined tag handle %r" % handle.encode('utf-8'),
308 - tag_mark)
309 - tag = self.tag_handles[handle]+suffix
310 - else:
311 - tag = suffix
312 - #if tag == u'!':
313 - # raise ParserError("while parsing a node", start_mark,
314 - # "found non-specific tag '!'", tag_mark,
315 - # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.")
316 - if start_mark is None:
317 - start_mark = end_mark = self.peek_token().start_mark
318 - event = None
319 - implicit = (tag is None or tag == u'!')
320 - if indentless_sequence and self.check_token(BlockEntryToken):
321 - end_mark = self.peek_token().end_mark
322 - event = SequenceStartEvent(anchor, tag, implicit,
323 - start_mark, end_mark)
324 - self.state = self.parse_indentless_sequence_entry
325 - else:
326 - if self.check_token(ScalarToken):
327 - token = self.get_token()
328 - end_mark = token.end_mark
329 - if (token.plain and tag is None) or tag == u'!':
330 - implicit = (True, False)
331 - elif tag is None:
332 - implicit = (False, True)
333 - else:
334 - implicit = (False, False)
335 - event = ScalarEvent(anchor, tag, implicit, token.value,
336 - start_mark, end_mark, style=token.style)
337 - self.state = self.states.pop()
338 - elif self.check_token(FlowSequenceStartToken):
339 - end_mark = self.peek_token().end_mark
340 - event = SequenceStartEvent(anchor, tag, implicit,
341 - start_mark, end_mark, flow_style=True)
342 - self.state = self.parse_flow_sequence_first_entry
343 - elif self.check_token(FlowMappingStartToken):
344 - end_mark = self.peek_token().end_mark
345 - event = MappingStartEvent(anchor, tag, implicit,
346 - start_mark, end_mark, flow_style=True)
347 - self.state = self.parse_flow_mapping_first_key
348 - elif block and self.check_token(BlockSequenceStartToken):
349 - end_mark = self.peek_token().start_mark
350 - event = SequenceStartEvent(anchor, tag, implicit,
351 - start_mark, end_mark, flow_style=False)
352 - self.state = self.parse_block_sequence_first_entry
353 - elif block and self.check_token(BlockMappingStartToken):
354 - end_mark = self.peek_token().start_mark
355 - event = MappingStartEvent(anchor, tag, implicit,
356 - start_mark, end_mark, flow_style=False)
357 - self.state = self.parse_block_mapping_first_key
358 - elif anchor is not None or tag is not None:
359 - # Empty scalars are allowed even if a tag or an anchor is
360 - # specified.
361 - event = ScalarEvent(anchor, tag, (implicit, False), u'',
362 - start_mark, end_mark)
363 - self.state = self.states.pop()
364 - else:
365 - if block:
366 - node = 'block'
367 - else:
368 - node = 'flow'
369 - token = self.peek_token()
370 - raise ParserError("while parsing a %s node" % node, start_mark,
371 - "expected the node content, but found %r" % token.id,
372 - token.start_mark)
373 - return event
374 -
375 - # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
376 -
377 - def parse_block_sequence_first_entry(self):
378 - token = self.get_token()
379 - self.marks.append(token.start_mark)
380 - return self.parse_block_sequence_entry()
381 -
382 - def parse_block_sequence_entry(self):
383 - if self.check_token(BlockEntryToken):
384 - token = self.get_token()
385 - if not self.check_token(BlockEntryToken, BlockEndToken):
386 - self.states.append(self.parse_block_sequence_entry)
387 - return self.parse_block_node()
388 - else:
389 - self.state = self.parse_block_sequence_entry
390 - return self.process_empty_scalar(token.end_mark)
391 - if not self.check_token(BlockEndToken):
392 - token = self.peek_token()
393 - raise ParserError("while parsing a block collection", self.marks[-1],
394 - "expected <block end>, but found %r" % token.id, token.start_mark)
395 - token = self.get_token()
396 - event = SequenceEndEvent(token.start_mark, token.end_mark)
397 - self.state = self.states.pop()
398 - self.marks.pop()
399 - return event
400 -
401 - # indentless_sequence ::= (BLOCK-ENTRY block_node?)+
402 -
403 - def parse_indentless_sequence_entry(self):
404 - if self.check_token(BlockEntryToken):
405 - token = self.get_token()
406 - if not self.check_token(BlockEntryToken,
407 - KeyToken, ValueToken, BlockEndToken):
408 - self.states.append(self.parse_indentless_sequence_entry)
409 - return self.parse_block_node()
410 - else:
411 - self.state = self.parse_indentless_sequence_entry
412 - return self.process_empty_scalar(token.end_mark)
413 - token = self.peek_token()
414 - event = SequenceEndEvent(token.start_mark, token.start_mark)
415 - self.state = self.states.pop()
416 - return event
417 -
418 - # block_mapping ::= BLOCK-MAPPING_START
419 - # ((KEY block_node_or_indentless_sequence?)?
420 - # (VALUE block_node_or_indentless_sequence?)?)*
421 - # BLOCK-END
422 -
423 - def parse_block_mapping_first_key(self):
424 - token = self.get_token()
425 - self.marks.append(token.start_mark)
426 - return self.parse_block_mapping_key()
427 -
428 - def parse_block_mapping_key(self):
429 - if self.check_token(KeyToken):
430 - token = self.get_token()
431 - if not self.check_token(KeyToken, ValueToken, BlockEndToken):
432 - self.states.append(self.parse_block_mapping_value)
433 - return self.parse_block_node_or_indentless_sequence()
434 - else:
435 - self.state = self.parse_block_mapping_value
436 - return self.process_empty_scalar(token.end_mark)
437 - if not self.check_token(BlockEndToken):
438 - token = self.peek_token()
439 - raise ParserError("while parsing a block mapping", self.marks[-1],
440 - "expected <block end>, but found %r" % token.id, token.start_mark)
441 - token = self.get_token()
442 - event = MappingEndEvent(token.start_mark, token.end_mark)
443 - self.state = self.states.pop()
444 - self.marks.pop()
445 - return event
446 -
447 - def parse_block_mapping_value(self):
448 - if self.check_token(ValueToken):
449 - token = self.get_token()
450 - if not self.check_token(KeyToken, ValueToken, BlockEndToken):
451 - self.states.append(self.parse_block_mapping_key)
452 - return self.parse_block_node_or_indentless_sequence()
453 - else:
454 - self.state = self.parse_block_mapping_key
455 - return self.process_empty_scalar(token.end_mark)
456 - else:
457 - self.state = self.parse_block_mapping_key
458 - token = self.peek_token()
459 - return self.process_empty_scalar(token.start_mark)
460 -
461 - # flow_sequence ::= FLOW-SEQUENCE-START
462 - # (flow_sequence_entry FLOW-ENTRY)*
463 - # flow_sequence_entry?
464 - # FLOW-SEQUENCE-END
465 - # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
466 - #
467 - # Note that while production rules for both flow_sequence_entry and
468 - # flow_mapping_entry are equal, their interpretations are different.
469 - # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
470 - # generate an inline mapping (set syntax).
471 -
472 - def parse_flow_sequence_first_entry(self):
473 - token = self.get_token()
474 - self.marks.append(token.start_mark)
475 - return self.parse_flow_sequence_entry(first=True)
476 -
477 - def parse_flow_sequence_entry(self, first=False):
478 - if not self.check_token(FlowSequenceEndToken):
479 - if not first:
480 - if self.check_token(FlowEntryToken):
481 - self.get_token()
482 - else:
483 - token = self.peek_token()
484 - raise ParserError("while parsing a flow sequence", self.marks[-1],
485 - "expected ',' or ']', but got %r" % token.id, token.start_mark)
486 -
487 - if self.check_token(KeyToken):
488 - token = self.peek_token()
489 - event = MappingStartEvent(None, None, True,
490 - token.start_mark, token.end_mark,
491 - flow_style=True)
492 - self.state = self.parse_flow_sequence_entry_mapping_key
493 - return event
494 - elif not self.check_token(FlowSequenceEndToken):
495 - self.states.append(self.parse_flow_sequence_entry)
496 - return self.parse_flow_node()
497 - token = self.get_token()
498 - event = SequenceEndEvent(token.start_mark, token.end_mark)
499 - self.state = self.states.pop()
500 - self.marks.pop()
501 - return event
502 -
503 - def parse_flow_sequence_entry_mapping_key(self):
504 - token = self.get_token()
505 - if not self.check_token(ValueToken,
506 - FlowEntryToken, FlowSequenceEndToken):
507 - self.states.append(self.parse_flow_sequence_entry_mapping_value)
508 - return self.parse_flow_node()
509 - else:
510 - self.state = self.parse_flow_sequence_entry_mapping_value
511 - return self.process_empty_scalar(token.end_mark)
512 -
513 - def parse_flow_sequence_entry_mapping_value(self):
514 - if self.check_token(ValueToken):
515 - token = self.get_token()
516 - if not self.check_token(FlowEntryToken, FlowSequenceEndToken):
517 - self.states.append(self.parse_flow_sequence_entry_mapping_end)
518 - return self.parse_flow_node()
519 - else:
520 - self.state = self.parse_flow_sequence_entry_mapping_end
521 - return self.process_empty_scalar(token.end_mark)
522 - else:
523 - self.state = self.parse_flow_sequence_entry_mapping_end
524 - token = self.peek_token()
525 - return self.process_empty_scalar(token.start_mark)
526 -
527 - def parse_flow_sequence_entry_mapping_end(self):
528 - self.state = self.parse_flow_sequence_entry
529 - token = self.peek_token()
530 - return MappingEndEvent(token.start_mark, token.start_mark)
531 -
532 - # flow_mapping ::= FLOW-MAPPING-START
533 - # (flow_mapping_entry FLOW-ENTRY)*
534 - # flow_mapping_entry?
535 - # FLOW-MAPPING-END
536 - # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
537 -
538 - def parse_flow_mapping_first_key(self):
539 - token = self.get_token()
540 - self.marks.append(token.start_mark)
541 - return self.parse_flow_mapping_key(first=True)
542 -
543 - def parse_flow_mapping_key(self, first=False):
544 - if not self.check_token(FlowMappingEndToken):
545 - if not first:
546 - if self.check_token(FlowEntryToken):
547 - self.get_token()
548 - else:
549 - token = self.peek_token()
550 - raise ParserError("while parsing a flow mapping", self.marks[-1],
551 - "expected ',' or '}', but got %r" % token.id, token.start_mark)
552 - if self.check_token(KeyToken):
553 - token = self.get_token()
554 - if not self.check_token(ValueToken,
555 - FlowEntryToken, FlowMappingEndToken):
556 - self.states.append(self.parse_flow_mapping_value)
557 - return self.parse_flow_node()
558 - else:
559 - self.state = self.parse_flow_mapping_value
560 - return self.process_empty_scalar(token.end_mark)
561 - elif not self.check_token(FlowMappingEndToken):
562 - self.states.append(self.parse_flow_mapping_empty_value)
563 - return self.parse_flow_node()
564 - token = self.get_token()
565 - event = MappingEndEvent(token.start_mark, token.end_mark)
566 - self.state = self.states.pop()
567 - self.marks.pop()
568 - return event
569 -
570 - def parse_flow_mapping_value(self):
571 - if self.check_token(ValueToken):
572 - token = self.get_token()
573 - if not self.check_token(FlowEntryToken, FlowMappingEndToken):
574 - self.states.append(self.parse_flow_mapping_key)
575 - return self.parse_flow_node()
576 - else:
577 - self.state = self.parse_flow_mapping_key
578 - return self.process_empty_scalar(token.end_mark)
579 - else:
580 - self.state = self.parse_flow_mapping_key
581 - token = self.peek_token()
582 - return self.process_empty_scalar(token.start_mark)
583 -
584 - def parse_flow_mapping_empty_value(self):
585 - self.state = self.parse_flow_mapping_key
586 - return self.process_empty_scalar(self.peek_token().start_mark)
587 -
588 - def process_empty_scalar(self, mark):
589 - return ScalarEvent(None, None, (True, False), u'', mark, mark)
590 -
src/collectors/python.d.plugin/python_modules/pyyaml2/reader.py deleted
-191
@@ -1,191 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -# This module contains abstractions for the input stream. You don't have to
3 -# looks further, there are no pretty code.
4 -#
5 -# We define two classes here.
6 -#
7 -# Mark(source, line, column)
8 -# It's just a record and its only use is producing nice error messages.
9 -# Parser does not use it for any other purposes.
10 -#
11 -# Reader(source, data)
12 -# Reader determines the encoding of `data` and converts it to unicode.
13 -# Reader provides the following methods and attributes:
14 -# reader.peek(length=1) - return the next `length` characters
15 -# reader.forward(length=1) - move the current position to `length` characters.
16 -# reader.index - the number of the current character.
17 -# reader.line, stream.column - the line and the column of the current character.
18 -
19 -__all__ = ['Reader', 'ReaderError']
20 -
21 -from error import YAMLError, Mark
22 -
23 -import codecs, re
24 -
25 -class ReaderError(YAMLError):
26 -
27 - def __init__(self, name, position, character, encoding, reason):
28 - self.name = name
29 - self.character = character
30 - self.position = position
31 - self.encoding = encoding
32 - self.reason = reason
33 -
34 - def __str__(self):
35 - if isinstance(self.character, str):
36 - return "'%s' codec can't decode byte #x%02x: %s\n" \
37 - " in \"%s\", position %d" \
38 - % (self.encoding, ord(self.character), self.reason,
39 - self.name, self.position)
40 - else:
41 - return "unacceptable character #x%04x: %s\n" \
42 - " in \"%s\", position %d" \
43 - % (self.character, self.reason,
44 - self.name, self.position)
45 -
46 -class Reader(object):
47 - # Reader:
48 - # - determines the data encoding and converts it to unicode,
49 - # - checks if characters are in allowed range,
50 - # - adds '\0' to the end.
51 -
52 - # Reader accepts
53 - # - a `str` object,
54 - # - a `unicode` object,
55 - # - a file-like object with its `read` method returning `str`,
56 - # - a file-like object with its `read` method returning `unicode`.
57 -
58 - # Yeah, it's ugly and slow.
59 -
60 - def __init__(self, stream):
61 - self.name = None
62 - self.stream = None
63 - self.stream_pointer = 0
64 - self.eof = True
65 - self.buffer = u''
66 - self.pointer = 0
67 - self.raw_buffer = None
68 - self.raw_decode = None
69 - self.encoding = None
70 - self.index = 0
71 - self.line = 0
72 - self.column = 0
73 - if isinstance(stream, unicode):
74 - self.name = "<unicode string>"
75 - self.check_printable(stream)
76 - self.buffer = stream+u'\0'
77 - elif isinstance(stream, str):
78 - self.name = "<string>"
79 - self.raw_buffer = stream
80 - self.determine_encoding()
81 - else:
82 - self.stream = stream
83 - self.name = getattr(stream, 'name', "<file>")
84 - self.eof = False
85 - self.raw_buffer = ''
86 - self.determine_encoding()
87 -
88 - def peek(self, index=0):
89 - try:
90 - return self.buffer[self.pointer+index]
91 - except IndexError:
92 - self.update(index+1)
93 - return self.buffer[self.pointer+index]
94 -
95 - def prefix(self, length=1):
96 - if self.pointer+length >= len(self.buffer):
97 - self.update(length)
98 - return self.buffer[self.pointer:self.pointer+length]
99 -
100 - def forward(self, length=1):
101 - if self.pointer+length+1 >= len(self.buffer):
102 - self.update(length+1)
103 - while length:
104 - ch = self.buffer[self.pointer]
105 - self.pointer += 1
106 - self.index += 1
107 - if ch in u'\n\x85\u2028\u2029' \
108 - or (ch == u'\r' and self.buffer[self.pointer] != u'\n'):
109 - self.line += 1
110 - self.column = 0
111 - elif ch != u'\uFEFF':
112 - self.column += 1
113 - length -= 1
114 -
115 - def get_mark(self):
116 - if self.stream is None:
117 - return Mark(self.name, self.index, self.line, self.column,
118 - self.buffer, self.pointer)
119 - else:
120 - return Mark(self.name, self.index, self.line, self.column,
121 - None, None)
122 -
123 - def determine_encoding(self):
124 - while not self.eof and len(self.raw_buffer) < 2:
125 - self.update_raw()
126 - if not isinstance(self.raw_buffer, unicode):
127 - if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
128 - self.raw_decode = codecs.utf_16_le_decode
129 - self.encoding = 'utf-16-le'
130 - elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE):
131 - self.raw_decode = codecs.utf_16_be_decode
132 - self.encoding = 'utf-16-be'
133 - else:
134 - self.raw_decode = codecs.utf_8_decode
135 - self.encoding = 'utf-8'
136 - self.update(1)
137 -
138 - NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
139 - def check_printable(self, data):
140 - match = self.NON_PRINTABLE.search(data)
141 - if match:
142 - character = match.group()
143 - position = self.index+(len(self.buffer)-self.pointer)+match.start()
144 - raise ReaderError(self.name, position, ord(character),
145 - 'unicode', "special characters are not allowed")
146 -
147 - def update(self, length):
148 - if self.raw_buffer is None:
149 - return
150 - self.buffer = self.buffer[self.pointer:]
151 - self.pointer = 0
152 - while len(self.buffer) < length:
153 - if not self.eof:
154 - self.update_raw()
155 - if self.raw_decode is not None:
156 - try:
157 - data, converted = self.raw_decode(self.raw_buffer,
158 - 'strict', self.eof)
159 - except UnicodeDecodeError, exc:
160 - character = exc.object[exc.start]
161 - if self.stream is not None:
162 - position = self.stream_pointer-len(self.raw_buffer)+exc.start
163 - else:
164 - position = exc.start
165 - raise ReaderError(self.name, position, character,
166 - exc.encoding, exc.reason)
167 - else:
168 - data = self.raw_buffer
169 - converted = len(data)
170 - self.check_printable(data)
171 - self.buffer += data
172 - self.raw_buffer = self.raw_buffer[converted:]
173 - if self.eof:
174 - self.buffer += u'\0'
175 - self.raw_buffer = None
176 - break
177 -
178 - def update_raw(self, size=1024):
179 - data = self.stream.read(size)
180 - if data:
181 - self.raw_buffer += data
182 - self.stream_pointer += len(data)
183 - else:
184 - self.eof = True
185 -
186 -#try:
187 -# import psyco
188 -# psyco.bind(Reader)
189 -#except ImportError:
190 -# pass
191 -
src/collectors/python.d.plugin/python_modules/pyyaml2/representer.py deleted
-485
@@ -1,485 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
4 - 'RepresenterError']
5 -
6 -from error import *
7 -from nodes import *
8 -
9 -import datetime
10 -
11 -import sys, copy_reg, types
12 -
13 -class RepresenterError(YAMLError):
14 - pass
15 -
16 -class BaseRepresenter(object):
17 -
18 - yaml_representers = {}
19 - yaml_multi_representers = {}
20 -
21 - def __init__(self, default_style=None, default_flow_style=None):
22 - self.default_style = default_style
23 - self.default_flow_style = default_flow_style
24 - self.represented_objects = {}
25 - self.object_keeper = []
26 - self.alias_key = None
27 -
28 - def represent(self, data):
29 - node = self.represent_data(data)
30 - self.serialize(node)
31 - self.represented_objects = {}
32 - self.object_keeper = []
33 - self.alias_key = None
34 -
35 - def get_classobj_bases(self, cls):
36 - bases = [cls]
37 - for base in cls.__bases__:
38 - bases.extend(self.get_classobj_bases(base))
39 - return bases
40 -
41 - def represent_data(self, data):
42 - if self.ignore_aliases(data):
43 - self.alias_key = None
44 - else:
45 - self.alias_key = id(data)
46 - if self.alias_key is not None:
47 - if self.alias_key in self.represented_objects:
48 - node = self.represented_objects[self.alias_key]
49 - #if node is None:
50 - # raise RepresenterError("recursive objects are not allowed: %r" % data)
51 - return node
52 - #self.represented_objects[alias_key] = None
53 - self.object_keeper.append(data)
54 - data_types = type(data).__mro__
55 - if type(data) is types.InstanceType:
56 - data_types = self.get_classobj_bases(data.__class__)+list(data_types)
57 - if data_types[0] in self.yaml_representers:
58 - node = self.yaml_representers[data_types[0]](self, data)
59 - else:
60 - for data_type in data_types:
61 - if data_type in self.yaml_multi_representers:
62 - node = self.yaml_multi_representers[data_type](self, data)
63 - break
64 - else:
65 - if None in self.yaml_multi_representers:
66 - node = self.yaml_multi_representers[None](self, data)
67 - elif None in self.yaml_representers:
68 - node = self.yaml_representers[None](self, data)
69 - else:
70 - node = ScalarNode(None, unicode(data))
71 - #if alias_key is not None:
72 - # self.represented_objects[alias_key] = node
73 - return node
74 -
75 - def add_representer(cls, data_type, representer):
76 - if not 'yaml_representers' in cls.__dict__:
77 - cls.yaml_representers = cls.yaml_representers.copy()
78 - cls.yaml_representers[data_type] = representer
79 - add_representer = classmethod(add_representer)
80 -
81 - def add_multi_representer(cls, data_type, representer):
82 - if not 'yaml_multi_representers' in cls.__dict__:
83 - cls.yaml_multi_representers = cls.yaml_multi_representers.copy()
84 - cls.yaml_multi_representers[data_type] = representer
85 - add_multi_representer = classmethod(add_multi_representer)
86 -
87 - def represent_scalar(self, tag, value, style=None):
88 - if style is None:
89 - style = self.default_style
90 - node = ScalarNode(tag, value, style=style)
91 - if self.alias_key is not None:
92 - self.represented_objects[self.alias_key] = node
93 - return node
94 -
95 - def represent_sequence(self, tag, sequence, flow_style=None):
96 - value = []
97 - node = SequenceNode(tag, value, flow_style=flow_style)
98 - if self.alias_key is not None:
99 - self.represented_objects[self.alias_key] = node
100 - best_style = True
101 - for item in sequence:
102 - node_item = self.represent_data(item)
103 - if not (isinstance(node_item, ScalarNode) and not node_item.style):
104 - best_style = False
105 - value.append(node_item)
106 - if flow_style is None:
107 - if self.default_flow_style is not None:
108 - node.flow_style = self.default_flow_style
109 - else:
110 - node.flow_style = best_style
111 - return node
112 -
113 - def represent_mapping(self, tag, mapping, flow_style=None):
114 - value = []
115 - node = MappingNode(tag, value, flow_style=flow_style)
116 - if self.alias_key is not None:
117 - self.represented_objects[self.alias_key] = node
118 - best_style = True
119 - if hasattr(mapping, 'items'):
120 - mapping = mapping.items()
121 - mapping.sort()
122 - for item_key, item_value in mapping:
123 - node_key = self.represent_data(item_key)
124 - node_value = self.represent_data(item_value)
125 - if not (isinstance(node_key, ScalarNode) and not node_key.style):
126 - best_style = False
127 - if not (isinstance(node_value, ScalarNode) and not node_value.style):
128 - best_style = False
129 - value.append((node_key, node_value))
130 - if flow_style is None:
131 - if self.default_flow_style is not None:
132 - node.flow_style = self.default_flow_style
133 - else:
134 - node.flow_style = best_style
135 - return node
136 -
137 - def ignore_aliases(self, data):
138 - return False
139 -
140 -class SafeRepresenter(BaseRepresenter):
141 -
142 - def ignore_aliases(self, data):
143 - if data in [None, ()]:
144 - return True
145 - if isinstance(data, (str, unicode, bool, int, float)):
146 - return True
147 -
148 - def represent_none(self, data):
149 - return self.represent_scalar(u'tag:yaml.org,2002:null',
150 - u'null')
151 -
152 - def represent_str(self, data):
153 - tag = None
154 - style = None
155 - try:
156 - data = unicode(data, 'ascii')
157 - tag = u'tag:yaml.org,2002:str'
158 - except UnicodeDecodeError:
159 - try:
160 - data = unicode(data, 'utf-8')
161 - tag = u'tag:yaml.org,2002:str'
162 - except UnicodeDecodeError:
163 - data = data.encode('base64')
164 - tag = u'tag:yaml.org,2002:binary'
165 - style = '|'
166 - return self.represent_scalar(tag, data, style=style)
167 -
168 - def represent_unicode(self, data):
169 - return self.represent_scalar(u'tag:yaml.org,2002:str', data)
170 -
171 - def represent_bool(self, data):
172 - if data:
173 - value = u'true'
174 - else:
175 - value = u'false'
176 - return self.represent_scalar(u'tag:yaml.org,2002:bool', value)
177 -
178 - def represent_int(self, data):
179 - return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
180 -
181 - def represent_long(self, data):
182 - return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
183 -
184 - inf_value = 1e300
185 - while repr(inf_value) != repr(inf_value*inf_value):
186 - inf_value *= inf_value
187 -
188 - def represent_float(self, data):
189 - if data != data or (data == 0.0 and data == 1.0):
190 - value = u'.nan'
191 - elif data == self.inf_value:
192 - value = u'.inf'
193 - elif data == -self.inf_value:
194 - value = u'-.inf'
195 - else:
196 - value = unicode(repr(data)).lower()
197 - # Note that in some cases `repr(data)` represents a float number
198 - # without the decimal parts. For instance:
199 - # >>> repr(1e17)
200 - # '1e17'
201 - # Unfortunately, this is not a valid float representation according
202 - # to the definition of the `!!float` tag. We fix this by adding
203 - # '.0' before the 'e' symbol.
204 - if u'.' not in value and u'e' in value:
205 - value = value.replace(u'e', u'.0e', 1)
206 - return self.represent_scalar(u'tag:yaml.org,2002:float', value)
207 -
208 - def represent_list(self, data):
209 - #pairs = (len(data) > 0 and isinstance(data, list))
210 - #if pairs:
211 - # for item in data:
212 - # if not isinstance(item, tuple) or len(item) != 2:
213 - # pairs = False
214 - # break
215 - #if not pairs:
216 - return self.represent_sequence(u'tag:yaml.org,2002:seq', data)
217 - #value = []
218 - #for item_key, item_value in data:
219 - # value.append(self.represent_mapping(u'tag:yaml.org,2002:map',
220 - # [(item_key, item_value)]))
221 - #return SequenceNode(u'tag:yaml.org,2002:pairs', value)
222 -
223 - def represent_dict(self, data):
224 - return self.represent_mapping(u'tag:yaml.org,2002:map', data)
225 -
226 - def represent_set(self, data):
227 - value = {}
228 - for key in data:
229 - value[key] = None
230 - return self.represent_mapping(u'tag:yaml.org,2002:set', value)
231 -
232 - def represent_date(self, data):
233 - value = unicode(data.isoformat())
234 - return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
235 -
236 - def represent_datetime(self, data):
237 - value = unicode(data.isoformat(' '))
238 - return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
239 -
240 - def represent_yaml_object(self, tag, data, cls, flow_style=None):
241 - if hasattr(data, '__getstate__'):
242 - state = data.__getstate__()
243 - else:
244 - state = data.__dict__.copy()
245 - return self.represent_mapping(tag, state, flow_style=flow_style)
246 -
247 - def represent_undefined(self, data):
248 - raise RepresenterError("cannot represent an object: %s" % data)
249 -
250 -SafeRepresenter.add_representer(type(None),
251 - SafeRepresenter.represent_none)
252 -
253 -SafeRepresenter.add_representer(str,
254 - SafeRepresenter.represent_str)
255 -
256 -SafeRepresenter.add_representer(unicode,
257 - SafeRepresenter.represent_unicode)
258 -
259 -SafeRepresenter.add_representer(bool,
260 - SafeRepresenter.represent_bool)
261 -
262 -SafeRepresenter.add_representer(int,
263 - SafeRepresenter.represent_int)
264 -
265 -SafeRepresenter.add_representer(long,
266 - SafeRepresenter.represent_long)
267 -
268 -SafeRepresenter.add_representer(float,
269 - SafeRepresenter.represent_float)
270 -
271 -SafeRepresenter.add_representer(list,
272 - SafeRepresenter.represent_list)
273 -
274 -SafeRepresenter.add_representer(tuple,
275 - SafeRepresenter.represent_list)
276 -
277 -SafeRepresenter.add_representer(dict,
278 - SafeRepresenter.represent_dict)
279 -
280 -SafeRepresenter.add_representer(set,
281 - SafeRepresenter.represent_set)
282 -
283 -SafeRepresenter.add_representer(datetime.date,
284 - SafeRepresenter.represent_date)
285 -
286 -SafeRepresenter.add_representer(datetime.datetime,
287 - SafeRepresenter.represent_datetime)
288 -
289 -SafeRepresenter.add_representer(None,
290 - SafeRepresenter.represent_undefined)
291 -
292 -class Representer(SafeRepresenter):
293 -
294 - def represent_str(self, data):
295 - tag = None
296 - style = None
297 - try:
298 - data = unicode(data, 'ascii')
299 - tag = u'tag:yaml.org,2002:str'
300 - except UnicodeDecodeError:
301 - try:
302 - data = unicode(data, 'utf-8')
303 - tag = u'tag:yaml.org,2002:python/str'
304 - except UnicodeDecodeError:
305 - data = data.encode('base64')
306 - tag = u'tag:yaml.org,2002:binary'
307 - style = '|'
308 - return self.represent_scalar(tag, data, style=style)
309 -
310 - def represent_unicode(self, data):
311 - tag = None
312 - try:
313 - data.encode('ascii')
314 - tag = u'tag:yaml.org,2002:python/unicode'
315 - except UnicodeEncodeError:
316 - tag = u'tag:yaml.org,2002:str'
317 - return self.represent_scalar(tag, data)
318 -
319 - def represent_long(self, data):
320 - tag = u'tag:yaml.org,2002:int'
321 - if int(data) is not data:
322 - tag = u'tag:yaml.org,2002:python/long'
323 - return self.represent_scalar(tag, unicode(data))
324 -
325 - def represent_complex(self, data):
326 - if data.imag == 0.0:
327 - data = u'%r' % data.real
328 - elif data.real == 0.0:
329 - data = u'%rj' % data.imag
330 - elif data.imag > 0:
331 - data = u'%r+%rj' % (data.real, data.imag)
332 - else:
333 - data = u'%r%rj' % (data.real, data.imag)
334 - return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data)
335 -
336 - def represent_tuple(self, data):
337 - return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data)
338 -
339 - def represent_name(self, data):
340 - name = u'%s.%s' % (data.__module__, data.__name__)
341 - return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'')
342 -
343 - def represent_module(self, data):
344 - return self.represent_scalar(
345 - u'tag:yaml.org,2002:python/module:'+data.__name__, u'')
346 -
347 - def represent_instance(self, data):
348 - # For instances of classic classes, we use __getinitargs__ and
349 - # __getstate__ to serialize the data.
350 -
351 - # If data.__getinitargs__ exists, the object must be reconstructed by
352 - # calling cls(**args), where args is a tuple returned by
353 - # __getinitargs__. Otherwise, the cls.__init__ method should never be
354 - # called and the class instance is created by instantiating a trivial
355 - # class and assigning to the instance's __class__ variable.
356 -
357 - # If data.__getstate__ exists, it returns the state of the object.
358 - # Otherwise, the state of the object is data.__dict__.
359 -
360 - # We produce either a !!python/object or !!python/object/new node.
361 - # If data.__getinitargs__ does not exist and state is a dictionary, we
362 - # produce a !!python/object node . Otherwise we produce a
363 - # !!python/object/new node.
364 -
365 - cls = data.__class__
366 - class_name = u'%s.%s' % (cls.__module__, cls.__name__)
367 - args = None
368 - state = None
369 - if hasattr(data, '__getinitargs__'):
370 - args = list(data.__getinitargs__())
371 - if hasattr(data, '__getstate__'):
372 - state = data.__getstate__()
373 - else:
374 - state = data.__dict__
375 - if args is None and isinstance(state, dict):
376 - return self.represent_mapping(
377 - u'tag:yaml.org,2002:python/object:'+class_name, state)
378 - if isinstance(state, dict) and not state:
379 - return self.represent_sequence(
380 - u'tag:yaml.org,2002:python/object/new:'+class_name, args)
381 - value = {}
382 - if args:
383 - value['args'] = args
384 - value['state'] = state
385 - return self.represent_mapping(
386 - u'tag:yaml.org,2002:python/object/new:'+class_name, value)
387 -
388 - def represent_object(self, data):
389 - # We use __reduce__ API to save the data. data.__reduce__ returns
390 - # a tuple of length 2-5:
391 - # (function, args, state, listitems, dictitems)
392 -
393 - # For reconstructing, we calls function(*args), then set its state,
394 - # listitems, and dictitems if they are not None.
395 -
396 - # A special case is when function.__name__ == '__newobj__'. In this
397 - # case we create the object with args[0].__new__(*args).
398 -
399 - # Another special case is when __reduce__ returns a string - we don't
400 - # support it.
401 -
402 - # We produce a !!python/object, !!python/object/new or
403 - # !!python/object/apply node.
404 -
405 - cls = type(data)
406 - if cls in copy_reg.dispatch_table:
407 - reduce = copy_reg.dispatch_table[cls](data)
408 - elif hasattr(data, '__reduce_ex__'):
409 - reduce = data.__reduce_ex__(2)
410 - elif hasattr(data, '__reduce__'):
411 - reduce = data.__reduce__()
412 - else:
413 - raise RepresenterError("cannot represent object: %r" % data)
414 - reduce = (list(reduce)+[None]*5)[:5]
415 - function, args, state, listitems, dictitems = reduce
416 - args = list(args)
417 - if state is None:
418 - state = {}
419 - if listitems is not None:
420 - listitems = list(listitems)
421 - if dictitems is not None:
422 - dictitems = dict(dictitems)
423 - if function.__name__ == '__newobj__':
424 - function = args[0]
425 - args = args[1:]
426 - tag = u'tag:yaml.org,2002:python/object/new:'
427 - newobj = True
428 - else:
429 - tag = u'tag:yaml.org,2002:python/object/apply:'
430 - newobj = False
431 - function_name = u'%s.%s' % (function.__module__, function.__name__)
432 - if not args and not listitems and not dictitems \
433 - and isinstance(state, dict) and newobj:
434 - return self.represent_mapping(
435 - u'tag:yaml.org,2002:python/object:'+function_name, state)
436 - if not listitems and not dictitems \
437 - and isinstance(state, dict) and not state:
438 - return self.represent_sequence(tag+function_name, args)
439 - value = {}
440 - if args:
441 - value['args'] = args
442 - if state or not isinstance(state, dict):
443 - value['state'] = state
444 - if listitems:
445 - value['listitems'] = listitems
446 - if dictitems:
447 - value['dictitems'] = dictitems
448 - return self.represent_mapping(tag+function_name, value)
449 -
450 -Representer.add_representer(str,
451 - Representer.represent_str)
452 -
453 -Representer.add_representer(unicode,
454 - Representer.represent_unicode)
455 -
456 -Representer.add_representer(long,
457 - Representer.represent_long)
458 -
459 -Representer.add_representer(complex,
460 - Representer.represent_complex)
461 -
462 -Representer.add_representer(tuple,
463 - Representer.represent_tuple)
464 -
465 -Representer.add_representer(type,
466 - Representer.represent_name)
467 -
468 -Representer.add_representer(types.ClassType,
469 - Representer.represent_name)
470 -
471 -Representer.add_representer(types.FunctionType,
472 - Representer.represent_name)
473 -
474 -Representer.add_representer(types.BuiltinFunctionType,
475 - Representer.represent_name)
476 -
477 -Representer.add_representer(types.ModuleType,
478 - Representer.represent_module)
479 -
480 -Representer.add_multi_representer(types.InstanceType,
481 - Representer.represent_instance)
482 -
483 -Representer.add_multi_representer(object,
484 - Representer.represent_object)
485 -
src/collectors/python.d.plugin/python_modules/pyyaml2/resolver.py deleted
-225
@@ -1,225 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['BaseResolver', 'Resolver']
4 -
5 -from error import *
6 -from nodes import *
7 -
8 -import re
9 -
10 -class ResolverError(YAMLError):
11 - pass
12 -
13 -class BaseResolver(object):
14 -
15 - DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
16 - DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq'
17 - DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
18 -
19 - yaml_implicit_resolvers = {}
20 - yaml_path_resolvers = {}
21 -
22 - def __init__(self):
23 - self.resolver_exact_paths = []
24 - self.resolver_prefix_paths = []
25 -
26 - def add_implicit_resolver(cls, tag, regexp, first):
27 - if not 'yaml_implicit_resolvers' in cls.__dict__:
28 - cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()
29 - if first is None:
30 - first = [None]
31 - for ch in first:
32 - cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
33 - add_implicit_resolver = classmethod(add_implicit_resolver)
34 -
35 - def add_path_resolver(cls, tag, path, kind=None):
36 - # Note: `add_path_resolver` is experimental. The API could be changed.
37 - # `new_path` is a pattern that is matched against the path from the
38 - # root to the node that is being considered. `node_path` elements are
39 - # tuples `(node_check, index_check)`. `node_check` is a node class:
40 - # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None`
41 - # matches any kind of a node. `index_check` could be `None`, a boolean
42 - # value, a string value, or a number. `None` and `False` match against
43 - # any _value_ of sequence and mapping nodes. `True` matches against
44 - # any _key_ of a mapping node. A string `index_check` matches against
45 - # a mapping value that corresponds to a scalar key which content is
46 - # equal to the `index_check` value. An integer `index_check` matches
47 - # against a sequence value with the index equal to `index_check`.
48 - if not 'yaml_path_resolvers' in cls.__dict__:
49 - cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy()
50 - new_path = []
51 - for element in path:
52 - if isinstance(element, (list, tuple)):
53 - if len(element) == 2:
54 - node_check, index_check = element
55 - elif len(element) == 1:
56 - node_check = element[0]
57 - index_check = True
58 - else:
59 - raise ResolverError("Invalid path element: %s" % element)
60 - else:
61 - node_check = None
62 - index_check = element
63 - if node_check is str:
64 - node_check = ScalarNode
65 - elif node_check is list:
66 - node_check = SequenceNode
67 - elif node_check is dict:
68 - node_check = MappingNode
69 - elif node_check not in [ScalarNode, SequenceNode, MappingNode] \
70 - and not isinstance(node_check, basestring) \
71 - and node_check is not None:
72 - raise ResolverError("Invalid node checker: %s" % node_check)
73 - if not isinstance(index_check, (basestring, int)) \
74 - and index_check is not None:
75 - raise ResolverError("Invalid index checker: %s" % index_check)
76 - new_path.append((node_check, index_check))
77 - if kind is str:
78 - kind = ScalarNode
79 - elif kind is list:
80 - kind = SequenceNode
81 - elif kind is dict:
82 - kind = MappingNode
83 - elif kind not in [ScalarNode, SequenceNode, MappingNode] \
84 - and kind is not None:
85 - raise ResolverError("Invalid node kind: %s" % kind)
86 - cls.yaml_path_resolvers[tuple(new_path), kind] = tag
87 - add_path_resolver = classmethod(add_path_resolver)
88 -
89 - def descend_resolver(self, current_node, current_index):
90 - if not self.yaml_path_resolvers:
91 - return
92 - exact_paths = {}
93 - prefix_paths = []
94 - if current_node:
95 - depth = len(self.resolver_prefix_paths)
96 - for path, kind in self.resolver_prefix_paths[-1]:
97 - if self.check_resolver_prefix(depth, path, kind,
98 - current_node, current_index):
99 - if len(path) > depth:
100 - prefix_paths.append((path, kind))
101 - else:
102 - exact_paths[kind] = self.yaml_path_resolvers[path, kind]
103 - else:
104 - for path, kind in self.yaml_path_resolvers:
105 - if not path:
106 - exact_paths[kind] = self.yaml_path_resolvers[path, kind]
107 - else:
108 - prefix_paths.append((path, kind))
109 - self.resolver_exact_paths.append(exact_paths)
110 - self.resolver_prefix_paths.append(prefix_paths)
111 -
112 - def ascend_resolver(self):
113 - if not self.yaml_path_resolvers:
114 - return
115 - self.resolver_exact_paths.pop()
116 - self.resolver_prefix_paths.pop()
117 -
118 - def check_resolver_prefix(self, depth, path, kind,
119 - current_node, current_index):
120 - node_check, index_check = path[depth-1]
121 - if isinstance(node_check, basestring):
122 - if current_node.tag != node_check:
123 - return
124 - elif node_check is not None:
125 - if not isinstance(current_node, node_check):
126 - return
127 - if index_check is True and current_index is not None:
128 - return
129 - if (index_check is False or index_check is None) \
130 - and current_index is None:
131 - return
132 - if isinstance(index_check, basestring):
133 - if not (isinstance(current_index, ScalarNode)
134 - and index_check == current_index.value):
135 - return
136 - elif isinstance(index_check, int) and not isinstance(index_check, bool):
137 - if index_check != current_index:
138 - return
139 - return True
140 -
141 - def resolve(self, kind, value, implicit):
142 - if kind is ScalarNode and implicit[0]:
143 - if value == u'':
144 - resolvers = self.yaml_implicit_resolvers.get(u'', [])
145 - else:
146 - resolvers = self.yaml_implicit_resolvers.get(value[0], [])
147 - resolvers += self.yaml_implicit_resolvers.get(None, [])
148 - for tag, regexp in resolvers:
149 - if regexp.match(value):
150 - return tag
151 - implicit = implicit[1]
152 - if self.yaml_path_resolvers:
153 - exact_paths = self.resolver_exact_paths[-1]
154 - if kind in exact_paths:
155 - return exact_paths[kind]
156 - if None in exact_paths:
157 - return exact_paths[None]
158 - if kind is ScalarNode:
159 - return self.DEFAULT_SCALAR_TAG
160 - elif kind is SequenceNode:
161 - return self.DEFAULT_SEQUENCE_TAG
162 - elif kind is MappingNode:
163 - return self.DEFAULT_MAPPING_TAG
164 -
165 -class Resolver(BaseResolver):
166 - pass
167 -
168 -Resolver.add_implicit_resolver(
169 - u'tag:yaml.org,2002:bool',
170 - re.compile(ur'''^(?:yes|Yes|YES|no|No|NO
171 - |true|True|TRUE|false|False|FALSE
172 - |on|On|ON|off|Off|OFF)$''', re.X),
173 - list(u'yYnNtTfFoO'))
174 -
175 -Resolver.add_implicit_resolver(
176 - u'tag:yaml.org,2002:float',
177 - re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
178 - |\.[0-9_]+(?:[eE][-+][0-9]+)?
179 - |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
180 - |[-+]?\.(?:inf|Inf|INF)
181 - |\.(?:nan|NaN|NAN))$''', re.X),
182 - list(u'-+0123456789.'))
183 -
184 -Resolver.add_implicit_resolver(
185 - u'tag:yaml.org,2002:int',
186 - re.compile(ur'''^(?:[-+]?0b[0-1_]+
187 - |[-+]?0[0-7_]+
188 - |[-+]?(?:0|[1-9][0-9_]*)
189 - |[-+]?0x[0-9a-fA-F_]+
190 - |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),
191 - list(u'-+0123456789'))
192 -
193 -Resolver.add_implicit_resolver(
194 - u'tag:yaml.org,2002:merge',
195 - re.compile(ur'^(?:<<)$'),
196 - [u'<'])
197 -
198 -Resolver.add_implicit_resolver(
199 - u'tag:yaml.org,2002:null',
200 - re.compile(ur'''^(?: ~
201 - |null|Null|NULL
202 - | )$''', re.X),
203 - [u'~', u'n', u'N', u''])
204 -
205 -Resolver.add_implicit_resolver(
206 - u'tag:yaml.org,2002:timestamp',
207 - re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
208 - |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
209 - (?:[Tt]|[ \t]+)[0-9][0-9]?
210 - :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)?
211 - (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
212 - list(u'0123456789'))
213 -
214 -Resolver.add_implicit_resolver(
215 - u'tag:yaml.org,2002:value',
216 - re.compile(ur'^(?:=)$'),
217 - [u'='])
218 -
219 -# The following resolver is only for documentation purposes. It cannot work
220 -# because plain scalars cannot start with '!', '&', or '*'.
221 -Resolver.add_implicit_resolver(
222 - u'tag:yaml.org,2002:yaml',
223 - re.compile(ur'^(?:!|&|\*)$'),
224 - list(u'!&*'))
225 -
src/collectors/python.d.plugin/python_modules/pyyaml2/scanner.py deleted
-1458
@@ -1,1458 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -# Scanner produces tokens of the following types:
4 -# STREAM-START
5 -# STREAM-END
6 -# DIRECTIVE(name, value)
7 -# DOCUMENT-START
8 -# DOCUMENT-END
9 -# BLOCK-SEQUENCE-START
10 -# BLOCK-MAPPING-START
11 -# BLOCK-END
12 -# FLOW-SEQUENCE-START
13 -# FLOW-MAPPING-START
14 -# FLOW-SEQUENCE-END
15 -# FLOW-MAPPING-END
16 -# BLOCK-ENTRY
17 -# FLOW-ENTRY
18 -# KEY
19 -# VALUE
20 -# ALIAS(value)
21 -# ANCHOR(value)
22 -# TAG(value)
23 -# SCALAR(value, plain, style)
24 -#
25 -# Read comments in the Scanner code for more details.
26 -#
27 -
28 -__all__ = ['Scanner', 'ScannerError']
29 -
30 -from error import MarkedYAMLError
31 -from tokens import *
32 -
33 -class ScannerError(MarkedYAMLError):
34 - pass
35 -
36 -class SimpleKey(object):
37 - # See below simple keys treatment.
38 -
39 - def __init__(self, token_number, required, index, line, column, mark):
40 - self.token_number = token_number
41 - self.required = required
42 - self.index = index
43 - self.line = line
44 - self.column = column
45 - self.mark = mark
46 -
47 -class Scanner(object):
48 -
49 - def __init__(self):
50 - """Initialize the scanner."""
51 - # It is assumed that Scanner and Reader will have a common descendant.
52 - # Reader do the dirty work of checking for BOM and converting the
53 - # input data to Unicode. It also adds NUL to the end.
54 - #
55 - # Reader supports the following methods
56 - # self.peek(i=0) # peek the next i-th character
57 - # self.prefix(l=1) # peek the next l characters
58 - # self.forward(l=1) # read the next l characters and move the pointer.
59 -
60 - # Had we reached the end of the stream?
61 - self.done = False
62 -
63 - # The number of unclosed '{' and '['. `flow_level == 0` means block
64 - # context.
65 - self.flow_level = 0
66 -
67 - # List of processed tokens that are not yet emitted.
68 - self.tokens = []
69 -
70 - # Add the STREAM-START token.
71 - self.fetch_stream_start()
72 -
73 - # Number of tokens that were emitted through the `get_token` method.
74 - self.tokens_taken = 0
75 -
76 - # The current indentation level.
77 - self.indent = -1
78 -
79 - # Past indentation levels.
80 - self.indents = []
81 -
82 - # Variables related to simple keys treatment.
83 -
84 - # A simple key is a key that is not denoted by the '?' indicator.
85 - # Example of simple keys:
86 - # ---
87 - # block simple key: value
88 - # ? not a simple key:
89 - # : { flow simple key: value }
90 - # We emit the KEY token before all keys, so when we find a potential
91 - # simple key, we try to locate the corresponding ':' indicator.
92 - # Simple keys should be limited to a single line and 1024 characters.
93 -
94 - # Can a simple key start at the current position? A simple key may
95 - # start:
96 - # - at the beginning of the line, not counting indentation spaces
97 - # (in block context),
98 - # - after '{', '[', ',' (in the flow context),
99 - # - after '?', ':', '-' (in the block context).
100 - # In the block context, this flag also signifies if a block collection
101 - # may start at the current position.
102 - self.allow_simple_key = True
103 -
104 - # Keep track of possible simple keys. This is a dictionary. The key
105 - # is `flow_level`; there can be no more that one possible simple key
106 - # for each level. The value is a SimpleKey record:
107 - # (token_number, required, index, line, column, mark)
108 - # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow),
109 - # '[', or '{' tokens.
110 - self.possible_simple_keys = {}
111 -
112 - # Public methods.
113 -
114 - def check_token(self, *choices):
115 - # Check if the next token is one of the given types.
116 - while self.need_more_tokens():
117 - self.fetch_more_tokens()
118 - if self.tokens:
119 - if not choices:
120 - return True
121 - for choice in choices:
122 - if isinstance(self.tokens[0], choice):
123 - return True
124 - return False
125 -
126 - def peek_token(self):
127 - # Return the next token, but do not delete if from the queue.
128 - while self.need_more_tokens():
129 - self.fetch_more_tokens()
130 - if self.tokens:
131 - return self.tokens[0]
132 -
133 - def get_token(self):
134 - # Return the next token.
135 - while self.need_more_tokens():
136 - self.fetch_more_tokens()
137 - if self.tokens:
138 - self.tokens_taken += 1
139 - return self.tokens.pop(0)
140 -
141 - # Private methods.
142 -
143 - def need_more_tokens(self):
144 - if self.done:
145 - return False
146 - if not self.tokens:
147 - return True
148 - # The current token may be a potential simple key, so we
149 - # need to look further.
150 - self.stale_possible_simple_keys()
151 - if self.next_possible_simple_key() == self.tokens_taken:
152 - return True
153 -
154 - def fetch_more_tokens(self):
155 -
156 - # Eat whitespaces and comments until we reach the next token.
157 - self.scan_to_next_token()
158 -
159 - # Remove obsolete possible simple keys.
160 - self.stale_possible_simple_keys()
161 -
162 - # Compare the current indentation and column. It may add some tokens
163 - # and decrease the current indentation level.
164 - self.unwind_indent(self.column)
165 -
166 - # Peek the next character.
167 - ch = self.peek()
168 -
169 - # Is it the end of stream?
170 - if ch == u'\0':
171 - return self.fetch_stream_end()
172 -
173 - # Is it a directive?
174 - if ch == u'%' and self.check_directive():
175 - return self.fetch_directive()
176 -
177 - # Is it the document start?
178 - if ch == u'-' and self.check_document_start():
179 - return self.fetch_document_start()
180 -
181 - # Is it the document end?
182 - if ch == u'.' and self.check_document_end():
183 - return self.fetch_document_end()
184 -
185 - # TODO: support for BOM within a stream.
186 - #if ch == u'\uFEFF':
187 - # return self.fetch_bom() <-- issue BOMToken
188 -
189 - # Note: the order of the following checks is NOT significant.
190 -
191 - # Is it the flow sequence start indicator?
192 - if ch == u'[':
193 - return self.fetch_flow_sequence_start()
194 -
195 - # Is it the flow mapping start indicator?
196 - if ch == u'{':
197 - return self.fetch_flow_mapping_start()
198 -
199 - # Is it the flow sequence end indicator?
200 - if ch == u']':
201 - return self.fetch_flow_sequence_end()
202 -
203 - # Is it the flow mapping end indicator?
204 - if ch == u'}':
205 - return self.fetch_flow_mapping_end()
206 -
207 - # Is it the flow entry indicator?
208 - if ch == u',':
209 - return self.fetch_flow_entry()
210 -
211 - # Is it the block entry indicator?
212 - if ch == u'-' and self.check_block_entry():
213 - return self.fetch_block_entry()
214 -
215 - # Is it the key indicator?
216 - if ch == u'?' and self.check_key():
217 - return self.fetch_key()
218 -
219 - # Is it the value indicator?
220 - if ch == u':' and self.check_value():
221 - return self.fetch_value()
222 -
223 - # Is it an alias?
224 - if ch == u'*':
225 - return self.fetch_alias()
226 -
227 - # Is it an anchor?
228 - if ch == u'&':
229 - return self.fetch_anchor()
230 -
231 - # Is it a tag?
232 - if ch == u'!':
233 - return self.fetch_tag()
234 -
235 - # Is it a literal scalar?
236 - if ch == u'|' and not self.flow_level:
237 - return self.fetch_literal()
238 -
239 - # Is it a folded scalar?
240 - if ch == u'>' and not self.flow_level:
241 - return self.fetch_folded()
242 -
243 - # Is it a single quoted scalar?
244 - if ch == u'\'':
245 - return self.fetch_single()
246 -
247 - # Is it a double quoted scalar?
248 - if ch == u'\"':
249 - return self.fetch_double()
250 -
251 - # It must be a plain scalar then.
252 - if self.check_plain():
253 - return self.fetch_plain()
254 -
255 - # No? It's an error. Let's produce a nice error message.
256 - raise ScannerError("while scanning for the next token", None,
257 - "found character %r that cannot start any token"
258 - % ch.encode('utf-8'), self.get_mark())
259 -
260 - # Simple keys treatment.
261 -
262 - def next_possible_simple_key(self):
263 - # Return the number of the nearest possible simple key. Actually we
264 - # don't need to loop through the whole dictionary. We may replace it
265 - # with the following code:
266 - # if not self.possible_simple_keys:
267 - # return None
268 - # return self.possible_simple_keys[
269 - # min(self.possible_simple_keys.keys())].token_number
270 - min_token_number = None
271 - for level in self.possible_simple_keys:
272 - key = self.possible_simple_keys[level]
273 - if min_token_number is None or key.token_number < min_token_number:
274 - min_token_number = key.token_number
275 - return min_token_number
276 -
277 - def stale_possible_simple_keys(self):
278 - # Remove entries that are no longer possible simple keys. According to
279 - # the YAML specification, simple keys
280 - # - should be limited to a single line,
281 - # - should be no longer than 1024 characters.
282 - # Disabling this procedure will allow simple keys of any length and
283 - # height (may cause problems if indentation is broken though).
284 - for level in self.possible_simple_keys.keys():
285 - key = self.possible_simple_keys[level]
286 - if key.line != self.line \
287 - or self.index-key.index > 1024:
288 - if key.required:
289 - raise ScannerError("while scanning a simple key", key.mark,
290 - "could not found expected ':'", self.get_mark())
291 - del self.possible_simple_keys[level]
292 -
293 - def save_possible_simple_key(self):
294 - # The next token may start a simple key. We check if it's possible
295 - # and save its position. This function is called for
296 - # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
297 -
298 - # Check if a simple key is required at the current position.
299 - required = not self.flow_level and self.indent == self.column
300 -
301 - # A simple key is required only if it is the first token in the current
302 - # line. Therefore it is always allowed.
303 - assert self.allow_simple_key or not required
304 -
305 - # The next token might be a simple key. Let's save it's number and
306 - # position.
307 - if self.allow_simple_key:
308 - self.remove_possible_simple_key()
309 - token_number = self.tokens_taken+len(self.tokens)
310 - key = SimpleKey(token_number, required,
311 - self.index, self.line, self.column, self.get_mark())
312 - self.possible_simple_keys[self.flow_level] = key
313 -
314 - def remove_possible_simple_key(self):
315 - # Remove the saved possible key position at the current flow level.
316 - if self.flow_level in self.possible_simple_keys:
317 - key = self.possible_simple_keys[self.flow_level]
318 -
319 - if key.required:
320 - raise ScannerError("while scanning a simple key", key.mark,
321 - "could not found expected ':'", self.get_mark())
322 -
323 - del self.possible_simple_keys[self.flow_level]
324 -
325 - # Indentation functions.
326 -
327 - def unwind_indent(self, column):
328 -
329 - ## In flow context, tokens should respect indentation.
330 - ## Actually the condition should be `self.indent >= column` according to
331 - ## the spec. But this condition will prohibit intuitively correct
332 - ## constructions such as
333 - ## key : {
334 - ## }
335 - #if self.flow_level and self.indent > column:
336 - # raise ScannerError(None, None,
337 - # "invalid intendation or unclosed '[' or '{'",
338 - # self.get_mark())
339 -
340 - # In the flow context, indentation is ignored. We make the scanner less
341 - # restrictive then specification requires.
342 - if self.flow_level:
343 - return
344 -
345 - # In block context, we may need to issue the BLOCK-END tokens.
346 - while self.indent > column:
347 - mark = self.get_mark()
348 - self.indent = self.indents.pop()
349 - self.tokens.append(BlockEndToken(mark, mark))
350 -
351 - def add_indent(self, column):
352 - # Check if we need to increase indentation.
353 - if self.indent < column:
354 - self.indents.append(self.indent)
355 - self.indent = column
356 - return True
357 - return False
358 -
359 - # Fetchers.
360 -
361 - def fetch_stream_start(self):
362 - # We always add STREAM-START as the first token and STREAM-END as the
363 - # last token.
364 -
365 - # Read the token.
366 - mark = self.get_mark()
367 -
368 - # Add STREAM-START.
369 - self.tokens.append(StreamStartToken(mark, mark,
370 - encoding=self.encoding))
371 -
372 -
373 - def fetch_stream_end(self):
374 -
375 - # Set the current intendation to -1.
376 - self.unwind_indent(-1)
377 -
378 - # Reset simple keys.
379 - self.remove_possible_simple_key()
380 - self.allow_simple_key = False
381 - self.possible_simple_keys = {}
382 -
383 - # Read the token.
384 - mark = self.get_mark()
385 -
386 - # Add STREAM-END.
387 - self.tokens.append(StreamEndToken(mark, mark))
388 -
389 - # The steam is finished.
390 - self.done = True
391 -
392 - def fetch_directive(self):
393 -
394 - # Set the current intendation to -1.
395 - self.unwind_indent(-1)
396 -
397 - # Reset simple keys.
398 - self.remove_possible_simple_key()
399 - self.allow_simple_key = False
400 -
401 - # Scan and add DIRECTIVE.
402 - self.tokens.append(self.scan_directive())
403 -
404 - def fetch_document_start(self):
405 - self.fetch_document_indicator(DocumentStartToken)
406 -
407 - def fetch_document_end(self):
408 - self.fetch_document_indicator(DocumentEndToken)
409 -
410 - def fetch_document_indicator(self, TokenClass):
411 -
412 - # Set the current intendation to -1.
413 - self.unwind_indent(-1)
414 -
415 - # Reset simple keys. Note that there could not be a block collection
416 - # after '---'.
417 - self.remove_possible_simple_key()
418 - self.allow_simple_key = False
419 -
420 - # Add DOCUMENT-START or DOCUMENT-END.
421 - start_mark = self.get_mark()
422 - self.forward(3)
423 - end_mark = self.get_mark()
424 - self.tokens.append(TokenClass(start_mark, end_mark))
425 -
426 - def fetch_flow_sequence_start(self):
427 - self.fetch_flow_collection_start(FlowSequenceStartToken)
428 -
429 - def fetch_flow_mapping_start(self):
430 - self.fetch_flow_collection_start(FlowMappingStartToken)
431 -
432 - def fetch_flow_collection_start(self, TokenClass):
433 -
434 - # '[' and '{' may start a simple key.
435 - self.save_possible_simple_key()
436 -
437 - # Increase the flow level.
438 - self.flow_level += 1
439 -
440 - # Simple keys are allowed after '[' and '{'.
441 - self.allow_simple_key = True
442 -
443 - # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START.
444 - start_mark = self.get_mark()
445 - self.forward()
446 - end_mark = self.get_mark()
447 - self.tokens.append(TokenClass(start_mark, end_mark))
448 -
449 - def fetch_flow_sequence_end(self):
450 - self.fetch_flow_collection_end(FlowSequenceEndToken)
451 -
452 - def fetch_flow_mapping_end(self):
453 - self.fetch_flow_collection_end(FlowMappingEndToken)
454 -
455 - def fetch_flow_collection_end(self, TokenClass):
456 -
457 - # Reset possible simple key on the current level.
458 - self.remove_possible_simple_key()
459 -
460 - # Decrease the flow level.
461 - self.flow_level -= 1
462 -
463 - # No simple keys after ']' or '}'.
464 - self.allow_simple_key = False
465 -
466 - # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END.
467 - start_mark = self.get_mark()
468 - self.forward()
469 - end_mark = self.get_mark()
470 - self.tokens.append(TokenClass(start_mark, end_mark))
471 -
472 - def fetch_flow_entry(self):
473 -
474 - # Simple keys are allowed after ','.
475 - self.allow_simple_key = True
476 -
477 - # Reset possible simple key on the current level.
478 - self.remove_possible_simple_key()
479 -
480 - # Add FLOW-ENTRY.
481 - start_mark = self.get_mark()
482 - self.forward()
483 - end_mark = self.get_mark()
484 - self.tokens.append(FlowEntryToken(start_mark, end_mark))
485 -
486 - def fetch_block_entry(self):
487 -
488 - # Block context needs additional checks.
489 - if not self.flow_level:
490 -
491 - # Are we allowed to start a new entry?
492 - if not self.allow_simple_key:
493 - raise ScannerError(None, None,
494 - "sequence entries are not allowed here",
495 - self.get_mark())
496 -
497 - # We may need to add BLOCK-SEQUENCE-START.
498 - if self.add_indent(self.column):
499 - mark = self.get_mark()
500 - self.tokens.append(BlockSequenceStartToken(mark, mark))
501 -
502 - # It's an error for the block entry to occur in the flow context,
503 - # but we let the parser detect this.
504 - else:
505 - pass
506 -
507 - # Simple keys are allowed after '-'.
508 - self.allow_simple_key = True
509 -
510 - # Reset possible simple key on the current level.
511 - self.remove_possible_simple_key()
512 -
513 - # Add BLOCK-ENTRY.
514 - start_mark = self.get_mark()
515 - self.forward()
516 - end_mark = self.get_mark()
517 - self.tokens.append(BlockEntryToken(start_mark, end_mark))
518 -
519 - def fetch_key(self):
520 -
521 - # Block context needs additional checks.
522 - if not self.flow_level:
523 -
524 - # Are we allowed to start a key (not nessesary a simple)?
525 - if not self.allow_simple_key:
526 - raise ScannerError(None, None,
527 - "mapping keys are not allowed here",
528 - self.get_mark())
529 -
530 - # We may need to add BLOCK-MAPPING-START.
531 - if self.add_indent(self.column):
532 - mark = self.get_mark()
533 - self.tokens.append(BlockMappingStartToken(mark, mark))
534 -
535 - # Simple keys are allowed after '?' in the block context.
536 - self.allow_simple_key = not self.flow_level
537 -
538 - # Reset possible simple key on the current level.
539 - self.remove_possible_simple_key()
540 -
541 - # Add KEY.
542 - start_mark = self.get_mark()
543 - self.forward()
544 - end_mark = self.get_mark()
545 - self.tokens.append(KeyToken(start_mark, end_mark))
546 -
547 - def fetch_value(self):
548 -
549 - # Do we determine a simple key?
550 - if self.flow_level in self.possible_simple_keys:
551 -
552 - # Add KEY.
553 - key = self.possible_simple_keys[self.flow_level]
554 - del self.possible_simple_keys[self.flow_level]
555 - self.tokens.insert(key.token_number-self.tokens_taken,
556 - KeyToken(key.mark, key.mark))
557 -
558 - # If this key starts a new block mapping, we need to add
559 - # BLOCK-MAPPING-START.
560 - if not self.flow_level:
561 - if self.add_indent(key.column):
562 - self.tokens.insert(key.token_number-self.tokens_taken,
563 - BlockMappingStartToken(key.mark, key.mark))
564 -
565 - # There cannot be two simple keys one after another.
566 - self.allow_simple_key = False
567 -
568 - # It must be a part of a complex key.
569 - else:
570 -
571 - # Block context needs additional checks.
572 - # (Do we really need them? They will be catched by the parser
573 - # anyway.)
574 - if not self.flow_level:
575 -
576 - # We are allowed to start a complex value if and only if
577 - # we can start a simple key.
578 - if not self.allow_simple_key:
579 - raise ScannerError(None, None,
580 - "mapping values are not allowed here",
581 - self.get_mark())
582 -
583 - # If this value starts a new block mapping, we need to add
584 - # BLOCK-MAPPING-START. It will be detected as an error later by
585 - # the parser.
586 - if not self.flow_level:
587 - if self.add_indent(self.column):
588 - mark = self.get_mark()
589 - self.tokens.append(BlockMappingStartToken(mark, mark))
590 -
591 - # Simple keys are allowed after ':' in the block context.
592 - self.allow_simple_key = not self.flow_level
593 -
594 - # Reset possible simple key on the current level.
595 - self.remove_possible_simple_key()
596 -
597 - # Add VALUE.
598 - start_mark = self.get_mark()
599 - self.forward()
600 - end_mark = self.get_mark()
601 - self.tokens.append(ValueToken(start_mark, end_mark))
602 -
603 - def fetch_alias(self):
604 -
605 - # ALIAS could be a simple key.
606 - self.save_possible_simple_key()
607 -
608 - # No simple keys after ALIAS.
609 - self.allow_simple_key = False
610 -
611 - # Scan and add ALIAS.
612 - self.tokens.append(self.scan_anchor(AliasToken))
613 -
614 - def fetch_anchor(self):
615 -
616 - # ANCHOR could start a simple key.
617 - self.save_possible_simple_key()
618 -
619 - # No simple keys after ANCHOR.
620 - self.allow_simple_key = False
621 -
622 - # Scan and add ANCHOR.
623 - self.tokens.append(self.scan_anchor(AnchorToken))
624 -
625 - def fetch_tag(self):
626 -
627 - # TAG could start a simple key.
628 - self.save_possible_simple_key()
629 -
630 - # No simple keys after TAG.
631 - self.allow_simple_key = False
632 -
633 - # Scan and add TAG.
634 - self.tokens.append(self.scan_tag())
635 -
636 - def fetch_literal(self):
637 - self.fetch_block_scalar(style='|')
638 -
639 - def fetch_folded(self):
640 - self.fetch_block_scalar(style='>')
641 -
642 - def fetch_block_scalar(self, style):
643 -
644 - # A simple key may follow a block scalar.
645 - self.allow_simple_key = True
646 -
647 - # Reset possible simple key on the current level.
648 - self.remove_possible_simple_key()
649 -
650 - # Scan and add SCALAR.
651 - self.tokens.append(self.scan_block_scalar(style))
652 -
653 - def fetch_single(self):
654 - self.fetch_flow_scalar(style='\'')
655 -
656 - def fetch_double(self):
657 - self.fetch_flow_scalar(style='"')
658 -
659 - def fetch_flow_scalar(self, style):
660 -
661 - # A flow scalar could be a simple key.
662 - self.save_possible_simple_key()
663 -
664 - # No simple keys after flow scalars.
665 - self.allow_simple_key = False
666 -
667 - # Scan and add SCALAR.
668 - self.tokens.append(self.scan_flow_scalar(style))
669 -
670 - def fetch_plain(self):
671 -
672 - # A plain scalar could be a simple key.
673 - self.save_possible_simple_key()
674 -
675 - # No simple keys after plain scalars. But note that `scan_plain` will
676 - # change this flag if the scan is finished at the beginning of the
677 - # line.
678 - self.allow_simple_key = False
679 -
680 - # Scan and add SCALAR. May change `allow_simple_key`.
681 - self.tokens.append(self.scan_plain())
682 -
683 - # Checkers.
684 -
685 - def check_directive(self):
686 -
687 - # DIRECTIVE: ^ '%' ...
688 - # The '%' indicator is already checked.
689 - if self.column == 0:
690 - return True
691 -
692 - def check_document_start(self):
693 -
694 - # DOCUMENT-START: ^ '---' (' '|'\n')
695 - if self.column == 0:
696 - if self.prefix(3) == u'---' \
697 - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
698 - return True
699 -
700 - def check_document_end(self):
701 -
702 - # DOCUMENT-END: ^ '...' (' '|'\n')
703 - if self.column == 0:
704 - if self.prefix(3) == u'...' \
705 - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
706 - return True
707 -
708 - def check_block_entry(self):
709 -
710 - # BLOCK-ENTRY: '-' (' '|'\n')
711 - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
712 -
713 - def check_key(self):
714 -
715 - # KEY(flow context): '?'
716 - if self.flow_level:
717 - return True
718 -
719 - # KEY(block context): '?' (' '|'\n')
720 - else:
721 - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
722 -
723 - def check_value(self):
724 -
725 - # VALUE(flow context): ':'
726 - if self.flow_level:
727 - return True
728 -
729 - # VALUE(block context): ':' (' '|'\n')
730 - else:
731 - return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
732 -
733 - def check_plain(self):
734 -
735 - # A plain scalar may start with any non-space character except:
736 - # '-', '?', ':', ',', '[', ']', '{', '}',
737 - # '#', '&', '*', '!', '|', '>', '\'', '\"',
738 - # '%', '@', '`'.
739 - #
740 - # It may also start with
741 - # '-', '?', ':'
742 - # if it is followed by a non-space character.
743 - #
744 - # Note that we limit the last rule to the block context (except the
745 - # '-' character) because we want the flow context to be space
746 - # independent.
747 - ch = self.peek()
748 - return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \
749 - or (self.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029'
750 - and (ch == u'-' or (not self.flow_level and ch in u'?:')))
751 -
752 - # Scanners.
753 -
754 - def scan_to_next_token(self):
755 - # We ignore spaces, line breaks and comments.
756 - # If we find a line break in the block context, we set the flag
757 - # `allow_simple_key` on.
758 - # The byte order mark is stripped if it's the first character in the
759 - # stream. We do not yet support BOM inside the stream as the
760 - # specification requires. Any such mark will be considered as a part
761 - # of the document.
762 - #
763 - # TODO: We need to make tab handling rules more sane. A good rule is
764 - # Tabs cannot precede tokens
765 - # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
766 - # KEY(block), VALUE(block), BLOCK-ENTRY
767 - # So the checking code is
768 - # if <TAB>:
769 - # self.allow_simple_keys = False
770 - # We also need to add the check for `allow_simple_keys == True` to
771 - # `unwind_indent` before issuing BLOCK-END.
772 - # Scanners for block, flow, and plain scalars need to be modified.
773 -
774 - if self.index == 0 and self.peek() == u'\uFEFF':
775 - self.forward()
776 - found = False
777 - while not found:
778 - while self.peek() == u' ':
779 - self.forward()
780 - if self.peek() == u'#':
781 - while self.peek() not in u'\0\r\n\x85\u2028\u2029':
782 - self.forward()
783 - if self.scan_line_break():
784 - if not self.flow_level:
785 - self.allow_simple_key = True
786 - else:
787 - found = True
788 -
789 - def scan_directive(self):
790 - # See the specification for details.
791 - start_mark = self.get_mark()
792 - self.forward()
793 - name = self.scan_directive_name(start_mark)
794 - value = None
795 - if name == u'YAML':
796 - value = self.scan_yaml_directive_value(start_mark)
797 - end_mark = self.get_mark()
798 - elif name == u'TAG':
799 - value = self.scan_tag_directive_value(start_mark)
800 - end_mark = self.get_mark()
801 - else:
802 - end_mark = self.get_mark()
803 - while self.peek() not in u'\0\r\n\x85\u2028\u2029':
804 - self.forward()
805 - self.scan_directive_ignored_line(start_mark)
806 - return DirectiveToken(name, value, start_mark, end_mark)
807 -
808 - def scan_directive_name(self, start_mark):
809 - # See the specification for details.
810 - length = 0
811 - ch = self.peek(length)
812 - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
813 - or ch in u'-_':
814 - length += 1
815 - ch = self.peek(length)
816 - if not length:
817 - raise ScannerError("while scanning a directive", start_mark,
818 - "expected alphabetic or numeric character, but found %r"
819 - % ch.encode('utf-8'), self.get_mark())
820 - value = self.prefix(length)
821 - self.forward(length)
822 - ch = self.peek()
823 - if ch not in u'\0 \r\n\x85\u2028\u2029':
824 - raise ScannerError("while scanning a directive", start_mark,
825 - "expected alphabetic or numeric character, but found %r"
826 - % ch.encode('utf-8'), self.get_mark())
827 - return value
828 -
829 - def scan_yaml_directive_value(self, start_mark):
830 - # See the specification for details.
831 - while self.peek() == u' ':
832 - self.forward()
833 - major = self.scan_yaml_directive_number(start_mark)
834 - if self.peek() != '.':
835 - raise ScannerError("while scanning a directive", start_mark,
836 - "expected a digit or '.', but found %r"
837 - % self.peek().encode('utf-8'),
838 - self.get_mark())
839 - self.forward()
840 - minor = self.scan_yaml_directive_number(start_mark)
841 - if self.peek() not in u'\0 \r\n\x85\u2028\u2029':
842 - raise ScannerError("while scanning a directive", start_mark,
843 - "expected a digit or ' ', but found %r"
844 - % self.peek().encode('utf-8'),
845 - self.get_mark())
846 - return (major, minor)
847 -
848 - def scan_yaml_directive_number(self, start_mark):
849 - # See the specification for details.
850 - ch = self.peek()
851 - if not (u'0' <= ch <= u'9'):
852 - raise ScannerError("while scanning a directive", start_mark,
853 - "expected a digit, but found %r" % ch.encode('utf-8'),
854 - self.get_mark())
855 - length = 0
856 - while u'0' <= self.peek(length) <= u'9':
857 - length += 1
858 - value = int(self.prefix(length))
859 - self.forward(length)
860 - return value
861 -
862 - def scan_tag_directive_value(self, start_mark):
863 - # See the specification for details.
864 - while self.peek() == u' ':
865 - self.forward()
866 - handle = self.scan_tag_directive_handle(start_mark)
867 - while self.peek() == u' ':
868 - self.forward()
869 - prefix = self.scan_tag_directive_prefix(start_mark)
870 - return (handle, prefix)
871 -
872 - def scan_tag_directive_handle(self, start_mark):
873 - # See the specification for details.
874 - value = self.scan_tag_handle('directive', start_mark)
875 - ch = self.peek()
876 - if ch != u' ':
877 - raise ScannerError("while scanning a directive", start_mark,
878 - "expected ' ', but found %r" % ch.encode('utf-8'),
879 - self.get_mark())
880 - return value
881 -
882 - def scan_tag_directive_prefix(self, start_mark):
883 - # See the specification for details.
884 - value = self.scan_tag_uri('directive', start_mark)
885 - ch = self.peek()
886 - if ch not in u'\0 \r\n\x85\u2028\u2029':
887 - raise ScannerError("while scanning a directive", start_mark,
888 - "expected ' ', but found %r" % ch.encode('utf-8'),
889 - self.get_mark())
890 - return value
891 -
892 - def scan_directive_ignored_line(self, start_mark):
893 - # See the specification for details.
894 - while self.peek() == u' ':
895 - self.forward()
896 - if self.peek() == u'#':
897 - while self.peek() not in u'\0\r\n\x85\u2028\u2029':
898 - self.forward()
899 - ch = self.peek()
900 - if ch not in u'\0\r\n\x85\u2028\u2029':
901 - raise ScannerError("while scanning a directive", start_mark,
902 - "expected a comment or a line break, but found %r"
903 - % ch.encode('utf-8'), self.get_mark())
904 - self.scan_line_break()
905 -
906 - def scan_anchor(self, TokenClass):
907 - # The specification does not restrict characters for anchors and
908 - # aliases. This may lead to problems, for instance, the document:
909 - # [ *alias, value ]
910 - # can be interpteted in two ways, as
911 - # [ "value" ]
912 - # and
913 - # [ *alias , "value" ]
914 - # Therefore we restrict aliases to numbers and ASCII letters.
915 - start_mark = self.get_mark()
916 - indicator = self.peek()
917 - if indicator == u'*':
918 - name = 'alias'
919 - else:
920 - name = 'anchor'
921 - self.forward()
922 - length = 0
923 - ch = self.peek(length)
924 - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
925 - or ch in u'-_':
926 - length += 1
927 - ch = self.peek(length)
928 - if not length:
929 - raise ScannerError("while scanning an %s" % name, start_mark,
930 - "expected alphabetic or numeric character, but found %r"
931 - % ch.encode('utf-8'), self.get_mark())
932 - value = self.prefix(length)
933 - self.forward(length)
934 - ch = self.peek()
935 - if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
936 - raise ScannerError("while scanning an %s" % name, start_mark,
937 - "expected alphabetic or numeric character, but found %r"
938 - % ch.encode('utf-8'), self.get_mark())
939 - end_mark = self.get_mark()
940 - return TokenClass(value, start_mark, end_mark)
941 -
942 - def scan_tag(self):
943 - # See the specification for details.
944 - start_mark = self.get_mark()
945 - ch = self.peek(1)
946 - if ch == u'<':
947 - handle = None
948 - self.forward(2)
949 - suffix = self.scan_tag_uri('tag', start_mark)
950 - if self.peek() != u'>':
951 - raise ScannerError("while parsing a tag", start_mark,
952 - "expected '>', but found %r" % self.peek().encode('utf-8'),
953 - self.get_mark())
954 - self.forward()
955 - elif ch in u'\0 \t\r\n\x85\u2028\u2029':
956 - handle = None
957 - suffix = u'!'
958 - self.forward()
959 - else:
960 - length = 1
961 - use_handle = False
962 - while ch not in u'\0 \r\n\x85\u2028\u2029':
963 - if ch == u'!':
964 - use_handle = True
965 - break
966 - length += 1
967 - ch = self.peek(length)
968 - handle = u'!'
969 - if use_handle:
970 - handle = self.scan_tag_handle('tag', start_mark)
971 - else:
972 - handle = u'!'
973 - self.forward()
974 - suffix = self.scan_tag_uri('tag', start_mark)
975 - ch = self.peek()
976 - if ch not in u'\0 \r\n\x85\u2028\u2029':
977 - raise ScannerError("while scanning a tag", start_mark,
978 - "expected ' ', but found %r" % ch.encode('utf-8'),
979 - self.get_mark())
980 - value = (handle, suffix)
981 - end_mark = self.get_mark()
982 - return TagToken(value, start_mark, end_mark)
983 -
984 - def scan_block_scalar(self, style):
985 - # See the specification for details.
986 -
987 - if style == '>':
988 - folded = True
989 - else:
990 - folded = False
991 -
992 - chunks = []
993 - start_mark = self.get_mark()
994 -
995 - # Scan the header.
996 - self.forward()
997 - chomping, increment = self.scan_block_scalar_indicators(start_mark)
998 - self.scan_block_scalar_ignored_line(start_mark)
999 -
1000 - # Determine the indentation level and go to the first non-empty line.
1001 - min_indent = self.indent+1
1002 - if min_indent < 1:
1003 - min_indent = 1
1004 - if increment is None:
1005 - breaks, max_indent, end_mark = self.scan_block_scalar_indentation()
1006 - indent = max(min_indent, max_indent)
1007 - else:
1008 - indent = min_indent+increment-1
1009 - breaks, end_mark = self.scan_block_scalar_breaks(indent)
1010 - line_break = u''
1011 -
1012 - # Scan the inner part of the block scalar.
1013 - while self.column == indent and self.peek() != u'\0':
1014 - chunks.extend(breaks)
1015 - leading_non_space = self.peek() not in u' \t'
1016 - length = 0
1017 - while self.peek(length) not in u'\0\r\n\x85\u2028\u2029':
1018 - length += 1
1019 - chunks.append(self.prefix(length))
1020 - self.forward(length)
1021 - line_break = self.scan_line_break()
1022 - breaks, end_mark = self.scan_block_scalar_breaks(indent)
1023 - if self.column == indent and self.peek() != u'\0':
1024 -
1025 - # Unfortunately, folding rules are ambiguous.
1026 - #
1027 - # This is the folding according to the specification:
1028 -
1029 - if folded and line_break == u'\n' \
1030 - and leading_non_space and self.peek() not in u' \t':
1031 - if not breaks:
1032 - chunks.append(u' ')
1033 - else:
1034 - chunks.append(line_break)
1035 -
1036 - # This is Clark Evans's interpretation (also in the spec
1037 - # examples):
1038 - #
1039 - #if folded and line_break == u'\n':
1040 - # if not breaks:
1041 - # if self.peek() not in ' \t':
1042 - # chunks.append(u' ')
1043 - # else:
1044 - # chunks.append(line_break)
1045 - #else:
1046 - # chunks.append(line_break)
1047 - else:
1048 - break
1049 -
1050 - # Chomp the tail.
1051 - if chomping is not False:
1052 - chunks.append(line_break)
1053 - if chomping is True:
1054 - chunks.extend(breaks)
1055 -
1056 - # We are done.
1057 - return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
1058 - style)
1059 -
1060 - def scan_block_scalar_indicators(self, start_mark):
1061 - # See the specification for details.
1062 - chomping = None
1063 - increment = None
1064 - ch = self.peek()
1065 - if ch in u'+-':
1066 - if ch == '+':
1067 - chomping = True
1068 - else:
1069 - chomping = False
1070 - self.forward()
1071 - ch = self.peek()
1072 - if ch in u'0123456789':
1073 - increment = int(ch)
1074 - if increment == 0:
1075 - raise ScannerError("while scanning a block scalar", start_mark,
1076 - "expected indentation indicator in the range 1-9, but found 0",
1077 - self.get_mark())
1078 - self.forward()
1079 - elif ch in u'0123456789':
1080 - increment = int(ch)
1081 - if increment == 0:
1082 - raise ScannerError("while scanning a block scalar", start_mark,
1083 - "expected indentation indicator in the range 1-9, but found 0",
1084 - self.get_mark())
1085 - self.forward()
1086 - ch = self.peek()
1087 - if ch in u'+-':
1088 - if ch == '+':
1089 - chomping = True
1090 - else:
1091 - chomping = False
1092 - self.forward()
1093 - ch = self.peek()
1094 - if ch not in u'\0 \r\n\x85\u2028\u2029':
1095 - raise ScannerError("while scanning a block scalar", start_mark,
1096 - "expected chomping or indentation indicators, but found %r"
1097 - % ch.encode('utf-8'), self.get_mark())
1098 - return chomping, increment
1099 -
1100 - def scan_block_scalar_ignored_line(self, start_mark):
1101 - # See the specification for details.
1102 - while self.peek() == u' ':
1103 - self.forward()
1104 - if self.peek() == u'#':
1105 - while self.peek() not in u'\0\r\n\x85\u2028\u2029':
1106 - self.forward()
1107 - ch = self.peek()
1108 - if ch not in u'\0\r\n\x85\u2028\u2029':
1109 - raise ScannerError("while scanning a block scalar", start_mark,
1110 - "expected a comment or a line break, but found %r"
1111 - % ch.encode('utf-8'), self.get_mark())
1112 - self.scan_line_break()
1113 -
1114 - def scan_block_scalar_indentation(self):
1115 - # See the specification for details.
1116 - chunks = []
1117 - max_indent = 0
1118 - end_mark = self.get_mark()
1119 - while self.peek() in u' \r\n\x85\u2028\u2029':
1120 - if self.peek() != u' ':
1121 - chunks.append(self.scan_line_break())
1122 - end_mark = self.get_mark()
1123 - else:
1124 - self.forward()
1125 - if self.column > max_indent:
1126 - max_indent = self.column
1127 - return chunks, max_indent, end_mark
1128 -
1129 - def scan_block_scalar_breaks(self, indent):
1130 - # See the specification for details.
1131 - chunks = []
1132 - end_mark = self.get_mark()
1133 - while self.column < indent and self.peek() == u' ':
1134 - self.forward()
1135 - while self.peek() in u'\r\n\x85\u2028\u2029':
1136 - chunks.append(self.scan_line_break())
1137 - end_mark = self.get_mark()
1138 - while self.column < indent and self.peek() == u' ':
1139 - self.forward()
1140 - return chunks, end_mark
1141 -
1142 - def scan_flow_scalar(self, style):
1143 - # See the specification for details.
1144 - # Note that we loose indentation rules for quoted scalars. Quoted
1145 - # scalars don't need to adhere indentation because " and ' clearly
1146 - # mark the beginning and the end of them. Therefore we are less
1147 - # restrictive then the specification requires. We only need to check
1148 - # that document separators are not included in scalars.
1149 - if style == '"':
1150 - double = True
1151 - else:
1152 - double = False
1153 - chunks = []
1154 - start_mark = self.get_mark()
1155 - quote = self.peek()
1156 - self.forward()
1157 - chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
1158 - while self.peek() != quote:
1159 - chunks.extend(self.scan_flow_scalar_spaces(double, start_mark))
1160 - chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
1161 - self.forward()
1162 - end_mark = self.get_mark()
1163 - return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
1164 - style)
1165 -
1166 - ESCAPE_REPLACEMENTS = {
1167 - u'0': u'\0',
1168 - u'a': u'\x07',
1169 - u'b': u'\x08',
1170 - u't': u'\x09',
1171 - u'\t': u'\x09',
1172 - u'n': u'\x0A',
1173 - u'v': u'\x0B',
1174 - u'f': u'\x0C',
1175 - u'r': u'\x0D',
1176 - u'e': u'\x1B',
1177 - u' ': u'\x20',
1178 - u'\"': u'\"',
1179 - u'\\': u'\\',
1180 - u'N': u'\x85',
1181 - u'_': u'\xA0',
1182 - u'L': u'\u2028',
1183 - u'P': u'\u2029',
1184 - }
1185 -
1186 - ESCAPE_CODES = {
1187 - u'x': 2,
1188 - u'u': 4,
1189 - u'U': 8,
1190 - }
1191 -
1192 - def scan_flow_scalar_non_spaces(self, double, start_mark):
1193 - # See the specification for details.
1194 - chunks = []
1195 - while True:
1196 - length = 0
1197 - while self.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029':
1198 - length += 1
1199 - if length:
1200 - chunks.append(self.prefix(length))
1201 - self.forward(length)
1202 - ch = self.peek()
1203 - if not double and ch == u'\'' and self.peek(1) == u'\'':
1204 - chunks.append(u'\'')
1205 - self.forward(2)
1206 - elif (double and ch == u'\'') or (not double and ch in u'\"\\'):
1207 - chunks.append(ch)
1208 - self.forward()
1209 - elif double and ch == u'\\':
1210 - self.forward()
1211 - ch = self.peek()
1212 - if ch in self.ESCAPE_REPLACEMENTS:
1213 - chunks.append(self.ESCAPE_REPLACEMENTS[ch])
1214 - self.forward()
1215 - elif ch in self.ESCAPE_CODES:
1216 - length = self.ESCAPE_CODES[ch]
1217 - self.forward()
1218 - for k in range(length):
1219 - if self.peek(k) not in u'0123456789ABCDEFabcdef':
1220 - raise ScannerError("while scanning a double-quoted scalar", start_mark,
1221 - "expected escape sequence of %d hexdecimal numbers, but found %r" %
1222 - (length, self.peek(k).encode('utf-8')), self.get_mark())
1223 - code = int(self.prefix(length), 16)
1224 - chunks.append(unichr(code))
1225 - self.forward(length)
1226 - elif ch in u'\r\n\x85\u2028\u2029':
1227 - self.scan_line_break()
1228 - chunks.extend(self.scan_flow_scalar_breaks(double, start_mark))
1229 - else:
1230 - raise ScannerError("while scanning a double-quoted scalar", start_mark,
1231 - "found unknown escape character %r" % ch.encode('utf-8'), self.get_mark())
1232 - else:
1233 - return chunks
1234 -
1235 - def scan_flow_scalar_spaces(self, double, start_mark):
1236 - # See the specification for details.
1237 - chunks = []
1238 - length = 0
1239 - while self.peek(length) in u' \t':
1240 - length += 1
1241 - whitespaces = self.prefix(length)
1242 - self.forward(length)
1243 - ch = self.peek()
1244 - if ch == u'\0':
1245 - raise ScannerError("while scanning a quoted scalar", start_mark,
1246 - "found unexpected end of stream", self.get_mark())
1247 - elif ch in u'\r\n\x85\u2028\u2029':
1248 - line_break = self.scan_line_break()
1249 - breaks = self.scan_flow_scalar_breaks(double, start_mark)
1250 - if line_break != u'\n':
1251 - chunks.append(line_break)
1252 - elif not breaks:
1253 - chunks.append(u' ')
1254 - chunks.extend(breaks)
1255 - else:
1256 - chunks.append(whitespaces)
1257 - return chunks
1258 -
1259 - def scan_flow_scalar_breaks(self, double, start_mark):
1260 - # See the specification for details.
1261 - chunks = []
1262 - while True:
1263 - # Instead of checking indentation, we check for document
1264 - # separators.
1265 - prefix = self.prefix(3)
1266 - if (prefix == u'---' or prefix == u'...') \
1267 - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
1268 - raise ScannerError("while scanning a quoted scalar", start_mark,
1269 - "found unexpected document separator", self.get_mark())
1270 - while self.peek() in u' \t':
1271 - self.forward()
1272 - if self.peek() in u'\r\n\x85\u2028\u2029':
1273 - chunks.append(self.scan_line_break())
1274 - else:
1275 - return chunks
1276 -
1277 - def scan_plain(self):
1278 - # See the specification for details.
1279 - # We add an additional restriction for the flow context:
1280 - # plain scalars in the flow context cannot contain ',', ':' and '?'.
1281 - # We also keep track of the `allow_simple_key` flag here.
1282 - # Indentation rules are loosed for the flow context.
1283 - chunks = []
1284 - start_mark = self.get_mark()
1285 - end_mark = start_mark
1286 - indent = self.indent+1
1287 - # We allow zero indentation for scalars, but then we need to check for
1288 - # document separators at the beginning of the line.
1289 - #if indent == 0:
1290 - # indent = 1
1291 - spaces = []
1292 - while True:
1293 - length = 0
1294 - if self.peek() == u'#':
1295 - break
1296 - while True:
1297 - ch = self.peek(length)
1298 - if ch in u'\0 \t\r\n\x85\u2028\u2029' \
1299 - or (not self.flow_level and ch == u':' and
1300 - self.peek(length+1) in u'\0 \t\r\n\x85\u2028\u2029') \
1301 - or (self.flow_level and ch in u',:?[]{}'):
1302 - break
1303 - length += 1
1304 - # It's not clear what we should do with ':' in the flow context.
1305 - if (self.flow_level and ch == u':'
1306 - and self.peek(length+1) not in u'\0 \t\r\n\x85\u2028\u2029,[]{}'):
1307 - self.forward(length)
1308 - raise ScannerError("while scanning a plain scalar", start_mark,
1309 - "found unexpected ':'", self.get_mark(),
1310 - "Please check http://pyyaml.org/wiki/YAMLColonInFlowContext for details.")
1311 - if length == 0:
1312 - break
1313 - self.allow_simple_key = False
1314 - chunks.extend(spaces)
1315 - chunks.append(self.prefix(length))
1316 - self.forward(length)
1317 - end_mark = self.get_mark()
1318 - spaces = self.scan_plain_spaces(indent, start_mark)
1319 - if not spaces or self.peek() == u'#' \
1320 - or (not self.flow_level and self.column < indent):
1321 - break
1322 - return ScalarToken(u''.join(chunks), True, start_mark, end_mark)
1323 -
1324 - def scan_plain_spaces(self, indent, start_mark):
1325 - # See the specification for details.
1326 - # The specification is really confusing about tabs in plain scalars.
1327 - # We just forbid them completely. Do not use tabs in YAML!
1328 - chunks = []
1329 - length = 0
1330 - while self.peek(length) in u' ':
1331 - length += 1
1332 - whitespaces = self.prefix(length)
1333 - self.forward(length)
1334 - ch = self.peek()
1335 - if ch in u'\r\n\x85\u2028\u2029':
1336 - line_break = self.scan_line_break()
1337 - self.allow_simple_key = True
1338 - prefix = self.prefix(3)
1339 - if (prefix == u'---' or prefix == u'...') \
1340 - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
1341 - return
1342 - breaks = []
1343 - while self.peek() in u' \r\n\x85\u2028\u2029':
1344 - if self.peek() == ' ':
1345 - self.forward()
1346 - else:
1347 - breaks.append(self.scan_line_break())
1348 - prefix = self.prefix(3)
1349 - if (prefix == u'---' or prefix == u'...') \
1350 - and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
1351 - return
1352 - if line_break != u'\n':
1353 - chunks.append(line_break)
1354 - elif not breaks:
1355 - chunks.append(u' ')
1356 - chunks.extend(breaks)
1357 - elif whitespaces:
1358 - chunks.append(whitespaces)
1359 - return chunks
1360 -
1361 - def scan_tag_handle(self, name, start_mark):
1362 - # See the specification for details.
1363 - # For some strange reasons, the specification does not allow '_' in
1364 - # tag handles. I have allowed it anyway.
1365 - ch = self.peek()
1366 - if ch != u'!':
1367 - raise ScannerError("while scanning a %s" % name, start_mark,
1368 - "expected '!', but found %r" % ch.encode('utf-8'),
1369 - self.get_mark())
1370 - length = 1
1371 - ch = self.peek(length)
1372 - if ch != u' ':
1373 - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
1374 - or ch in u'-_':
1375 - length += 1
1376 - ch = self.peek(length)
1377 - if ch != u'!':
1378 - self.forward(length)
1379 - raise ScannerError("while scanning a %s" % name, start_mark,
1380 - "expected '!', but found %r" % ch.encode('utf-8'),
1381 - self.get_mark())
1382 - length += 1
1383 - value = self.prefix(length)
1384 - self.forward(length)
1385 - return value
1386 -
1387 - def scan_tag_uri(self, name, start_mark):
1388 - # See the specification for details.
1389 - # Note: we do not check if URI is well-formed.
1390 - chunks = []
1391 - length = 0
1392 - ch = self.peek(length)
1393 - while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \
1394 - or ch in u'-;/?:@&=+$,_.!~*\'()[]%':
1395 - if ch == u'%':
1396 - chunks.append(self.prefix(length))
1397 - self.forward(length)
1398 - length = 0
1399 - chunks.append(self.scan_uri_escapes(name, start_mark))
1400 - else:
1401 - length += 1
1402 - ch = self.peek(length)
1403 - if length:
1404 - chunks.append(self.prefix(length))
1405 - self.forward(length)
1406 - length = 0
1407 - if not chunks:
1408 - raise ScannerError("while parsing a %s" % name, start_mark,
1409 - "expected URI, but found %r" % ch.encode('utf-8'),
1410 - self.get_mark())
1411 - return u''.join(chunks)
1412 -
1413 - def scan_uri_escapes(self, name, start_mark):
1414 - # See the specification for details.
1415 - bytes = []
1416 - mark = self.get_mark()
1417 - while self.peek() == u'%':
1418 - self.forward()
1419 - for k in range(2):
1420 - if self.peek(k) not in u'0123456789ABCDEFabcdef':
1421 - raise ScannerError("while scanning a %s" % name, start_mark,
1422 - "expected URI escape sequence of 2 hexdecimal numbers, but found %r" %
1423 - (self.peek(k).encode('utf-8')), self.get_mark())
1424 - bytes.append(chr(int(self.prefix(2), 16)))
1425 - self.forward(2)
1426 - try:
1427 - value = unicode(''.join(bytes), 'utf-8')
1428 - except UnicodeDecodeError, exc:
1429 - raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark)
1430 - return value
1431 -
1432 - def scan_line_break(self):
1433 - # Transforms:
1434 - # '\r\n' : '\n'
1435 - # '\r' : '\n'
1436 - # '\n' : '\n'
1437 - # '\x85' : '\n'
1438 - # '\u2028' : '\u2028'
1439 - # '\u2029 : '\u2029'
1440 - # default : ''
1441 - ch = self.peek()
1442 - if ch in u'\r\n\x85':
1443 - if self.prefix(2) == u'\r\n':
1444 - self.forward(2)
1445 - else:
1446 - self.forward()
1447 - return u'\n'
1448 - elif ch in u'\u2028\u2029':
1449 - self.forward()
1450 - return ch
1451 - return u''
1452 -
1453 -#try:
1454 -# import psyco
1455 -# psyco.bind(Scanner)
1456 -#except ImportError:
1457 -# pass
1458 -
src/collectors/python.d.plugin/python_modules/pyyaml2/serializer.py deleted
-112
@@ -1,112 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -__all__ = ['Serializer', 'SerializerError']
4 -
5 -from error import YAMLError
6 -from events import *
7 -from nodes import *
8 -
9 -class SerializerError(YAMLError):
10 - pass
11 -
12 -class Serializer(object):
13 -
14 - ANCHOR_TEMPLATE = u'id%03d'
15 -
16 - def __init__(self, encoding=None,
17 - explicit_start=None, explicit_end=None, version=None, tags=None):
18 - self.use_encoding = encoding
19 - self.use_explicit_start = explicit_start
20 - self.use_explicit_end = explicit_end
21 - self.use_version = version
22 - self.use_tags = tags
23 - self.serialized_nodes = {}
24 - self.anchors = {}
25 - self.last_anchor_id = 0
26 - self.closed = None
27 -
28 - def open(self):
29 - if self.closed is None:
30 - self.emit(StreamStartEvent(encoding=self.use_encoding))
31 - self.closed = False
32 - elif self.closed:
33 - raise SerializerError("serializer is closed")
34 - else:
35 - raise SerializerError("serializer is already opened")
36 -
37 - def close(self):
38 - if self.closed is None:
39 - raise SerializerError("serializer is not opened")
40 - elif not self.closed:
41 - self.emit(StreamEndEvent())
42 - self.closed = True
43 -
44 - #def __del__(self):
45 - # self.close()
46 -
47 - def serialize(self, node):
48 - if self.closed is None:
49 - raise SerializerError("serializer is not opened")
50 - elif self.closed:
51 - raise SerializerError("serializer is closed")
52 - self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
53 - version=self.use_version, tags=self.use_tags))
54 - self.anchor_node(node)
55 - self.serialize_node(node, None, None)
56 - self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
57 - self.serialized_nodes = {}
58 - self.anchors = {}
59 - self.last_anchor_id = 0
60 -
61 - def anchor_node(self, node):
62 - if node in self.anchors:
63 - if self.anchors[node] is None:
64 - self.anchors[node] = self.generate_anchor(node)
65 - else:
66 - self.anchors[node] = None
67 - if isinstance(node, SequenceNode):
68 - for item in node.value:
69 - self.anchor_node(item)
70 - elif isinstance(node, MappingNode):
71 - for key, value in node.value:
72 - self.anchor_node(key)
73 - self.anchor_node(value)
74 -
75 - def generate_anchor(self, node):
76 - self.last_anchor_id += 1
77 - return self.ANCHOR_TEMPLATE % self.last_anchor_id
78 -
79 - def serialize_node(self, node, parent, index):
80 - alias = self.anchors[node]
81 - if node in self.serialized_nodes:
82 - self.emit(AliasEvent(alias))
83 - else:
84 - self.serialized_nodes[node] = True
85 - self.descend_resolver(parent, index)
86 - if isinstance(node, ScalarNode):
87 - detected_tag = self.resolve(ScalarNode, node.value, (True, False))
88 - default_tag = self.resolve(ScalarNode, node.value, (False, True))
89 - implicit = (node.tag == detected_tag), (node.tag == default_tag)
90 - self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
91 - style=node.style))
92 - elif isinstance(node, SequenceNode):
93 - implicit = (node.tag
94 - == self.resolve(SequenceNode, node.value, True))
95 - self.emit(SequenceStartEvent(alias, node.tag, implicit,
96 - flow_style=node.flow_style))
97 - index = 0
98 - for item in node.value:
99 - self.serialize_node(item, node, index)
100 - index += 1
101 - self.emit(SequenceEndEvent())
102 - elif isinstance(node, MappingNode):
103 - implicit = (node.tag
104 - == self.resolve(MappingNode, node.value, True))
105 - self.emit(MappingStartEvent(alias, node.tag, implicit,
106 - flow_style=node.flow_style))
107 - for key, value in node.value:
108 - self.serialize_node(key, node, None)
109 - self.serialize_node(value, node, key)
110 - self.emit(MappingEndEvent())
111 - self.ascend_resolver()
112 -
src/collectors/python.d.plugin/python_modules/pyyaml2/tokens.py deleted
-105
@@ -1,105 +0,0 @@
1 -# SPDX-License-Identifier: MIT
2 -
3 -class Token(object):
4 - def __init__(self, start_mark, end_mark):
5 - self.start_mark = start_mark
6 - self.end_mark = end_mark
7 - def __repr__(self):
8 - attributes = [key for key in self.__dict__
9 - if not key.endswith('_mark')]
10 - attributes.sort()
11 - arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
12 - for key in attributes])
13 - return '%s(%s)' % (self.__class__.__name__, arguments)
14 -
15 -#class BOMToken(Token):
16 -# id = '<byte order mark>'
17 -
18 -class DirectiveToken(Token):
19 - id = '<directive>'
20 - def __init__(self, name, value, start_mark, end_mark):
21 - self.name = name
22 - self.value = value
23 - self.start_mark = start_mark
24 - self.end_mark = end_mark
25 -
26 -class DocumentStartToken(Token):
27 - id = '<document start>'
28 -
29 -class DocumentEndToken(Token):
30 - id = '<document end>'
31 -
32 -class StreamStartToken(Token):
33 - id = '<stream start>'
34 - def __init__(self, start_mark=None, end_mark=None,
35 - encoding=None):
36 - self.start_mark = start_mark
37 - self.end_mark = end_mark
38 - self.encoding = encoding
39 -
40 -class StreamEndToken(Token):
41 - id = '<stream end>'
42 -
43 -class BlockSequenceStartToken(Token):
44 - id = '<block sequence start>'
45 -
46 -class BlockMappingStartToken(Token):
47 - id = '<block mapping start>'
48 -
49 -class BlockEndToken(Token):
50 - id = '<block end>'
51 -
52 -class FlowSequenceStartToken(Token):
53 - id = '['
54 -
55 -class FlowMappingStartToken(Token):
56 - id = '{'
57 -
58 -class FlowSequenceEndToken(Token):
59 - id = ']'
60 -
61 -class FlowMappingEndToken(Token):
62 - id = '}'
63 -
64 -class KeyToken(Token):
65 - id = '?'
66 -
67 -class ValueToken(Token):
68 - id = ':'
69 -
70 -class BlockEntryToken(Token):
71 - id = '-'
72 -
73 -class FlowEntryToken(Token):
74 - id = ','
75 -
76 -class AliasToken(Token):
77 - id = '<alias>'
78 - def __init__(self, value, start_mark, end_mark):
79 - self.value = value
80 - self.start_mark = start_mark
81 - self.end_mark = end_mark
82 -
83 -class AnchorToken(Token):
84 - id = '<anchor>'
85 - def __init__(self, value, start_mark, end_mark):
86 - self.value = value
87 - self.start_mark = start_mark
88 - self.end_mark = end_mark
89 -
90 -class TagToken(Token):
91 - id = '<tag>'
92 - def __init__(self, value, start_mark, end_mark):
93 - self.value = value
94 - self.start_mark = start_mark
95 - self.end_mark = end_mark
96 -
97 -class ScalarToken(Token):
98 - id = '<scalar>'
99 - def __init__(self, value, plain, start_mark, end_mark, style=None):
100 - self.value = value
101 - self.plain = plain
102 - self.start_mark = start_mark
103 - self.end_mark = end_mark
104 - self.style = style
105 -