GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( d4663b...83e50d )
by P.R.
02:57
created

EventController   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Test Coverage

Coverage 90.28%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 243
rs 9.8
ccs 65
cts 72
cp 0.9028
wmc 31

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 55 1
A event_queue_empty() 0 8 1
A event_loop_start() 0 8 1
A event_loop_end() 0 8 1
A internal_unregister_event_ref() 0 17 4
A internal_unregister_listener_object_ref() 0 15 3
C loop() 0 25 7
A internal_register_event() 0 10 1
A queue_size() 0 7 1
B _dispatch_event() 0 18 5
B internal_register_listener() 0 29 5
A internal_queue_event() 0 10 1
1
"""
2
Enarksh
3
4
Copyright 2013-2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8 1
import sys
9 1
import traceback
10
11 1
from enarksh.event.Event import Event
12 1
from enarksh.event.EventActor import EventActor
13
14
15 1
class EventController(EventActor):
16
    """
17
    A single threaded and a run-to-completion event controller. That is, each event is processed completely before any
18
    other event is processed. Hence, an event listener will run entirely before any other code runs (which can
19
    potentially modify the data the event listener invokes).
20
21
    Methods with name starting with 'internal_' MUST not be called from your application (only friend classes are
22
    allowed to call these methods).
23
    """
24
25
    # ------------------------------------------------------------------------------------------------------------------
26 1
    def __init__(self):
27
        """
28
        Object constructor.
29
        """
30 1
        Event.event_controller = self
31
32 1
        EventActor.__init__(self)
33
34 1
        self._events = dict()
35
        """
36
        All events in the current program.
37
38
        :type: dict[enarksh.event.Event.Event,dict[*,list[*]]]
39
        """
40
41 1
        self._listener_objects = dict()
42
        """
43
44
        :type: dict[*, set[enarksh.event.Event.Event]]
45
        """
46
47 1
        self._event_loop_start = Event(self)
48
        """
49
        Event that will be fired at the start of the event loop.
50
51
        :type: enarksh.event.Event.Event
52
        """
53
54 1
        self._event_loop_end = Event(self)
55
        """
56
        Event that will be fired at the end of the event loop.
57
58
        :type: enarksh.event.Event.Event
59
        """
60
61 1
        self._event_queue_empty = Event(self)
62
        """
63
        Event that will be fired when the event queue is empty.
64
65
        :type: enarksh.event.Event.Event
66
        """
67
68 1
        self.exit = False
69
        """
70
        If True the event loop terminates as soon as the event queue is emtpy. No event_queue_empty event will be fired.
71
72
        :type: bool
73
        """
74
75 1
        self._queue = []
76 1
        """
77
        The queue with events that have fired but have not been processed yet.
78
79
        :type: list[(enarksh.event.Event.Event,*)]
80
        """
81
82
    # ------------------------------------------------------------------------------------------------------------------
83 1
    @property
84
    def event_loop_end(self):
85
        """
86
        Returns the event that will be fired at the end of the event loop.
87
88
        :rtype: enarksh.event.Event.Event
89
        """
90 1
        return self._event_loop_end
91
92
    # ------------------------------------------------------------------------------------------------------------------
93 1
    @property
94
    def event_loop_start(self):
95
        """
96
        Returns the event that will be fired at the start of the event loop.
97
98
        :rtype: enarksh.event.Event.Event
99
        """
100 1
        return self._event_loop_start
101
102
    # ------------------------------------------------------------------------------------------------------------------
103 1
    @property
104
    def event_queue_empty(self):
105
        """
106
        Returns the event that will be fired when the event queue is empty.
107
108
        :rtype: enarksh.event.Event.Event
109
        """
110 1
        return self._event_queue_empty
111
112
    # ------------------------------------------------------------------------------------------------------------------
113 1
    def queue_size(self):
114
        """
115
        Returns the number of event on the event queue.
116
117
        :rtype: int
118
        """
119
        return len(self._queue)
120
121
    # ------------------------------------------------------------------------------------------------------------------
122 1
    def loop(self):
123
        """
124
        Start the event handler loop.
125
126
        The event handler loop terminates under each of the conditions below:
127
        * The event handler for 'event_queue_empty' completes without adding new events on the event queue.
128
        * Property exit has been set to True and the event queue is empty. Note: after property exit has been set to
129
          True event 'event_queue_empty' will not be fired any more.
130
        """
131 1
        self._dispatch_event(self._event_loop_start, None)
132
133 1
        if not self.exit and not self._queue:
134 1
            self._dispatch_event(self._event_queue_empty, None)
135
136 1
        while self._queue:
137 1
            event, event_data = self._queue.pop(0)
138
139 1
            self._dispatch_event(event, event_data)
140
141 1
            if not self._queue and not self.exit:
142 1
                self._dispatch_event(self._event_queue_empty, None)
143 1
                if not self._queue:
144 1
                    self.exit = True
145
146 1
        self._dispatch_event(self._event_loop_end, None)
147
148
    # ------------------------------------------------------------------------------------------------------------------
149 1
    def _dispatch_event(self, event, event_data):
150
        """
