<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def pipe_csv(context=None, _INPUT=None, conf=None, **kwargs):
 """A source that fetches and parses a csv file to yield items. Loopable. Parameters context : pipe2py.Context object _INPUT : pipeforever pipe or an iterable of items or fields conf : URL -- url skip -- number of header rows to skip col_mode -- column name source: row=header row(s), custom=defined in col_name col_name -- list of custom column names col_row_start -- first column header row col_row_end -- last column header row separator -- column separator Yields ------ _OUTPUT : items Note: Current restrictions: separator must be 1 character assumes every row has exactly the expected number of fields, as defined in the header """

    conf = DotDict(conf)
    conf_sep = conf['separator']
    conf_mode = conf['col_mode']
    col_name = conf['col_name']

    for item in _INPUT:
        item = DotDict(item)
        url = utils.get_value(conf['URL'], item, **kwargs)
        url = utils.get_abspath(url)
        separator = utils.get_value(conf_sep, item, encode=True, **kwargs)
        skip = int(utils.get_value(conf['skip'], item, **kwargs))
        col_mode = utils.get_value(conf_mode, item, **kwargs)

        f = urlopen(url)

        if context and context.verbose:
            print "pipe_csv loading:", url

        for i in xrange(skip):
            f.next()

        reader = csv.UnicodeReader(f, delimiter=separator)
        fieldnames = []

        if col_mode == 'custom':
            fieldnames = [DotDict(x).get() for x in col_name]
        else:
            fieldnames = _gen_fieldnames(conf, reader, item, **kwargs)

        for rows in reader:
            yield dict(zip(fieldnames, rows))

        f.close()

        if item.get('forever'):
            # _INPUT is pipeforever and not a loop,
            # so we just yield our item once
            break