from typing import Any
import numbers


def _max_len(value: Any, max_len: int = 20, add_addr: bool = False) -> Any:
    """Abbreviate a string representation of an object to `max_len` characters.

    For numbers, booleans and None, the original value will be returned for
    correct rendering in the table formatting tool.

    Args:
        value: Object to be represented as a string.
        max_len: Maximum return string length.
        add_addr: If True, will add part of the object address to the end of the
            string, e.g. to identify different instances of the same class. If
            False, three dots (``...``) will be used instead.
    """
    if value is None or isinstance(value, (int, float, numbers.Number, bool)):
        return value

    string = str(value)
    if len(string) <= max_len:
        return string

    if add_addr and not isinstance(value, (int, float, bool)):
        result = f"{string[: (max_len - 5)]}_{hex(id(value))[-4:]}"
        return result

    result = f"{string[: (max_len - 3)]}..."
    return result