def from_file(filename, level="(not set)"):
    """Load test cases from file, return as list of dicts.

    Puzzle should be formatted as a string on a single line.
    See puzzle.latinsquare.from_string. Trailing whitespace is stripped.

    Args:
        filename: File to read. One line per puzzle.
        level: Label to use for the "difficulty level" when loading this
            data. Optional.

    Returns:
        A list of dictionaries. Dictionary keys are puzzle (containing puzzle
        string); label (filename and line number of puzzle); and
        level (as passed to this function)
    """
    ret = []
    i = 0
    with open(filename) as f:
        for line in f:
            i += 1
            tc = {"puzzle": line.rstrip(), "label": f"{filename}:{i}", "level": level}
            ret.append(tc)
    return ret