This file is indexed.

/usr/share/pyshared/coherence/dispatcher.py is in python-coherence 0.6.6.2-8.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from twisted.internet import defer

class Receiver(object):
    def __init__(self, signal, callback, args, kwargs):
        self.signal = signal
        self.callback = callback
        self.arguments = args
        self.keywords = kwargs

    def __call__(self, *args, **kwargs):
        args = args + self.arguments

        kw = self.keywords.copy()
        if kwargs:
            kw.update(kwargs)
        return self.callback(*args, **kw)

    def __repr__(self):
        return "<Receiver %s for %s: %s (%s, %s)>" % (id(self),
                self.signal,
                self.callback,
                ', '.join(
                        ['%r' % x for x in self.arguments]
                        ),
                ', '.join(
                        ['%s=%s' % (x, y) for x, y in self.keywords.iteritems()]
                        )
                )

class UnknownSignal(Exception): pass

class Dispatcher(object):

    __signals__ = {}

    def __init__(self):
        self.receivers = {}
        for signal in self.__signals__.iterkeys():
            self.receivers[signal] = []

    def connect(self, signal, callback, *args, **kw):
        receiver = Receiver(signal, callback, args, kw)
        try:
            self.receivers[signal].append(receiver)
        except KeyError:
            raise UnknownSignal(signal)
        return receiver

    def disconnect(self, receiver):
        if not receiver:
            return

        try:
            self.receivers[receiver.signal].remove(receiver)
        except KeyError:
            raise UnknownSignal(receiver.signal)
        except AttributeError:
            raise TypeError("'%r' is not a Receiver-like object" % receiver)
        except ValueError:
            # receiver not in the list, goal achieved
            pass

    def emit(self, signal, *args, **kwargs):
        results = []
        errors = []
        for receiver in self._get_receivers(signal):
            try:
                results.append((receiver, receiver(*args, **kwargs)))
            except Exception, e:
                errors.append((receiver, e))

        return results, errors

    def deferred_emit(self, signal, *args, **kwargs):
        receivers = []
        dfrs = []
        # TODO: the loop is blocking, use callLaters and/or coiterate here
        for receiver in self._get_receivers(signal):
            receivers.append(receiver)
            dfrs.append(defer.maybeDeferred(receiver, *args, **kwargs))

        if not dfrs:
            return defer.succeed([])

        result_dfr = defer.DeferredList(dfrs)
        result_dfr.addCallback(self._merge_results_and_receivers, receivers)
        return result_dfr

    def save_emit(self, signal, *args, **kwargs):
        deferred = defer.Deferred()
        # run the deferred_emit in as a callback
        deferred.addCallback(self.deferred_emit, *args, **kwargs)
        # and callback the deferred with the signal as the 'result' in the
        # next mainloop iteration
        from twisted.internet import reactor
        reactor.callLater(0, deferred.callback, signal)
        return deferred

    def _merge_results_and_receivers(self, result, receivers):
        # make a list of (rec1, res1), (rec2, res2), (rec3, res3) ...
        return [(receiver, result[counter])
                for counter, receiver in enumerate(receivers)]

    def _get_receivers(self, signal):
        try:
            return self.receivers[signal]
        except KeyError:
            raise UnknownSignal(signal)


class SignalingProperty(object):
    """
    Does emit self.signal when the value has changed but only if HAS changed
    (means old_value != new_value).
    """

    def __init__(self, signal, var_name=None, default=None):
        self.signal = signal

        if var_name is None:
            var_name = "__%s__val" % signal

        self.var_name = var_name

        self.default = default

    def __get__(self, obj, objtype=None):
        return getattr(obj, self.var_name, self.default)

    def __set__(self, obj, value):
        if self.__get__(obj) == value:
            return
        setattr(obj, self.var_name, value)
        obj.emit(self.signal, value)

class ChangedSignalingProperty(SignalingProperty):
    """
    Does send the signal with two values when changed:
        1. the new value
        2. the value it has been before
    """
    def __set__(self, obj, value):
        before = self.__get__(obj)
        if before == value:
            return
        setattr(obj, self.var_name, value)
        obj.emit(self.signal, value, before)

class CustomSignalingProperty(object):
    """
    Signal changes to this property. allows to specify fget and fset as the
    build in property-decorator.
    """

    def __init__(self, signal, fget, fset, fdel=None, doc=None):
        """
        fdel is there for API compability only. As there is no good way to
        signal a deletion it is not implemented at all.
        """
        self.signal = signal
        self.fget = fget
        self.fset = fset
        self.__doc__ = doc

    def __get__(self, obj, objtype):
        return self.fget(obj)

    def __set__(self, obj, value):
        """
        Call fset with value. Call fget before and after to figure out if
        something actually changed. Only if something changed the signal is
        emitted.

        The signal will be emitted with the new value given by fget.

        *Note*: This means that fset might gets called with the same value twice
        while the signal is not emitted a second time. You might want to check
        for that in your fset.
        """

        old_value = self.fget(obj)
        self.fset(obj, value)
        new_value = self.fget(obj)

        if old_value == new_value:
            return

        obj.emit(self.signal, new_value)