Checks that every object in @iterable is an instance of @cls

        Will also unmarshal JSON objects to Python objects if items in
        @iterable are an instance of dict

        Args:
            iterable:   Any iterable to check.  Note that it would not
                        make sense to pass a generator to this function
            cls:        type, The class type to assert each member
                        of @iterable is
            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 @iterable is None,
                        and @dynamic is not None.
            objcls:     None-or-type, a type to assert @iterable is,
                        ie:  list, set, etc...
            choices:    iterable-or-None, If not None, each object in
                        @iterable must be in @choices
            ctor:       None-or-static-method: Use this method as the
                        constructor instead of __init__
            allow_none: bool, True to allow @iterable to be None,
                        otherwise False
        Returns:
            @iterable, note that @iterable will be recreated, which
            may be a performance concern if @iterable has many items
        Raises:
            TypeError: if @obj is not an instance of @cls

def type_assert_iter(
    iterable,
    cls,
    cast_from=None,
    cast_to=None,
    dynamic=None,
    objcls=None,
    choices=None,
    ctor=None,
    allow_none=False,
):
    """ Checks that every object in @iterable is an instance of @cls

        Will also unmarshal JSON objects to Python objects if items in
        @iterable are an instance of dict

        Args:
            iterable:   Any iterable to check.  Note that it would not
                        make sense to pass a generator to this function
            cls:        type, The class type to assert each member
                        of @iterable is
            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 @iterable is None,
                        and @dynamic is not None.
            objcls:     None-or-type, a type to assert @iterable is,
                        ie:  list, set, etc...
            choices:    iterable-or-None, If not None, each object in
                        @iterable must be in @choices
            ctor:       None-or-static-method: Use this method as the
                        constructor instead of __init__
            allow_none: bool, True to allow @iterable to be None,
                        otherwise False
        Returns:
            @iterable, note that @iterable will be recreated, which
            may be a performance concern if @iterable has many items
        Raises:
            TypeError: if @obj is not an instance of @cls
    """
    if (
        allow_none
        and
        iterable is None
    ):
        return iterable

    _check_dstruct(iterable, objcls)

    if choices is not None:
        for obj in iterable:
            _check_choices(obj, choices)

    if (
        iterable is None
        and
        dynamic is not None
    ):
        iterable = dynamic
    t = type(iterable)
    return t(
        _check(
            obj,
            cls,
            False,
            cast_from,
            cast_to,
            ctor=ctor,
        ) for obj in iterable
    )