none [kbd-scrolllock] kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock 
  "   lY>d
n-jvOe1hu     #
# Copyright (c) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. 
#

"""

  YAMLObject - Provides mapping to/from YAML.

  $Id: //eng/vdo-releases/magnesium/src/python/vdo/utils/YAMLObject.py#2 $

"""

import gettext
import yaml

gettext.install("utils")

########################################################################
class YAMLObject(yaml.YAMLObject):
  """Provides conversion of objects to and from YAML representations.

  The attributes that are included in the YAML representation are taken
  from an instance's __dict__ filtered through the list returned from the
  _yamlAttributeKeys property.

  The list from the _yamlAttributeKeys property is used to check for missing
  attributes when generating the YAML representation.  It is also used
  to check for missing or extraneous attributes when constructing an instance
  from the YAML representation.
  Subclasses must override _yamlAttributeKeys.

  Subclasses must specify the class attribute yaml_tag which indicates the type
  of the instance in the YAML representation.

  Class attributes:
    yaml_tag (unicode string) - YAML representation identfifier;
                                must be specified by subclasses
    yaml_loader               - The loader to use; set to yaml.SafeLoader
                                to allow yaml.load_safe() to instantiate
                                objects
  """
  yaml_loader = yaml.SafeLoader

  ######################################################################
  # Overridden methods
  ######################################################################
  @classmethod
  def from_yaml(cls, loader, node):
    """Constructs and returns an instance from its YAML representation.

    Returns:
      instance constructed from YAML representation.
    """
    instance = cls._yamlMakeInstance()
    yield instance
    mapping = loader.construct_mapping(node)
    instance._yamlSetAttributes(mapping)

  ######################################################################
  @classmethod
  def to_yaml(cls, dumper, data):
    """Returns a YAML representation of the instance.

    Returns:
      YAML representation of instance
    """
    yamlData = data._yamlData
    return dumper.represent_mapping(data.yaml_tag, yamlData)

  ######################################################################
  def __init__(self):
    super(YAMLObject, self).__init__()
    self._preservedExtraAttributes = {}

  ######################################################################
  # Protected methods
  ######################################################################
  @classmethod
  def _yamlMakeInstance(cls):
    """Returns an instance of the class specifying placeholder values for
    any arguments required by the __init__ method.

    The default implementation is to instantiate without arguments.
    Subclasses must override if their __init__ method takes arguments.
    """
    return cls()

  ######################################################################
  @property
  def _yamlData(self):
    """Returns a dictionary containing the data to include in generating
    the instance's YAML representation.

    The base implementation