Ensures that given iterable container has certain type.

  Args:
    iterable: An iterable container to assert the type for.
    expected_item_type: An expected type of the container items.

  Raises:
    TypeError: If given container does is not an iterable or its items do not
               have the expected type.

def AssertIterableType(iterable, expected_item_type):
  """Ensures that given iterable container has certain type.

  Args:
    iterable: An iterable container to assert the type for.
    expected_item_type: An expected type of the container items.

  Raises:
    TypeError: If given container does is not an iterable or its items do not
               have the expected type.
  """
  # We do not consider iterators to be iterables even though Python does. An
  # "iterable" should be a type that can be iterated (that is: an iterator can
  # be constructed for them). Iterators should not be considered to be iterable
  # because it makes no sense to construct an iterator for iterator. The most
  # important practical implication is that act of iterating an iterator drains
  # it whereas act of iterating the iterable does not.
  if isinstance(iterable, collections.Iterator):
    message = "Expected iterable container but got iterator `%s` instead"
    message %= iterable
    raise TypeError(message)

  AssertType(iterable, collections.Iterable)
  for item in iterable:
    AssertType(item, expected_item_type)