def connect(receiver, signal=Any, sender=Any, weak=True):
    """Connect receiver to sender for signal

    receiver -- a callable Python object which is to receive
        messages/signals/events.  Receivers must be hashable
        objects.

        if weak is True, then receiver must be weak-referencable
        (more precisely saferef.safeRef() must be able to create
        a reference to the receiver).
    
        Receivers are fairly flexible in their specification,
        as the machinery in the robustApply module takes care
        of most of the details regarding figuring out appropriate
        subsets of the sent arguments to apply to a given
        receiver.

        Note:
            if receiver is itself a weak reference (a callable),
            it will be de-referenced by the system's machinery,
            so *generally* weak references are not suitable as
            receivers, though some use might be found for the
            facility whereby a higher-level library passes in
            pre-weakrefed receiver references.

    signal -- the signal to which the receiver should respond
    
        if Any, receiver will receive any signal from the
        indicated sender (which might also be Any, but is not
        necessarily Any).
        
        Otherwise must be a hashable Python object other than
        None (DispatcherError raised on None).
        
    sender -- the sender to which the receiver should respond
    
        if Any, receiver will receive the indicated signals
        from any sender.
        
        if Anonymous, receiver will only receive indicated
        signals from send/sendExact which do not specify a
        sender, or specify Anonymous explicitly as the sender.

        Otherwise can be any python object.
        
    weak -- whether to use weak references to the receiver
        By default, the module will attempt to use weak
        references to the receiver objects.  If this parameter
        is false, then strong references will be used.

    returns None, may raise DispatcherTypeError
    """
    if signal is None:
        raise errors.DispatcherTypeError(
            'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender)
        )
    if weak:
        receiver = saferef.safeRef(receiver, onDelete=_removeReceiver)
    senderkey = id(sender)
    if senderkey in connections:
        signals = connections[senderkey]
    else:
        connections[senderkey] = signals = {}
    # Keep track of senders for cleanup.
    # Is Anonymous something we want to clean up?
    if sender not in (None, Anonymous, Any):
        def remove(object, senderkey=senderkey):
            _removeSender(senderkey=senderkey)
        # Skip objects that can not be weakly referenced, which means
        # they won't be automatically cleaned up, but that's too bad.
        try:
            weakSender = weakref.ref(sender, remove)
            senders[senderkey] = weakSender
        except:
            pass
        
    receiverID = id(receiver)
    # get current set, remove any current references to
    # this receiver in the set, including back-references
    if signal in signals:
        receivers = signals[signal]
        _removeOldBackRefs(senderkey, signal, receiver, receivers)
    else:
        receivers = signals[signal] = []
    try:
        current = sendersBack.get( receiverID )
        if current is None:
            sendersBack[ receiverID ] = current = []
        if senderkey not in current:
            current.append(senderkey)
    except:
        pass

    receivers.append(receiver)
Connect receiver to sender for signal

    receiver -- a callable Python object which is to receive
        messages/signals/events.  Receivers must be hashable
        objects.

        if weak is True, then receiver must be weak-referencable
        (more precisely saferef.safeRef() must be able to create
        a reference to the receiver).
    
        Receivers are fairly flexible in their specification,
        as the machinery in the robustApply module takes care
        of most of the details regarding figuring out appropriate
        subsets of the sent arguments to apply to a given
        receiver.

        Note:
            if receiver is itself a weak reference (a callable),
            it will be de-referenced by the system's machinery,
            so *generally* weak references are not suitable as
            receivers, though some use might be found for the
            facility whereby a higher-level library passes in
            pre-weakrefed receiver references.

    signal -- the signal to which the receiver should respond
    
        if Any, receiver will receive any signal from the
        indicated sender (which might also be Any, but is not
        necessarily Any).
        
        Otherwise must be a hashable Python object other than
        None (DispatcherError raised on None).
        
    sender -- the sender to which the receiver should respond
    
        if Any, receiver will receive the indicated signals
        from any sender.
        
        if Anonymous, receiver will only receive indicated
        signals from send/sendExact which do not specify a
        sender, or specify Anonymous explicitly as the sender.

        Otherwise can be any python object.
        
    weak -- whether to use weak references to the receiver
        By default, the module will attempt to use weak
        references to the receiver objects.  If this parameter
        is false, then strong references will be used.

    returns None, may raise DispatcherTypeError