from __future__ import unicode_literals
from __future__ import print_function

from copy import deepcopy

from builtins import input
from builtins import object
try:
    import oyaml as yaml
except ImportError:
    print("yaml has been replaced by oyaml to provide support for ordered dictionaries read from configuration")
    print("Please install via: \033[91m pip install oyaml --user.\033[0m")
    _ = input("Acknowledge by hitting enter (running with yaml for now. Note this might cause crashes)")
    import yaml
from . import _logger


class YAMLLoader(object):
    def __init__(self, **kwargs):
        kwargs.setdefault('log_level', 'warning')
        for k, v in kwargs.items():
            setattr(self, k, v)

    def construct_yaml_str(self, node):
        # Override the default string handling function
        # to always return unicode objects
        return self.construct_scalar(node)
    global default_ctor
    default_ctor = deepcopy(yaml.pyyaml.Loader.__dict__['yaml_constructors'])
    yaml.pyyaml.Loader.add_constructor(u'tag:yaml.org,2002:str', construct_yaml_str)

    @staticmethod
    def read_yaml(file_name, accept_none=False):
        if accept_none and file_name is None:
            return None
        try:
            try:
                with open(file_name, 'r') as config_file:
                    config = yaml.load(config_file, Loader=yaml.pyyaml.Loader)
            except TypeError:
                #workaround for existing yaml files written with py2 loader
                with open(file_name, 'r') as config_file:
                    setattr(yaml.pyyaml.Loader, 'yaml_constructors', default_ctor)
                    config = yaml.load(config_file, Loader=yaml.pyyaml.Loader)
            return config
        except IOError as e:
            _logger.error("Could not find or open yaml file %s" % file_name)
            _logger.error(e.strerror)
            raise e
        except yaml.YAMLError as e:
            _logger.error("Failed to load yaml file %s" % file_name)
            raise e


class YAMLDumper(object):
    def __init__(self, **kwargs):
        kwargs.setdefault('log_level', 'warning')
        for k, v in kwargs.items():
            setattr(self, k, v)

    @staticmethod
    def dump_yaml(data, file_name, **kwargs):
        try:
            _logger.debug("Try to open file %s" % file_name)
            out_file = open(file_name, "w+")
            _logger.debug("Try to dump data to file %s" % file_name)
            yaml.dump(data, out_file, **kwargs)
            out_file.close()
        except Exception as e:
            _logger.error("Failed to dump data to file %s" % file_name)
            raise e

@@ -555,32 +555,124 @@
 Loader(object):%0A
+    %22%22%22%0A    Class to load data from yaml files using oyaml module for ordered dicts%0A    %22%22%22%0A
     def __init__
@@ -1014,16 +1014,29 @@
 lt_ctor%0A
+    try:%0A    
     defa
@@ -1105,16 +1105,50 @@
 tors'%5D)%0A
+    except KeyError:%0A        pass%0A
     yaml
@@ -1288,24 +1288,335 @@
 one=False):%0A
+        %22%22%22%0A        Read data from given file and return it%0A        :param file_name: name of yaml file%0A        :type file_name: str%0A        :param accept_none: switch to deal with no file name provided (returns None)%0A        :type accept_none: bool%0A        :return: loaded data%0A        :rtype: any%0A        %22%22%22%0A
         if a
@@ -2505,24 +2505,79 @@
 er(object):%0A
+    %22%22%22%0A    Wrapper to write data to yaml file%0A    %22%22%22%0A
     def __in
@@ -2773,32 +2773,352 @@
 ame, **kwargs):%0A
+        %22%22%22%0A        Converts and writes data to yaml file%0A        :param data: data to be stored%0A        :type data: ant%0A        :param file_name: output file name%0A        :type file_name: str%0A        :param kwargs: optional arguments%0A        :type kwargs: dict%0A        :return: nothing%0A        :rtype: None%0A        %22%22%22%0A
         try:%0A   
@@ -3154,30 +3154,37 @@
 o open file 
-%25s%22 %25 
+%7B:s%7D%22.format(
 file_name)%0A 
@@ -3173,32 +3173,33 @@
 ormat(file_name)
+)
 %0A            out
@@ -3272,38 +3272,45 @@
 mp data to file 
-%25s%22 %25 
+%7B:s%7D%22.format(
 file_name)%0A     
@@ -3295,32 +3295,33 @@
 ormat(file_name)
+)
 %0A            yam
@@ -3464,30 +3464,37 @@
 ata to file 
-%25s%22 %25 
+%7B:s%7D%22.format(
 file_name)%0A 
@@ -3483,32 +3483,33 @@
 ormat(file_name)
+)
 %0A            rai

fix unavailable default constructor in python3