1"""Module implementing error-catching version of send (sendRobust)"""
2from pydispatch.dispatcher import Any, Anonymous, liveReceivers, getAllReceivers
3from pydispatch.robustapply import robustApply
4
5def sendRobust(
6    signal=Any,
7    sender=Anonymous,
8    *arguments, **named
9):
10    """Send signal from sender to all connected receivers catching errors
11
12    signal -- (hashable) signal value, see connect for details
13
14    sender -- the sender of the signal
15
16        if Any, only receivers registered for Any will receive
17        the message.
18
19        if Anonymous, only receivers registered to receive
20        messages from Anonymous or Any will receive the message
21
22        Otherwise can be any python object (normally one
23        registered with a connect if you actually want
24        something to occur).
25
26    arguments -- positional arguments which will be passed to
27        *all* receivers. Note that this may raise TypeErrors
28        if the receivers do not allow the particular arguments.
29        Note also that arguments are applied before named
30        arguments, so they should be used with care.
31
32    named -- named arguments which will be filtered according
33        to the parameters of the receivers to only provide those
34        acceptable to the receiver.
35
36    Return a list of tuple pairs [(receiver, response), ... ]
37
38    if any receiver raises an error (specifically any subclass of Exception),
39    the error instance is returned as the result for that receiver.
40    """
41    # Call each receiver with whatever arguments it can accept.
42    # Return a list of tuple pairs [(receiver, response), ... ].
43    responses = []
44    for receiver in liveReceivers(getAllReceivers(sender, signal)):
45        try:
46            response = robustApply(
47                receiver,
48                signal=signal,
49                sender=sender,
50                *arguments,
51                **named
52            )
53        except Exception as err:
54            responses.append((receiver, err))
55        else:
56            responses.append((receiver, response))
57    return responses