from typing import Set


def _generate_new_name(base_name: str, taken_names: Set[str]) -> str:
    """Return a name based on the provided string that is not already taken.

    This method tries the following names: {base_name}_0, then {base_name}_1, etc.
    and returns the first one that's not in taken_names

    Args:
        base_name: The base for name construction as explained above
        taken_names: The set of names not permitted as output

    Returns:
        a name based on the base_name that is not in taken_names
    """
    index = 0
    while "{}_{}".format(base_name, index) in taken_names:
        index += 1
    return "{}_{}".format(base_name, index)