This file is indexed.

/usr/share/pyshared/tvtk/messenger.py is in mayavi2 4.1.0-1.

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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
"""
Implements a simple, robust, safe, Messenger class that allows one to
register callbacks for a signal/slot (or event/handler) kind of
messaging system.  One can basically register a callback
function/method to be called when an object sends a particular event.
The Messenger class is Borg.  So it is easy to instantiate and use.
This module is also reload-safe, so if the module is reloaded the
callback information is not lost.  Method callbacks do not have a
reference counting problem since weak references are used.

The main functionality of this module is provided by three functions,
`connect`, `disconnect` and `send`.

Here is example usage with VTK::

    >>> import messenger, vtk
    >>> def cb(obj, evt):
    ...  print obj.__class__.__name__, evt
    ...
    >>> o = vtk.vtkProperty()
    >>> o.AddObserver('ModifiedEvent', messenger.send)
    1
    >>> messenger.connect(o, 'ModifiedEvent', cb)
    >>>
    >>> o.SetRepresentation(1)
    vtkOpenGLProperty ModifiedEvent
    >>> messenger.connect(o, 'AnyEvent', cb)
    >>> o.SetRepresentation(2)
    vtkOpenGLProperty ModifiedEvent
    vtkOpenGLProperty ModifiedEvent
    >>>
    >>> messenger.send(o, 'foo')
    vtkOpenGLProperty foo
    >>> messenger.disconnect(o, 'AnyEvent')
    >>> messenger.send(o, 'foo')
    >>>

This approach is necessary if you don't want to be bitten by reference
cycles.  If you have a Python object holding a reference to a VTK
object and pass a method of the object to the AddObserver call, you
will get a reference cycle that cannot be collected by the garbage
collector.  Using this messenger module gets around the problem.

Also note that adding a connection for 'AnyEvent' will trigger a
callback no matter what event was generated.  The code above also
shows how disconnection works.

"""
# Author: Prabhu Ramachandran
# Copyright (c) 2004-2007, Enthought, Inc.
# License: BSD Style.

__all__ = ['Messenger', 'MessengerError',
           'connect', 'disconnect', 'send']

import types
import sys
import weakref


#################################################################
# This code makes the module reload-safe.
#################################################################
_saved = {}

for name in ['messenger', 'tvtk.messenger']:
    if sys.modules.has_key(name):
        mod = sys.modules[name]
        if hasattr(mod, 'Messenger'):
            _saved = mod.Messenger._shared_data
        del mod
        break


#################################################################
# `MessengerError` class for exceptions raised by Messenger.
#################################################################

class MessengerError(Exception):
    pass



#################################################################
# `Messenger` class.
#################################################################

