def METHOD_NAME(*signals):
    """A context manager for catching signals.
    Entering this context manager starts listening for the given signals and
    returns an async iterator; exiting the context manager stops listening.
    The async iterator blocks until a signal arrives, and then yields it.
    Note that if you leave the ``with`` block while the iterator has
    unextracted signals still pending inside it, then they will be
    re-delivered using Python's regular signal handling logic. This avoids a
    race condition when signals arrives just before we exit the ``with``
    block.
    Args:
      signals: the signals to listen for.
    Raises:
      TypeError: if no signals were provided.
      RuntimeError: if you try to use this anywhere except Python's main
          thread. (This is a Python limitation.)
    Example:
      A common convention for Unix daemons is that they should reload their
      configuration when they receive a ``SIGHUP``. Here's a sketch of what
      that might look like using :func:`open_signal_receiver`::
         with trio.open_signal_receiver(signal.SIGHUP) as signal_aiter:
             async for signum in signal_aiter:
                 assert signum == signal.SIGHUP
                 reload_configuration()
    """
    if not signals:
        raise TypeError("No signals were provided")
    if not is_main_thread():
        raise RuntimeError(
            "Sorry, open_signal_receiver is only possible when running in "
            "Python interpreter's main thread"
        )
    token = trio.lowlevel.current_trio_token()
    queue = SignalReceiver()
    def handler(signum, _):
        token.run_sync_soon(queue._add, signum, idempotent=True)
    try:
        with _signal_handler(signals, handler):
            yield queue
    finally:
        queue._redeliver_remaining()