def load_csv(vs):
    'Convert from CSV, first handling header row specially.'
    with vs.source.open_text() as fp:
        for i in range(options.skip):
            wrappedNext(fp)  # discard initial lines

        if options.safety_first:
            rdr = csv.reader(removeNulls(fp), **csvoptions())
        else:
            rdr = csv.reader(fp, **csvoptions())

        vs.rows = []

        # headers first, to setup columns before adding rows
        headers = [wrappedNext(rdr) for i in range(int(options.header))]

        if headers:
            # columns ideally reflect the max number of fields over all rows
            vs.columns = ArrayNamedColumns('\\n'.join(x) for x in zip(*headers))
        else:
            r = wrappedNext(rdr)
            vs.addRow(r)
            vs.columns = ArrayColumns(len(vs.rows[0]))

        if not vs.columns:
            vs.columns = [ColumnItem(0)]

        vs.recalc()  # make columns usable
        with Progress(total=vs.source.filesize) as prog:
            try:
                samplelen = 0
                for i in range(options_num_first_rows):  # for progress below
                    row = wrappedNext(rdr)
                    vs.addRow(row)
                    samplelen += sum(len(x) for x in row)

                samplelen //= options_num_first_rows  # avg len of first n rows

                while True:
                    vs.addRow(wrappedNext(rdr))
                    prog.addProgress(samplelen)
            except StopIteration:
                pass  # as expected

    vs.recalc()
    return vs
Convert from CSV, first handling header row specially.