Package lepl :: Package core :: Module monitor
[hide private]
[frames] | no frames]

Source Code for Module lepl.core.monitor

  1   
  2  # The contents of this file are subject to the Mozilla Public License 
  3  # (MPL) Version 1.1 (the "License"); you may not use this file except 
  4  # in compliance with the License. You may obtain a copy of the License 
  5  # at http://www.mozilla.org/MPL/ 
  6  # 
  7  # Software distributed under the License is distributed on an "AS IS" 
  8  # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
  9  # the License for the specific language governing rights and 
 10  # limitations under the License. 
 11  # 
 12  # The Original Code is LEPL (http://www.acooke.org/lepl) 
 13  # The Initial Developer of the Original Code is Andrew Cooke. 
 14  # Portions created by the Initial Developer are Copyright (C) 2009-2010 
 15  # Andrew Cooke (andrew@acooke.org). All Rights Reserved. 
 16  # 
 17  # Alternatively, the contents of this file may be used under the terms 
 18  # of the LGPL license (the GNU Lesser General Public License, 
 19  # http://www.gnu.org/licenses/lgpl.html), in which case the provisions 
 20  # of the LGPL License are applicable instead of those above. 
 21  # 
 22  # If you wish to allow use of your version of this file only under the 
 23  # terms of the LGPL License and not to allow others to use your version 
 24  # of this file under the MPL, indicate your decision by deleting the 
 25  # provisions above and replace them with the notice and other provisions 
 26  # required by the LGPL License.  If you do not delete the provisions 
 27  # above, a recipient may use your version of this file under either the 
 28  # MPL or the LGPL License. 
 29   
 30  ''' 
 31  Support for classes that monitor the execution process (for example, managing  
 32  resources and tracing program flow). 
 33   
 34  See `trampoline()`. 
 35  ''' 
 36   
 37   
