# Path: auxlib/compat.py
# def isiterable(obj):
# 
# Path: auxlib/decorators.py
# def memoizedproperty(func):
#     """
#     Decorator to cause a method to cache it's results in self for each
#     combination of inputs and return the cached result on subsequent calls.
#     Does not support named arguments or arg values that are not hashable.
# 
#     >>> class Foo (object):
#     ...   _x = 1
#     ...   @memoizedproperty
#     ...   def foo(self):
#     ...     self._x += 1
#     ...     print('updating and returning {0}'.format(self._x))
#     ...     return self._x
#     ...
#     >>> foo1 = Foo()
#     >>> foo2 = Foo()
#     >>> foo1.foo
#     updating and returning 2
#     2
#     >>> foo1.foo
#     2
#     >>> foo2.foo
#     updating and returning 2
#     2
#     >>> foo1.foo
#     2
#     """
#     inner_attname = '__%s' % func.__name__
# 
#     def new_fget(self):
#         if not hasattr(self, '_cache_'):
#             self._cache_ = dict()
#         cache = self._cache_
#         if inner_attname not in cache:
#             cache[inner_attname] = func(self)
#         return cache[inner_attname]
# 
#     return property(new_fget)
# 
# Path: auxlib/exceptions.py
# class AuxlibError(object):
#     """Mixin to identify exceptions associated with the auxlib package."""


from collections import Mapping
from itertools import chain
from re import IGNORECASE, compile
from enum import Enum
from .compat import NoneType, integer_types, isiterable, iteritems, string_types, text_type
from .decorators import memoizedproperty
from .exceptions import AuxlibError
        if not (type_hint - NUMBER_TYPES_SET):
            return numberify(value)
        elif not (type_hint - STRING_TYPES_SET):
            return text_type(value)
        elif not (type_hint - {bool, NoneType}):
            return boolify(value, nullable=True)
        elif not (type_hint - (STRING_TYPES_SET | {bool})):
            return boolify(value, return_string=True)
        elif not (type_hint - (STRING_TYPES_SET | {NoneType})):
            value = text_type(value)
            return None if value.lower() == 'none' else value
        elif not (type_hint - {bool, int}):
            return typify_str_no_hint(text_type(value))
        else:
            raise NotImplementedError()
    elif type_hint is not None:
        # coerce using the type hint, or use boolify for bool
        try:
            return boolify(value) if type_hint == bool else type_hint(value)
        except ValueError as e:
            # ValueError: invalid literal for int() with base 10: 'nope'
            raise TypeCoercionError(value, text_type(e))
    else:
        # no type hint, but we know value is a string, so try to match with the regex patterns
        #   if there's still no match, `typify_str_no_hint` will return `value`
        return typify_str_no_hint(value)


def typify_data_structure(value, type_hint=None):
    if isinstance(value, Mapping):

# Path: auxlib/compat.py
# def isiterable(obj):
# 
# Path: auxlib/decorators.py
# def memoizedproperty(func):
#     """
#     Decorator to cause a method to cache it's results in self for each
#     combination of inputs and return the cached result on subsequent calls.
#     Does not support named arguments or arg values that are not hashable.
# 
#     >>> class Foo (object):
#     ...   _x = 1
#     ...   @memoizedproperty
#     ...   def foo(self):
#     ...     self._x += 1
#     ...     print('updating and returning {0}'.format(self._x))
#     ...     return self._x
#     ...
#     >>> foo1 = Foo()
#     >>> foo2 = Foo()
#     >>> foo1.foo
#     updating and returning 2
#     2
#     >>> foo1.foo
#     2
#     >>> foo2.foo
#     updating and returning 2
#     2
#     >>> foo1.foo
#     2
#     """
#     inner_attname = '__%s' % func.__name__
# 
#     def new_fget(self):
#         if not hasattr(self, '_cache_'):
#             self._cache_ = dict()
#         cache = self._cache_
#         if inner_attname not in cache:
#             cache[inner_attname] = func(self)
#         return cache[inner_attname]
# 
#     return property(new_fget)
# 
# Path: auxlib/exceptions.py
# class AuxlibError(object):
#     """Mixin to identify exceptions associated with the auxlib package."""


# Path: auxlib/type_coercion.py
from collections import Mapping
from itertools import chain
from re import IGNORECASE, compile
from enum import Enum
from .compat import NoneType, integer_types, isiterable, iteritems, string_types, text_type
from .decorators import memoizedproperty
from .exceptions import AuxlibError

        if not (type_hint - NUMBER_TYPES_SET):
            return numberify(value)
        elif not (type_hint - STRING_TYPES_SET):
            return text_type(value)
        elif not (type_hint - {bool, NoneType}):
            return boolify(value, nullable=True)
        elif not (type_hint - (STRING_TYPES_SET | {bool})):
            return boolify(value, return_string=True)
        elif not (type_hint - (STRING_TYPES_SET | {NoneType})):
            value = text_type(value)
            return None if value.lower() == 'none' else value
        elif not (type_hint - {bool, int}):
            return typify_str_no_hint(text_type(value))
        else:
            raise NotImplementedError()
    elif type_hint is not None:
        # coerce using the type hint, or use boolify for bool
        try:
            return boolify(value) if type_hint == bool else type_hint(value)
        except ValueError as e:
            # ValueError: invalid literal for int() with base 10: 'nope'
            raise TypeCoercionError(value, text_type(e))
    else:
        # no type hint, but we know value is a string, so try to match with the regex patterns
        #   if there's still no match, `typify_str_no_hint` will return `value`
        return typify_str_no_hint(value)


def typify_data_structure(value, type_hint=None):
    if isinstance(value, Mapping):

        return type(value)((k, typify(v, type_hint)) for k, v in iteritems(value))