from typing import Iterable
from typing import Any
from typing import List


def str_list_limited(_list: Iterable[Any], limit: int) -> str:
    """
    Get the string representation of a list which is not too long.

    If the size of the input list is less or equal to the limit, returns str(list).
    If the size exceeds the limit, returns a string representation which matches str(list) for
    the first limit items, and the has the string "and N more", where N is the number of items
    not shown.

    This is useful for producing exception messages for collection lookups, so you can give
    the user some idea what is in the collection without potentially blowing up their terminal
    for large collections.
    """
    if limit < 0:
        raise ValueError("Limit must be positive")
    if not isinstance(_list, List):
        _list = list(_list)

    if len(_list) <= limit:
        return str(_list)
    else:
        return (
            "["
            + ", ".join(repr(x) for x in _list[:limit])
            + " and %s more" % (len(_list) - limit)
            + "]"
        )