code: 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()