code: def assert_list(obj, expected_type=string_types, can_be_none=True, default=(), key_arg=None,
      allowable=(list, Fileset, OrderedSet, set, tuple), raise_type=ValueError):
    
    def get_key_msg(key=None):
      if key is None:
        return ''
      else:
        return "In key '{}': ".format(key)
  
    allowable = tuple(allowable)
  
    key_msg = get_key_msg(key_arg)
    val = obj
    if val is None:
      if can_be_none:
        val = list(default)
      else:
        raise raise_type(
          '{}Expected an object of acceptable type {}, received None and can_be_none is False'
            .format(key_msg, allowable))
  
    if isinstance(val, allowable):
      lst = list(val)
      for e in lst:
        if not isinstance(e, expected_type):
          raise raise_type(
              '{}Expected a list containing values of type {}, instead got a value {} of {}'
              .format(key_msg, expected_type, e, e.__class__))
      return lst
    else:
      raise raise_type(
          '{}Expected an object of acceptable type {}, received {} instead'
          .format(key_msg, allowable, val))
docs: This function is used to ensure that parameters set by users in BUILD files are of acceptable types.
  
    :API: public
  
    :param obj           : the object that may be a list. It will pass if it is of type in allowable.
    :param expected_type : this is the expected type of the returned list contents.
    :param can_be_none   : this defines whether or not the obj can be None. If True, return default.
    :param default       : this is the default to return if can_be_none is True and obj is None.
    :param key_arg       : this is the name of the key to which obj belongs to
    :param allowable     : the acceptable types for obj. We do not want to allow any iterable (eg string).
    :param raise_type    : the error to throw if the type is not correct.