Beispiel #1
0
def iterrename(source, spec, strict):
    it = iter(source)
    hdr = next(it)
    flds = list(map(text_type, hdr))
    if strict:
        for x in spec:
            if isinstance(x, int):
                if x < 0 or x >= len(hdr):
                    raise FieldSelectionError(x)
            elif x not in flds:
                raise FieldSelectionError(x)
    outhdr = [
        spec[i] if i in spec else spec[f] if f in spec else f
        for i, f in enumerate(flds)
    ]
    yield tuple(outhdr)
    for row in it:
        yield tuple(row)
Beispiel #2
0
def asindices(hdr, spec):
    """Convert the given field `spec` into a list of field indices."""

    flds = list(map(text_type, hdr))
    indices = list()
    if not isinstance(spec, (list, tuple)):
        spec = (spec, )
    for s in spec:
        # spec could be a field index (takes priority)
        if isinstance(s, int) and s < len(hdr):
            indices.append(s)  # index fields from 0
        # spec could be a field
        elif s in flds:
            indices.append(flds.index(s))
        else:
            raise FieldSelectionError(s)
    return indices
def iterfieldconvert(source, converters, failonerror, errorvalue, where,
                     pass_row):

    # grab the fields in the source table
    it = iter(source)
    hdr = next(it)
    flds = list(map(text_type, hdr))
    yield tuple(hdr)  # these are not modified

    # build converter functions
    converter_functions = dict()
    for k, c in converters.items():

        # turn field names into row indices
        if not isinstance(k, integer_types):
            try:
                k = flds.index(k)
            except ValueError:  # not in list
                raise FieldSelectionError(k)
        assert isinstance(k, int), 'expected integer, found %r' % k

        # is converter a function?
        if callable(c):
            converter_functions[k] = c

        # is converter a method name?
        elif isinstance(c, string_types):
            converter_functions[k] = methodcaller(c)

        # is converter a method name with arguments?
        elif isinstance(c, (tuple, list)) and isinstance(c[0], string_types):
            methnm = c[0]
            methargs = c[1:]
            converter_functions[k] = methodcaller(methnm, *methargs)

        # is converter a dictionary?
        elif isinstance(c, dict):
            converter_functions[k] = dictconverter(c)

        # is it something else?
        elif c is None:
            pass  # ignore
        else:
            raise ArgumentError(
                'unexpected converter specification on field %r: %r' % (k, c))

    # define a function to transform a value
    def transform_value(i, v, *args):
        if i not in converter_functions:
            # no converter defined on this field, return value as-is
            return v
        else:
            try:
                return converter_functions[i](v, *args)
            except Exception as e:
                if failonerror:
                    raise e
                else:
                    return errorvalue

    # define a function to transform a row
    if pass_row:

        def transform_row(_row):
            return tuple(
                transform_value(i, v, _row) for i, v in enumerate(_row))
    else:

        def transform_row(_row):
            return tuple(transform_value(i, v) for i, v in enumerate(_row))

    # prepare where function
    if isinstance(where, string_types):
        where = expr(where)
    elif where is not None:
        assert callable(where), 'expected callable for "where" argument, ' \
                                'found %r' % where

    # prepare iterator
    if pass_row or where:
        # wrap rows as records
        it = (Record(row, flds) for row in it)

    # construct the data rows
    if where is None:
        # simple case, transform all rows
        for row in it:
            yield transform_row(row)
    else:
        # conditionally transform rows
        for row in it:
            if where(row):
                yield transform_row(row)
            else:
                yield row