38 -class ValueMonitor(object):
39 ''' 40 An interface expected by `trampoline()`, called to track data flow. 41 ''' 42
43 - def next_iteration(self, epoch, value, exception, stack):
44 ''' 45 Called at the start of each iteration. 46 ''' 47 pass
48
49 - def before_next(self, generator):
50 ''' 51 Called before invoking ``next`` on a generator. 52 ''' 53 pass
54
55 - def after_next(self, value):
56 ''' 57 Called after invoking ``next`` on a generator. 58 ''' 59 pass
60
61 - def before_throw(self, generator, value):
62 ''' 63 Called before invoking ``throw`` on a generator. 64 ''' 65 pass
66
67 - def after_throw(self, value):
68 ''' 69 Called after invoking ``throw`` on a generator. 70 ''' 71 pass
72
73 - def before_send(self, generator, value):
74 ''' 75 Called before invoking ``send`` on a generator. 76 ''' 77 pass
78
79 - def after_send(self, value):
80 ''' 81 Called after invoking ``send`` on a generator. 82 ''' 83 pass
84
85 - def exception(self, value):
86 ''' 87 Called when an exception is caught (instead of any 'after' method). 88 ''' 89 pass
90
91 - def raise_(self, value):
92 ''' 93 Called before raising an exception to the caller. 94 ''' 95 pass
96
97 - def yield_(self, value):
98 ''' 99 Called before yielding a value to the caller. 100 ''' 101 pass
102 103
104 -class StackMonitor(object):
105 ''' 106 An interface expected by `trampoline()`, called to track stack growth. 107 ''' 108
109 - def push(self, generator):
110 ''' 111 Called before adding a generator to the stack. 112 ''' 113 pass
114
115 - def pop(self, generator):
116 ''' 117 Called after removing a generator from the stack. 118 ''' 119 pass
120 121
122 -class ActiveMonitor(StackMonitor):
123 ''' 124 A `StackMonitor` implementation that allows matchers that implement the 125 interface on_push/on_pop to be called. 126 127 Generators can interact with active monitors if: 128 129 1. The monitor extends this class 130 131 2. The matcher has a monitor_class attribute whose value is equal to (or a 132 subclass of) the monitor class it will interact with 133 ''' 134
135 - def push(self, generator):
136 ''' 137 Called when a generator is pushed onto the trampoline stack. 138 ''' 139 if hasattr(generator.matcher, 'monitor_class') and \ 140 isinstance(self, generator.matcher.monitor_class): 141 generator.matcher.on_push(self)
142
143 - def pop(self, generator):
144 ''' 145 Called when a generator is popped from the trampoline stack. 146 ''' 147 if hasattr(generator.matcher, 'monitor_class') and \ 148 isinstance(self, generator.matcher.monitor_class): 149 generator.matcher.on_pop(self)
150 151
152 -class MultipleValueMonitors(ValueMonitor):
153 ''' 154 Combine several value monitors into one. 155 ''' 156
157 - def __init__(self, monitors=None):
158 super(MultipleValueMonitors, self).__init__() 159 self._monitors = [] if monitors is None else monitors
160
161 - def append(self, monitor):
162 ''' 163 Add another monitor to the chain. 164 ''' 165 self._monitors.append(monitor)
166
167 - def __len__(self):
168 return len(self._monitors)
169
170 - def next_iteration(self, epoch, value, exception, stack):
171 ''' 172 Called at the start of each iteration. 173 ''' 174 for monitor in self._monitors: 175 monitor.next_iteration(epoch, value, exception, stack)
176
177 - def before_next(self, generator):
178 ''' 179 Called before invoking ``next`` on a generator. 180 ''' 181 for monitor in self._monitors: 182 monitor.before_next(generator)
183
184 - def after_next(self, value):
185 ''' 186 Called after invoking ``next`` on a generator. 187 ''' 188 for monitor in self._monitors: 189 monitor.after_next(value)
190
191 - def before_throw(self, generator, value):
192 ''' 193 Called before invoking ``throw`` on a generator. 194 ''' 195 for monitor in self._monitors: 196 monitor.before_throw(generator, value)
197
198 - def after_throw(self, value):
199 ''' 200 Called after invoking ``throw`` on a generator. 201 ''' 202 for monitor in self._monitors: 203 monitor.after_throw(value)
204
205 - def before_send(self, generator, value):
206 ''' 207 Called before invoking ``send`` on a generator. 208 ''' 209 for monitor in self._monitors: 210 monitor.before_send(generator, value)
211
212 - def after_send(self, value):
213 ''' 214 Called after invoking ``send`` on a generator. 215 ''' 216 for monitor in self._monitors: 217 monitor.after_send(value)
218
219 - def exception(self, value):
220 ''' 221 Called when an exception is caught (instead of any 'after' method). 222 ''' 223 for monitor in self._monitors: 224 monitor.exception(value)
225
226 - def raise_(self, value):
227 ''' 228 Called before raising an exception to the caller. 229 ''' 230 for monitor in self._monitors: 231 monitor.raise_(value)
232
233 - def yield_(self, value):
234 ''' 235 Called before yielding a value to the caller. 236 ''' 237 for monitor in self._monitors: 238 monitor.yield_(value)
239 240
241 -class MultipleStackMonitors(StackMonitor):
242 ''' 243 Combine several stack monitors into one. 244 ''' 245
246 - def __init__(self, monitors=None):
247 super(MultipleStackMonitors, self).__init__() 248 self._monitors = [] if monitors is None else monitors
249
250 - def append(self, monitor):
251 ''' 252 Add another monitor to the chain. 253 ''' 254 self._monitors.append(monitor)
255
256 - def __len__(self):
257 return len(self._monitors)
258
259 - def push(self, value):
260 ''' 261 Called before adding a generator to the stack. 262 ''' 263 for monitor in self._monitors: 264 monitor.push(value)
265
266 - def pop(self, value):
267 ''' 268 Called after removing a generator from the stack. 269 ''' 270 for monitor in self._monitors: 271 monitor.pop(value)
272 273
274 -def prepare_monitors(monitor_factories):
275 ''' 276 Take a list of monitor factories and return an active and a passive 277 monitor (or None, if none given). 278 ''' 279 stack, value = MultipleStackMonitors(), MultipleValueMonitors() 280 monitor_factories = [] if monitor_factories is None else monitor_factories 281 for monitor_factory in monitor_factories: 282 monitor = monitor_factory() 283 if isinstance(monitor, StackMonitor): 284 stack.append(monitor) 285 if isinstance(monitor, ValueMonitor): 286 value.append(monitor) 287 return (stack if stack else None, value if value else None)
288