docs: def connect(self, callback, sender=None, senders=None, key=None, keys=None, weak=True):
          '''
          *This method is a coroutine.*
  
          Connect a callback. By default, the callback will be called any time
          :meth:`asyncio_dispatch.Signal.send` is called. You may restrict this by adding ``senders``
          and/or ``keys`` which will cause the connected callback to only be called when
          :meth:`asyncio_dispatch.Signal.send` is called with a matching `sender` and/or ``key``.
  
          The difference between a ``sender`` and a ``key`` is that a ``sender`` refers to a specific
          object's location in memory and uses :func:`builtins.id` for comparison while a ``key``
          uses :func:`builtins.hash` for comparison. Thus two strings of the same value will always
          be equal when used as a ``key`` but may be seen as different objects when used as a
          ``sender``.
  
  
          :param callback: A callable to be called when the signal is sent
          :param Object sender: Any python object. Connects the callback to a single ``sender``.
          :param list senders: An iterable of ``sender`` objects. Connects the callback against
              multiple ``senders``.
          :param str key: Any object that can be used as a key in a python dictionary. Connects the
              callback against a single ``key``.
          :param list keys: An iterable of ``key`` objects. Connects the callback against multiple
              ``keys``.
          :param weak: If ``True``, the callback will be stored as a weakreference. If a long-lived
              reference is required, use ``False``.
          '''
          weak_callback = yield from self._get_ref(callback, weak)
  
          # dispatch
          if (sender is None) and (senders is None) and (key is None) and (keys is None):
              # subscribe always activate the callback when the signal is sent
              with (yield from self._lock_all):
                  self._all.add(weak_callback)
          else:
              if sender is not None:
                  yield from self._add_sender(sender, weak_callback)
  
              if senders is not None:
                  for sender in senders:
                      yield from self._add_sender(sender, weak_callback)
  
              if key is not None:
                  yield from self._add_key(key, weak_callback)
  
              if keys is not None:
                  for key in keys:
                      yield from self._add_key(key, weak_callback)