151
        Dispatches an event.
152
153
        :param enarksh.event.Event.Event event: The event to be dispatch.
154
        :param * event_data: Additional data supplied by the event source.
155
        """
156 1
        for listener_object, listeners in self._events[event.ref].items():
157 1
            for listener, listener_data in listeners:
158 1
                try:
159 1
                    if listener_object:
160 1
                        listener(listener_object(), event, event_data, listener_data)
161
                    else:
162
                        listener(event, event_data, listener_data)
163
                except Exception as exception:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
164
                    # @todo Improve logging.
165
                    print(exception, file=sys.stderr)
166
                    traceback.print_exc(file=sys.stderr)
167
168
    # ------------------------------------------------------------------------------------------------------------------
169 1
    def internal_queue_event(self, event, event_data):
170
        """
171
        Puts an event that has fired on the event queue.
172
173
        Note: Do not use this method directly. Use enarksh.event.Event.Event.fire() instead.
174
175
        :param enarksh.event.Event.Event event: The event that has fired.
176
        :param * event_data: Additional data supplied by the event source.
177
        """
178 1
        self._queue.append((event, event_data))
179
180
    # ------------------------------------------------------------------------------------------------------------------
181 1
    def internal_unregister_event_ref(self, event_ref):
182
        """
183
        Removes an event as an event in the current program.
184
185
        Note: Do not use this method directly. Use enarksh.event.EventActor.EventActor.destroy() instead.
186
187
        :param enarksh.event.Event.Event event_ref: The event that must be removed.
188
        """
189 1
        if event_ref in self._events:
190 1
            for listener_object in self._events[event_ref].keys():
191 1
                events = self._listener_objects[listener_object]
192 1
                events.remove(event_ref)
193
194 1
                if not events:
195 1
                    del self._listener_objects[listener_object]
196
197 1
            del self._events[event_ref]
198
199
    # ------------------------------------------------------------------------------------------------------------------
200 1
    def internal_unregister_listener_object_ref(self, listener_object_ref):
201
        """
202
        Removes an object as a listener object (i.e. an object with one or more methods registered as event listeners).
203
204
        Note: Do not use this method directly.
205
206
        :param enarksh.event.Listener.Listener listener_object_ref: The listener object.
207
        """
208 1
        if listener_object_ref in self._listener_objects:
209
            # Remove the object from all events.
210 1
            for event in self._listener_objects[listener_object_ref]:
211 1
                del self._events[event][listener_object_ref]
212
213
            # Remove the object as listener object.
214 1
            del self._listener_objects[listener_object_ref]
215
216
    # ------------------------------------------------------------------------------------------------------------------
217 1
    def internal_register_event(self, event):
218
        """
219
        Registers an event as an event in the current program.
220
221
        Note: Do not use this method directly. This method is automatically called by
222
        enarksh.event.Event.Event#__init__()
223
224
        :param enarksh.event.Event.Event event: The event that must be registered.
225
        """
226 1
        self._events[event.ref] = dict()
227
228
    # ------------------------------------------------------------------------------------------------------------------
229 1
    def internal_register_listener(self, event, listener, listener_data=None):
230
        """
231
        Registers a callable as a listener for an event.
232
233
        Note: Do not use this method directly. Use enarksh.event.Event.Event.register_listener() instead.
234
235
        :param enarksh.event.Event.Event event: The event for which the listener needs to notified.
236
        :param callable listener: The callable that must be called when the event fires. If the callable is a class
237
                                  method it object must be an instance of enarksh.event.EventActor.EventActor.
238
        :param listener_data: Additional data supplied by the listener. This data will be passed to the listener when
239
                              the event fires.
240
        """
241 1
        if hasattr(listener, '__self__'):
242 1
            if not isinstance(listener.__self__, EventActor):
243
                raise ValueError('Only an event actor can be a listener, got {0}'.format(listener.__self__))
244 1
            listener_object = listener.__self__.ref
245 1
            listener = listener.__func__
246
        else:
247
            listener_object = None
248
249
        # Register the event and the listener.
250 1
        if listener_object not in self._events[event.ref]:
251 1
            self._events[event.ref][listener_object] = list()
252 1
        self._events[event.ref][listener_object].append((listener, listener_data))
253
254
        # Register the listener's object as a listener object.
255 1
        if listener_object not in self._listener_objects:
256 1
            self._listener_objects[listener_object] = set()
257 1
        self._listener_objects[listener_object].add(event.ref)
258
259
# ----------------------------------------------------------------------------------------------------------------------
260