Checks that every key/value in @d is an instance of @kcls: @vcls

        Will also unmarshal JSON objects to Python objects if
        the value is an instance of dict and @vcls is a class type

        Args:
            d:          The dict to type assert
            kcls:       The class to type assert for keys.
                        NOTE: JSON only allows str keys
            vcls:       The class to type assert for values
            allow_none: Allow a None value for the values.
                        This would not make sense for the keys.
            cast_from:  type-or-tuple-of-types, If @obj is an instance
                        of this type(s), cast it to @cast_to
            cast_to:    type, The type to cast @obj to if it's an instance
                        of @cast_from, or None to cast to @cls.
                        If you need more than type(x), use a lambda or
                        factory function.
            dynamic:    @cls, A dynamic default value if @d is None,
                        and @dynamic is not None.
            objcls:     None-or-type, a type to assert @d is,
                        ie:  dict, etc...
                        Note that isinstance considers
                        collections.OrderedDict to be of type dict
            ctor:       None-or-static-method: Use this method as the
                        constructor instead of __init__
        Returns:
            @d, note that @d will be recreated, which
            may be a performance concern if @d has many items
        Raises:
            TypeError: if a key is not an instance of @kcls or
                       a value is not an instance of @vcls

def type_assert_dict(
    d,
    kcls=None,
    vcls=None,
    allow_none=False,
    cast_from=None,
    cast_to=None,
    dynamic=None,
    objcls=None,
    ctor=None,
):
    """ Checks that every key/value in @d is an instance of @kcls: @vcls

        Will also unmarshal JSON objects to Python objects if
        the value is an instance of dict and @vcls is a class type

        Args:
            d:          The dict to type assert
            kcls:       The class to type assert for keys.
                        NOTE: JSON only allows str keys
            vcls:       The class to type assert for values
            allow_none: Allow a None value for the values.
                        This would not make sense for the keys.
            cast_from:  type-or-tuple-of-types, If @obj is an instance
                        of this type(s), cast it to @cast_to
            cast_to:    type, The type to cast @obj to if it's an instance
                        of @cast_from, or None to cast to @cls.
                        If you need more than type(x), use a lambda or
                        factory function.
            dynamic:    @cls, A dynamic default value if @d is None,
                        and @dynamic is not None.
            objcls:     None-or-type, a type to assert @d is,
                        ie:  dict, etc...
                        Note that isinstance considers
                        collections.OrderedDict to be of type dict
            ctor:       None-or-static-method: Use this method as the
                        constructor instead of __init__
        Returns:
            @d, note that @d will be recreated, which
            may be a performance concern if @d has many items
        Raises:
            TypeError: if a key is not an instance of @kcls or
                       a value is not an instance of @vcls
    """
    _check_dstruct(d, objcls)

    if (
        d is None
        and
        dynamic is not None
    ):
        d = dynamic
    t = type(d)
    return t(
        (
            _check(k, kcls) if kcls else k,
            _check(
                v,
                vcls,
                allow_none,
                cast_from,
                cast_to,
                ctor=ctor,
            ) if vcls else v,
        )
        for k, v in d.items()
    )