blob: 95cd6414cf6fabc04dc8735d6ceeedff23797199 [file] [log] [blame]
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# markedyaml.py
# generates nodes with start/end line and column values
# start line seems off with single-line items, correct with multiline
#
# Original code from here: https://gist.github.com/dagss/5008118
# Request for licensing clarification made on 2017-09-19
# Contains improvements to support more types (bool/int/etc.)
from yaml.composer import Composer
from yaml.constructor import SafeConstructor
from yaml.parser import Parser
from yaml.reader import Reader
from yaml.resolver import Resolver
from yaml.scanner import Scanner
def create_node_class(cls):
class node_class(cls):
def __init__(self, x, start_mark, end_mark):
cls.__init__(self, x)
self.start_mark = start_mark
self.end_mark = end_mark
def __new__(self, x, start_mark, end_mark):
return cls.__new__(self, x)
node_class.__name__ = '%s_node' % cls.__name__
return node_class
dict_node = create_node_class(dict)
list_node = create_node_class(list)
unicode_node = create_node_class(unicode)
int_node = create_node_class(int)
float_node = create_node_class(float)
class NodeConstructor(SafeConstructor):
# To support lazy loading, the original constructors first yield
# an empty object, then fill them in when iterated. Due to
# laziness we omit this behaviour (and will only do "deep
# construction") by first exhausting iterators, then yielding
# copies.
def construct_yaml_map(self, node):
obj, = SafeConstructor.construct_yaml_map(self, node)
return dict_node(obj, node.start_mark, node.end_mark)
def construct_yaml_seq(self, node):
obj, = SafeConstructor.construct_yaml_seq(self, node)
return list_node(obj, node.start_mark, node.end_mark)
def construct_yaml_str(self, node):
obj = SafeConstructor.construct_scalar(self, node)
assert isinstance(obj, unicode)
return unicode_node(obj, node.start_mark, node.end_mark)
def construct_yaml_bool(self, node):
obj = SafeConstructor.construct_yaml_bool(self, node)
return int_node(obj, node.start_mark, node.end_mark)
def construct_yaml_int(self, node):
obj = SafeConstructor.construct_scalar(self, node)
return int_node(obj, node.start_mark, node.end_mark)
def construct_yaml_float(self, node):
obj = SafeConstructor.construct_scalar(self, node)
return float_node(obj, node.start_mark, node.end_mark)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:map',
NodeConstructor.construct_yaml_map)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:seq',
NodeConstructor.construct_yaml_seq)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:str',
NodeConstructor.construct_yaml_str)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:bool',
NodeConstructor.construct_yaml_bool)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:int',
NodeConstructor.construct_yaml_int)
NodeConstructor.add_constructor(
u'tag:yaml.org,2002:float',
NodeConstructor.construct_yaml_float)
class MarkedLoader(Reader, Scanner, Parser, Composer,
NodeConstructor, Resolver):
def __init__(self, stream):
Reader.__init__(self, stream)
Scanner.__init__(self)
Parser.__init__(self)
Composer.__init__(self)
NodeConstructor.__init__(self)
Resolver.__init__(self)
def get_data(stream):
return MarkedLoader(stream).get_data()