# Path: ronin/utils/types.py
# def type_name(the_type):
#     """
#     Human-readable name of type(s). Built-in types will avoid the "__builtin__" prefix.
# 
#     Tuples are always handled as a join of "|". 
#     
#     :param the_type: type(s)
#     :type the_type: type|(type)
#     :returns: name of type(s)
#     :rtype: str
#     """
# 
#     if isinstance(the_type, tuple):
#         return '|'.join([type_name(v) for v in the_type])    
#     module = to_str(the_type.__module__)
#     name = to_str(the_type.__name__)
#     return name if module == '__builtin__' else '{}.{}'.format(module, name)
# 
# def import_symbol(name):
#     """
#     Imports a symbol based on its fully qualified name.
#     
#     :param name: symbol name
#     :type name: str
#     :returns: symbol
#     :raises ImportError: if could not import the module
#     :raises AttributeError: if could not find the symbol in the module
#     """
#     
#     if name and ('.' in name):
#         module_name, name = name.rsplit('.', 1)
#         return getattr(__import__(module_name, fromlist=[name], level=0), name)
#     raise ImportError('import not found: {}'.format(name))
# 
# Path: ronin/utils/unicode.py



from .types import type_name, import_symbol
from .unicode import string
from collections import OrderedDict
from inspect import isclass
     list
    :type unwrapper_function: ~types.FunctionType
    """

    def __init__(self, items=None, key_type=None, value_type=None, wrapper_function=None,
                 unwrapper_function=None):
        super(StrictDict, self).__init__()
        if isinstance(items, StrictDict):
            self.key_type = items.key_type
            self.value_type = items.value_type
            self.wrapper_function = items.wrapper_function
            self.unwrapper_function = items.unwrapper_function
        self.key_type = _convert_type(key_type)
        self.value_type = _convert_type(value_type)
        self.wrapper_function = wrapper_function
        self.unwrapper_function = unwrapper_function
        if items:
            for k, v in items:
                self[k] = v

    def __getitem__(self, key):
        if (self.key_type is not None) and (not isinstance(key, self.key_type)):
            raise TypeError('key must be a "{}": {!r}'.format(type_name(self.key_type), key))
        value = super(StrictDict, self).__getitem__(key)
        if self.unwrapper_function is not None:
            value = self.unwrapper_function(value)
        return value

    def __setitem__(self, key, value, **_):
        if (self.key_type is not None) and (not isinstance(key, self.key_type)):

# Path: ronin/utils/types.py
# def type_name(the_type):
#     """
#     Human-readable name of type(s). Built-in types will avoid the "__builtin__" prefix.
# 
#     Tuples are always handled as a join of "|". 
#     
#     :param the_type: type(s)
#     :type the_type: type|(type)
#     :returns: name of type(s)
#     :rtype: str
#     """
# 
#     if isinstance(the_type, tuple):
#         return '|'.join([type_name(v) for v in the_type])    
#     module = to_str(the_type.__module__)
#     name = to_str(the_type.__name__)
#     return name if module == '__builtin__' else '{}.{}'.format(module, name)
# 
# def import_symbol(name):
#     """
#     Imports a symbol based on its fully qualified name.
#     
#     :param name: symbol name
#     :type name: str
#     :returns: symbol
#     :raises ImportError: if could not import the module
#     :raises AttributeError: if could not find the symbol in the module
#     """
#     
#     if name and ('.' in name):
#         module_name, name = name.rsplit('.', 1)
#         return getattr(__import__(module_name, fromlist=[name], level=0), name)
#     raise ImportError('import not found: {}'.format(name))
# 
# Path: ronin/utils/unicode.py



# Path: ronin/utils/collections.py
from .types import type_name, import_symbol
from .unicode import string
from collections import OrderedDict
from inspect import isclass

     list
    :type unwrapper_function: ~types.FunctionType
    """

    def __init__(self, items=None, key_type=None, value_type=None, wrapper_function=None,
                 unwrapper_function=None):
        super(StrictDict, self).__init__()
        if isinstance(items, StrictDict):
            self.key_type = items.key_type
            self.value_type = items.value_type
            self.wrapper_function = items.wrapper_function
            self.unwrapper_function = items.unwrapper_function
        self.key_type = _convert_type(key_type)
        self.value_type = _convert_type(value_type)
        self.wrapper_function = wrapper_function
        self.unwrapper_function = unwrapper_function
        if items:
            for k, v in items:
                self[k] = v

    def __getitem__(self, key):
        if (self.key_type is not None) and (not isinstance(key, self.key_type)):
            raise TypeError('key must be a "{}": {!r}'.format(type_name(self.key_type), key))
        value = super(StrictDict, self).__getitem__(key)
        if self.unwrapper_function is not None:
            value = self.unwrapper_function(value)
        return value

    def __setitem__(self, key, value, **_):
        if (self.key_type is not None) and (not isinstance(key, self.key_type)):

            raise TypeError('key must be a "{}": {!r}'.format(type_name(self.key_type), key))