def conditional_casting(str_value):
    """Tries to cast a string value to an integer or float.
    Falls back to the most general type if the casting fails.

    :param str_value: (string) value to be casted.
    :return: (int, float or string) the casted input value.

    >>> conditional_casting('1')
    1
    >>> conditional_casting('12a')
    '12a'
    >>> conditional_casting('12.0')
    12.0
    >>> conditional_casting('12a.0')
    '12a.0'
    """
    try:
        try:
            int_value = int(str_value)
            return int_value
        except ValueError:
            float_value = float(str_value)
            return float_value
    except ValueError:
        return str_value
