Raise an exception if obj is not an instance of one of the specified types.

    Similarly to isinstance, 'types' may be either a single type or a tuple of
    types.

    If name or type_name is provided, it is used in the exception message.
    The object's string representation is also included in the message,
    truncated to 'truncate_at' number of characters.

def require_instance(obj, types=None, name=None, type_name=None, truncate_at=80):
    """
    Raise an exception if obj is not an instance of one of the specified types.

    Similarly to isinstance, 'types' may be either a single type or a tuple of
    types.

    If name or type_name is provided, it is used in the exception message.
    The object's string representation is also included in the message,
    truncated to 'truncate_at' number of characters.
    """
    if not isinstance(obj, types):
        obj_string = str(obj)
        if len(obj_string) > truncate_at:
            obj_string = obj_string[:truncate_at - 3] + "..."
        if type_name is None:
            try:
                type_name = "one of " + ", ".join(str(t) for t in types)
            except TypeError:
                type_name = str(types)
        name_string = ("%s: " % name) if name else ""
        error_message = "%sexpected %s. Got: '%s' of type '%s'" % (
            name_string, type_name, obj_string, type(obj))
        raise TypeError(error_message)