code: def wait(objects, count=None, timeout=None):
      
      for obj in objects:
          if not hasattr(obj, 'add_done_callback'):
              raise TypeError('Expecting sequence of waitable objects')
      if count is None:
          count = len(objects)
      if count < 0 or count > len(objects):
          raise ValueError('count must be between 0 and len(objects)')
      if count == 0:
          return [], objects
      pending = list(objects)
      done = []
      try:
          for obj in _wait(pending, timeout):
              done.append(obj)
              if len(done) == count:
                  break
      except Timeout:
          pass
      return done, list(filter(bool, pending))
docs: Wait for one or more waitable objects.
  
      This method waits until *count* elements from the sequence of waitable
      objects *objects* have become ready. If *count* is ``None`` (the default),
      then wait for all objects to become ready.
  
      What "ready" is means depends on the object type. A waitable object is a
      objects that implements the ``add_done_callback()`` and
      ``remove_done_callback`` methods. This currently includes:
  
        * :class:`~gruvi.Event` - an event is ready when its internal flag is set.
        * :class:`~gruvi.Future` - a future is ready when its result is set.
        * :class:`~gruvi.Fiber` - a fiber is ready when has terminated.
        * :class:`~gruvi.Process` - a process is ready when the child has exited.