def cast_or_except(data, typefn, exn, msg):
    """ Raise exception exn with argument msg if data is not of type typefn """
    def str_type(t): return str(t).split("'")[1]
    try: return typefn(data)
    except: raise exn("{} must be valid {}".format(msg, str_type(typefn)))