docs: def collection_generator(collection):
      """This function returns a generator which iterates over the collection,
      similar to Collection.itertuples().  Collections are viewed by this module,
      regardless of type, as a mapping from an index to the value.  For sets, the
      "index" is the value itself (ie, (V, V)).  For dicts, it's a string, and
      for lists, it's an int.
  
      In general, this function defers to ``itertuples`` and/or ``iteritems``
      methods defined on the instances; however, when duck typing, this function
      typically provides the generator.
      """
      if collection is _nothing:
  
          def generator():
              if False:
                  yield any
  
      elif hasattr(collection, "itertuples"):
          return collection.itertuples()
      elif hasattr(collection, "keys"):
  
          def generator():
              for key in collection.keys():
                  yield (key, collection[key])
  
      elif hasattr(collection, "items"):
          return collection.items()
      elif hasattr(collection, "iteritems"):
          return collection.iteritems()
      elif hasattr(collection, "__getitem__"):
  
          def generator():
              i = 0
              for item in collection:
                  yield (i, item)
                  i += 1
  
      else:
  
          def generator():
              for item in collection:
                  yield (item, item)
  
      return generator()