##
# Copyright (c) 2008-2010 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


import importlib

from .map import MappingType
from ..error import SchemaValidationError


class ClassType(MappingType):
    def __init__(self, schema):
        super().__init__(schema)

    def load(self, dct):
        dct['mapping'] = {'=': {'type': 'map', 'required': True, 'mapping': dct['fields']}}
        dct['min-length'] = 1
        dct['max-length'] = 1
        super().load(dct)

    def check(self, node):
        if self.check_tag(node, 'tag:yaml.org,2002:null'):
            return node

        clsname = node.value[0][0].value

        try:
            mod, _, name = clsname.rpartition('.')
            cls = getattr(importlib.import_module(mod), name)
        except (ImportError, AttributeError):
            raise SchemaValidationError('could not find class %s' % clsname, node)

        if hasattr(cls, 'get_yaml_validator_config'):
            config = cls.get_yaml_validator_config()
            if config:
                next(iter(self.keys.values()))['type'].load_keys(config)

        node = super().check(node)

        clsdict = node.value[0][1]

        tag = 'tag:importkit.magic.io,2009/importkit/object/create:%s' % clsname
        self.push_tag(clsdict, tag)

        return clsdict

##
# Copyright (c) 2008-2010 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


import importlib

from .map import MappingType
from ..error import SchemaValidationError


class ClassType(MappingType):
    def __init__(self, schema):
        super().__init__(schema)

    def load(self, dct):
        fallback = dct.get('fallback')
        if fallback:
            try:
                mod, _, name = fallback.rpartition('.')
                self.fallback = getattr(importlib.import_module(mod), name)
                self.fallback_name = fallback
            except (ImportError, AttributeError):
                raise SchemaValidationError(
                        'could not find class %s' % fallback)

        dct['mapping'] = {'=': {'type': 'map', 'required': True,
                                'mapping': dct['fields']}}
        dct['min-length'] = 1
        dct['max-length'] = 1
        super().load(dct)

    def check(self, node):
        if self.check_tag(node, 'tag:yaml.org,2002:null'):
            return node

        clsname = node.value[0][0].value

        try:
            mod, _, name = clsname.rpartition('.')
            cls = getattr(importlib.import_module(mod), name)
        except (ImportError, AttributeError):
            if self.fallback:
                cls = self.fallback
                clsname = self.fallback_name
            else:
                raise SchemaValidationError(
                        'could not find class %s' % clsname, node)

        if hasattr(cls, 'get_yaml_validator_config'):
            config = cls.get_yaml_validator_config()
            if config:
                next(iter(self.keys.values()))['type'].load_keys(config)

        node = super().check(node)

        clsdict = node.value[0][1]

        tag = 'tag:importkit.magic.io,2009/importkit/object/create:%s' % clsname
        self.push_tag(clsdict, tag)

        return clsdict

Make it possible to specify fallback class name