def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True):
  # Python documentation recommends objects which do not support hash
  # set this value to None. Python library objects follow this rule.
  is_hashable = lambda val: val.__hash__

  # If x is hashable, returns whether x is in s. Else returns whether x is in l.
  def is_in_set_or_list(x, s, l):
    if is_hashable(x):
      return x in s
    return x in l

  prepend_index = 0

  # Make membership testing of hashables in |to| (in particular, strings)
  # faster.
  hashable_to_set = set(x for x in to if is_hashable(x))
  for item in fro:
    singleton = False
    if type(item) in (str, int):
      # The cheap and easy case.
      if is_paths:
        to_item = MakePathRelative(to_file, fro_file, item)
      else:
        to_item = item

      if not (type(item) is str and item.startswith('-')):
        # Any string that doesn't begin with a "-" is a singleton - it can
        # only appear once in a list, to be enforced by the list merge append
        # or prepend.
        singleton = True
    elif type(item) is dict:
      # Make a copy of the dictionary, continuing to look for paths to fix.
      # The other intelligent aspects of merge processing won't apply because
      # item is being merged into an empty dict.
      to_item = {}
      MergeDicts(to_item, item, to_file, fro_file)
    elif type(item) is list:
      # Recurse, making a copy of the list.  If the list contains any
      # descendant dicts, path fixing will occur.  Note that here, custom
      # values for is_paths and append are dropped; those are only to be
      # applied to |to| and |fro|, not sublists of |fro|.  append shouldn't
      # matter anyway because the new |to_item| list is empty.
      to_item = []
      MergeLists(to_item, item, to_file, fro_file)
    else:
      raise TypeError(
          'Attempt to merge list item of unsupported type ' + \
          item.__class__.__name__)

    if append:
      # If appending a singleton that's already in the list, don't append.
      # This ensures that the earliest occurrence of the item will stay put.
      if not singleton or not is_in_set_or_list(to_item, hashable_to_set, to):
        to.append(to_item)
        if is_hashable(to_item):
          hashable_to_set.add(to_item)
    else:
      # If prepending a singleton that's already in the list, remove the
      # existing instance and proceed with the prepend.  This ensures that the
      # item appears at the earliest possible position in the list.
      while singleton and to in to_item:
        to.remove(to_item)

      # Don't just insert everything at index 0.  That would prepend the new
      # items to the list in reverse order, which would be an unwelcome
      # surprise.
      to.insert(prepend_index, to_item)
      if is_hashable(to_item):
        hashable_to_set.add(to_item)
      prepend_index = prepend_index + 1
dataset/ETHPy150Open adblockplus/gyp/pylib/gyp/input.py/MergeLists/swapped operands of `in`