from typing import Union


def cast_number(qnum: str) -> Union[str, int, float]:
    """Attempt to cast a number from a string

    This function attempts to cast a string to a number. It will first try to parse an
    int, then a float, and finally returns a string if both fail.
    """

    try:
        return int(qnum)
    except ValueError:
        try:
            return float(qnum)
        except ValueError:
            return qnum