class Messenger:

    """Implements a messenger class which deals with something like
    signals and slots.  Basically, an object can register a signal
    that it plans to emit.  Any other object can decide to handle that
    signal (of that particular object) by registering itself with the
    messenger.  When a signal is emitted the messenger calls all
    handlers.  This makes it totally easy to deal with communication
    between objects.  The class is Borg.  Rather than use this class,
    please use the 'connect' and 'disconnect' functions.

    """

    _shared_data = _saved

    def __init__(self):
        """Create the messenger.  This class is Borg.  So all
        instances are the same.

        """

        self.__dict__ = self._shared_data

        if not hasattr(self, '_signals'):
            # First instantiation.
            self._signals = {}
            self._catch_all = ['AnyEvent', 'all']

    #################################################################
    # 'Messenger' interface.
    #################################################################

    def connect(self, obj, event, callback):
        """ Registers a slot given an object and its signal to slot
        into and also given a bound method in `callback` that should
        have two arguments.  `send` will call the callback
        with the object that emitted the signal and the actual
        event/signal as arguments.

        Parameters
        ----------

        - obj :  Python object

          Any Python object that will generate the particular event.

        - event : An event (can be anything, usually strings)

          The event `obj` will generate.  If this is in the list
          `self._catch_all`, then any event will call this callback.

        - callback : `function` or `method`

          This callback will be called when the object generates the
          particular event.  The object, event and any other arguments
          and keyword arguments given by the `obj` are passed along to
          the callback.

        """
        typ = type(callback)
        key = hash(obj)
        if not self._signals.has_key(key):
            self._signals[key] = {}
        signals = self._signals[key]
        if not signals.has_key(event):
            signals[event] = {}

        slots = signals[event]

        callback_key = hash(callback)
        if typ is types.FunctionType:
            slots[callback_key] = (None, callback)
        elif typ is types.MethodType:
            obj = weakref.ref(callback.im_self)
            name = callback.__name__
            slots[callback_key] = (obj, name)
        else:
            raise MessengerError, \
                  "Callback must be a function or method. "\
                  "You passed a %s."%(str(callback))

    def disconnect(self, obj, event=None, callback=None, obj_is_hash=False):
        """Disconnects the object and its event handlers.

        Parameters
        ----------

        - obj : Object

          The object that generates events.

        - event : The event.  (defaults to None)

        - callback : `function` or `method`

          The event handler.

         If `event` and `callback` are None (the default) all the
         events and handlers for the object are removed.  If only
         `callback` is None, only this handler is removed.  If `obj`
         and 'event' alone are specified, all handlers for the event
         are removed.

        - obj_is_hash : `bool`

         Specifies if the object passed is a hash instead of the object itself.
         This is needed if the object is gc'd but only the hash exists and one
         wants to disconnect the object.

        """
        signals = self._signals
        if obj_is_hash:
            key = obj
        else:
            key = hash(obj)
        if not signals.has_key(key):
            return
        if callback is None:
            if event is None:
                del signals[key]
            else:
                del signals[key][event]
        else:
            del signals[key][event][hash(callback)]

    def send(self, source, event, *args, **kw_args):
        """To be called by the object `source` that desires to
        generate a particular event.  This function in turn invokes
        all the handlers for the event passing the `source` object,
        event and any additional arguments and keyword arguments.  If
        any connected callback is garbage collected without being
        disconnected, it is silently removed from the existing slots.

        Parameters
        ----------

        - source : Python object

          This is the object that generated the event.

        - event : The event.

          If there are handlers connected to events called 'AnyEvent'
          or 'all', then any event will invoke these.

        """
        try:
            sigs = self._get_signals(source)
        except (MessengerError, KeyError):
            return
        events = self._catch_all[:]
        if event not in events:
            events.append(event)
        for evt in events:
            if sigs.has_key(evt):
                slots = sigs[evt]
                for key in slots.keys():
                    obj, meth = slots[key]
                    if obj: # instance method
                        inst = obj()
                        if inst:
                            getattr(inst, meth)(source, event, *args, **kw_args)
                        else:
                            # Oops, dead reference.
                            del slots[key]
                    else: # normal function
                        meth(source, event, *args, **kw_args)

    def is_registered(self, obj):
        """Returns if the given object has registered itself with the
        messenger.

        """
        try:
            sigs = self._get_signals(obj)
        except MessengerError:
            return 0
        else:
            return 1

    def get_signal_names(self, obj):
        """Returns a list of signal names the object passed has
        registered.

        """
        return self._get_signals(obj).keys()

    #################################################################
    # Non-public interface.
    #################################################################

    def _get_signals(self, obj):
        """Given an object `obj` it returns the signals of that
        object.

        """
        ret = self._signals.get(hash(obj))
        if ret is None:
            raise MessengerError, \
                  "No such object: %s, has registered itself "\
                  "with the messenger."%obj
        else:
            return ret


#################################################################
# Convenience functions.
#################################################################

_messenger = Messenger()

def connect(obj, event, callback):
    _messenger.connect(obj, event, callback)
connect.__doc__ = _messenger.connect.__doc__

def disconnect(obj, event=None, callback=None, obj_is_hash=False):
    _messenger.disconnect(obj, event, callback)
disconnect.__doc__ = _messenger.disconnect.__doc__

def send(obj, event, *args, **kw_args):
    _messenger.send(obj, event, *args, **kw_args)
send.__doc__ = _messenger.send.__doc__

del _saved