def iter_gff3(path, attributes=None, region=None, score_fill=-1,
              phase_fill=-1, attributes_fill='.', tabix='tabix'):
    if attributes is not None:
        attributes = list(attributes)
        if isinstance(attributes_fill, (list, tuple)):
            if len(attributes) != len(attributes_fill):
                raise ValueError('number of fills does not match attributes')
        else:
            attributes_fill = [attributes_fill] * len(attributes)
    if region is not None:
        cmd = [tabix, path, region]
        buffer = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
    elif path.endswith('.gz') or path.endswith('.bgz'):
        buffer = gzip.open(path, mode='rb')
    else:
        buffer = open(path, mode='rb')
    try:
        for line in buffer:
            if line[0] == b'>':
                return
            if line[0] == b'
                continue
            vals = line.split(b'\t')
            if len(vals) == 9:
                fseqid, fsource, ftype, fstart, fend, fscore, fstrand, fphase, fattrs = vals
                fstart = int(fstart)
                fend = int(fend)
                if fscore == b'.':
                    fscore = score_fill
                else:
                    fscore = float(fscore)
                if fphase == b'.':
                    fphase = phase_fill
                else:
                    fphase = int(fphase)
                if not PY2:
                    fseqid = str(fseqid, 'ascii')
                    fsource = str(fsource, 'ascii')
                    ftype = str(ftype, 'ascii')
                    fstrand = str(fstrand, 'ascii')
                    fattrs = str(fattrs, 'ascii')
                rec = (fseqid, fsource, ftype, fstart, fend, fscore, fstrand, fphase)
                if attributes is not None:
                    dattrs = gff3_parse_attributes(fattrs)
                    vattrs = tuple(
                        dattrs.get(k, f)
                        for k, f in zip(attributes, attributes_fill)
                    )
                    rec += vattrs
                yield rec
    finally:
        buffer.close()