import re


def get_type_string(val, nested_others):
    """Gets the type of the attr val as a string

    Args:
        val: current attr being processed
        nested_others: list of nested others to deal with that might have module path info in the string

    Returns:
        type_string: type of the attr as a str

    """
    # Grab the base or type info depending on what is provided
    if "type" in val.metadata:
        type_string = repr(val.metadata["type"])
    elif "base" in val.metadata:
        type_string = val.metadata["base"]
    elif hasattr(val.type, "__name__"):
        type_string = val.type.__name__
    else:
        type_string = str(val.type)
    # Regex out the typing info if present
    type_string = re.sub(r"typing.", "", type_string)
    # Regex out any nested_others that have module path information
    for other_val in nested_others:
        split_other = f"{'.'.join(other_val.split('.')[:-1])}."
        type_string = re.sub(split_other, "", type_string)
    # Regex the string to see if it matches any Enums in the __main__ module space
    # Construct the type with the metadata
    if "optional" in val.metadata:
        type_string = f"Optional[{type_string}]"
    return type_string