import logging


def get_parse_tsv_line_fn(
    return_none_on_error = False,
    reverse = False):
  """A higher-order function producing TSV line-parsing functions.

  Args:
    return_none_on_error: Whether to return None on encountering an error (such
      as too few TSV columns) rather than raising an Error.
    reverse: When True, returns ([`target`], `source`) instead of ([`source`],
      `target`). Useful for working with "reverse" (a.k.a. "noise" models that
      go from `target` to `source`.

  Returns:
    A parsing function that goes from a text line to a ([source], target) pair
    (or a ([`target`], `source`) pair when `reverse`=True).
  """

  def parse_tsv_line(line):
    """Parses the first two columns, `source` and `target`, from a TSV line.

    Any further columns are ignored.

    Args:
      line: A text line.

    Returns:
      a tuple ([source], target), with `source` being wrapped in a list.

    Raises:
      ValueError: when the line has less than two TSV columns and
        `return_none_on_error`=False.
    """
    split = line.rstrip("\n").split("\t")
    if len(split) < 2:
      message = 'TSV line has less than two tab-delimited fields:\n"{}"'.format(
          line)
      if return_none_on_error:
        logging.warning(message)
        return None
      else:
        raise ValueError(message)
    source, target = split[:2]
    if reverse:
      return [target], source
    else:
      return [source], target

  return parse_tsv_line