docs: async def gather_coalescing_exceptions(coros, display, *, verbose):
      '''The tricky thing about running multiple coroutines in parallel is what
      we're supposed to do when one of them raises an exception. The approach
      we're using here is to catch exceptions and keep waiting for other tasks to
      finish. At the end, we reraise a GatheredExceptions error, if any
      exceptions were caught.
  
      Another minor detail: We also want to make sure to start coroutines in the
      order given, so that they end up appearing to the user alphabetically in
      the fancy display. Note that asyncio.gather() puts coroutines in a set
      internally, so we schedule coroutines *before* we give them to gather().
      '''
  
      exceptions = []
      reprs = []
  
      async def catching_wrapper(coro):
          try:
              return (await coro)
          except Exception as e:
              exceptions.append(e)
              if isinstance(e, PrintableError) and not verbose:
                  reprs.append(e.message)
              else:
                  reprs.append(traceback.format_exc())
              return None
  
      # Suppress a deprecation warning in Python 3.5, while continuing to support
      # 3.3 and early 3.4 releases.
      if hasattr(asyncio, 'ensure_future'):
          schedule = getattr(asyncio, 'ensure_future')
      else:
          schedule = getattr(asyncio, 'async')
  
      futures = [schedule(catching_wrapper(coro)) for coro in coros]
  
      results = await asyncio.gather(*futures)
  
      if exceptions:
          raise GatheredExceptions(exceptions, reprs)
      else:
          return results