blob: 6e1cea8c9dad6c51d7766bb64b839fb9229eaa97 [file] [log] [blame]
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""YAML utilities."""
import collections
import yaml
class BaseYAMLTagHandlerMetaclass(type):
def __init__(cls, *args, **kwargs):
if cls.YAML_TAG is not None and cls.TARGET_CLASS is not None:
yaml.add_constructor(cls.YAML_TAG, cls.YAMLConstructor, Loader=cls.LOADER)
yaml.add_representer(cls.TARGET_CLASS, cls.YAMLRepresenter,
Dumper=cls.DUMPER)
super(BaseYAMLTagHandlerMetaclass, cls).__init__(*args, **kwargs)
class BaseYAMLTagHandler(metaclass=BaseYAMLTagHandlerMetaclass):
YAML_TAG = None
TARGET_CLASS = None
LOADER = yaml.Loader
DUMPER = yaml.Dumper
@classmethod
def YAMLConstructor(cls, loader, node, deep=False):
raise NotImplementedError
@classmethod
def YAMLRepresenter(cls, dumper, data):
raise NotImplementedError
def ParseMappingAsOrderedDict(enable=True,
loader=yaml.Loader,
dumper=yaml.Dumper):
"""Treat OrderedDict as the default mapping instance.
While we load a yaml file to a object, modify the object, and dump to a yaml
file, we hope to keep the order of the mapping instance. Therefore, we should
parse the mapping to the Python OrderedDict object, and dump the OrderedDict
instance to yaml just like a dict object.
Args:
enable: if enable is True, load and dump yaml as OrderedDict.
"""
def DictRepresenter(dumper, data):
return dumper.represent_dict(data.items())
def OrderedDictRepresenter(dumper, data):
return dumper.represent_object(data)
def OrderedDictConstructor(loader, node):
return collections.OrderedDict(loader.construct_pairs(node))
def DictConstructor(loader, node):
return dict(loader.construct_pairs(node))
if enable:
# Represent OrderedDict object like a dict.
# Construct the yaml mapping string to OrderedDict.
yaml.add_representer(collections.OrderedDict, DictRepresenter,
Dumper=dumper)
yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
OrderedDictConstructor, Loader=loader)
else:
# Set back to normal.
yaml.add_representer(collections.OrderedDict, OrderedDictRepresenter,
Dumper=dumper)
yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
DictConstructor, Loader=loader)