mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-10-31 07:04:17 +00:00 
			
		
		
		
	Initial commit of open source Workload Automation.
This commit is contained in:
		
							
								
								
									
										12
									
								
								wlauto/external/louie/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								wlauto/external/louie/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| This directory contains Louie package that has been modified by ARM Ltd. | ||||
| Original Louie package is licensed under BSD license. ARM Ltd. changes are | ||||
| licensed under Apache version 2 license. | ||||
|  | ||||
| Original Louie package may be found here: | ||||
|  | ||||
| https://pypi.python.org/pypi/Louie/1.1 | ||||
|  | ||||
| The text of the BSD License may be viewed here: | ||||
|  | ||||
| http://opensource.org/licenses/bsd-license.php | ||||
|  | ||||
							
								
								
									
										46
									
								
								wlauto/external/louie/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								wlauto/external/louie/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| __all__ = [ | ||||
|     'dispatcher', | ||||
|     'error', | ||||
|     'plugin', | ||||
|     'robustapply', | ||||
|     'saferef', | ||||
|     'sender', | ||||
|     'signal', | ||||
|     'version', | ||||
|      | ||||
|     'connect', | ||||
|     'disconnect', | ||||
|     'get_all_receivers', | ||||
|     'reset', | ||||
|     'send', | ||||
|     'send_exact', | ||||
|     'send_minimal', | ||||
|     'send_robust', | ||||
|  | ||||
|     'install_plugin', | ||||
|     'remove_plugin', | ||||
|     'Plugin', | ||||
|     'QtWidgetPlugin', | ||||
|     'TwistedDispatchPlugin', | ||||
|  | ||||
|     'Anonymous', | ||||
|     'Any', | ||||
|  | ||||
|     'All', | ||||
|     'Signal', | ||||
|     ] | ||||
|  | ||||
| import louie.dispatcher, louie.error, louie.plugin, louie.robustapply, \ | ||||
|        louie.saferef, louie.sender, louie.signal, louie.version | ||||
|  | ||||
| from louie.dispatcher import \ | ||||
|      connect, disconnect, get_all_receivers, reset, \ | ||||
|      send, send_exact, send_minimal, send_robust | ||||
|  | ||||
| from louie.plugin import \ | ||||
|      install_plugin, remove_plugin, Plugin, \ | ||||
|      QtWidgetPlugin, TwistedDispatchPlugin | ||||
|  | ||||
| from louie.sender import Anonymous, Any | ||||
|  | ||||
| from louie.signal import All, Signal | ||||
							
								
								
									
										591
									
								
								wlauto/external/louie/dispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										591
									
								
								wlauto/external/louie/dispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,591 @@ | ||||
| """Multiple-producer-multiple-consumer signal-dispatching. | ||||
|  | ||||
| ``dispatcher`` is the core of Louie, providing the primary API and the | ||||
| core logic for the system. | ||||
|  | ||||
| Internal attributes: | ||||
|  | ||||
| - ``WEAKREF_TYPES``: Tuple of types/classes which represent weak | ||||
|   references to receivers, and thus must be dereferenced on retrieval | ||||
|   to retrieve the callable object | ||||
|          | ||||
| - ``connections``:: | ||||
|  | ||||
|     { senderkey (id) : { signal : [receivers...] } } | ||||
|      | ||||
| - ``senders``: Used for cleaning up sender references on sender | ||||
|   deletion:: | ||||
|  | ||||
|     { senderkey (id) : weakref(sender) } | ||||
|      | ||||
| - ``senders_back``: Used for cleaning up receiver references on receiver | ||||
|   deletion:: | ||||
|  | ||||
|     { receiverkey (id) : [senderkey (id)...] } | ||||
| """ | ||||
|  | ||||
| import os | ||||
| import weakref | ||||
|  | ||||
| try: | ||||
|     set | ||||
| except NameError: | ||||
|     from sets import Set as set, ImmutableSet as frozenset | ||||
|  | ||||
| from louie import error | ||||
| from louie import robustapply | ||||
| from louie import saferef | ||||
| from louie.sender import Any, Anonymous | ||||
| from louie.signal import All | ||||
| from prioritylist import PriorityList | ||||
|  | ||||
|  | ||||
| # Support for statistics. | ||||
| if __debug__: | ||||
|     connects = 0 | ||||
|     disconnects = 0 | ||||
|     sends = 0 | ||||
|  | ||||
|     def print_stats(): | ||||
|         print ('\n' | ||||
|                'Louie connects: %i\n' | ||||
|                'Louie disconnects: %i\n' | ||||
|                'Louie sends: %i\n' | ||||
|                '\n') % (connects, disconnects, sends) | ||||
|  | ||||
|     if 'PYDISPATCH_STATS' in os.environ: | ||||
|         import atexit | ||||
|         atexit.register(print_stats) | ||||
|  | ||||
|  | ||||
|  | ||||
| WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref) | ||||
|  | ||||
|  | ||||
| connections = {} | ||||
| senders = {} | ||||
| senders_back = {} | ||||
| plugins = [] | ||||
|  | ||||
| def reset(): | ||||
|     """Reset the state of Louie. | ||||
|  | ||||
|     Useful during unit testing.  Should be avoided otherwise. | ||||
|     """ | ||||
|     global connections, senders, senders_back, plugins | ||||
|     connections = {} | ||||
|     senders = {} | ||||
|     senders_back = {} | ||||
|     plugins = [] | ||||
|  | ||||
|  | ||||
| def connect(receiver, signal=All, sender=Any, weak=True, priority=0): | ||||
|     """Connect ``receiver`` to ``sender`` for ``signal``. | ||||
|  | ||||
|     - ``receiver``: A callable Python object which is to receive | ||||
|       messages/signals/events.  Receivers must be hashable objects. | ||||
|  | ||||
|       If weak is ``True``, then receiver must be weak-referencable (more | ||||
|       precisely ``saferef.safe_ref()`` must be able to create a | ||||
|       reference to the receiver). | ||||
|      | ||||
|       Receivers are fairly flexible in their specification, as the | ||||
|       machinery in the ``robustapply`` module takes care of most of the | ||||
|       details regarding figuring out appropriate subsets of the sent | ||||
|       arguments to apply to a given receiver. | ||||
|  | ||||
|       Note: If ``receiver`` is itself a weak reference (a callable), it | ||||
|       will be de-referenced by the system's machinery, so *generally* | ||||
|       weak references are not suitable as receivers, though some use | ||||
|       might be found for the facility whereby a higher-level library | ||||
|       passes in pre-weakrefed receiver references. | ||||
|  | ||||
|     - ``signal``: The signal to which the receiver should respond. | ||||
|      | ||||
|       If ``All``, receiver will receive all signals from the indicated | ||||
|       sender (which might also be ``All``, but is not necessarily | ||||
|       ``All``). | ||||
|          | ||||
|       Otherwise must be a hashable Python object other than ``None`` | ||||
|       (``DispatcherError`` raised on ``None``). | ||||
|          | ||||
|     - ``sender``: The sender to which the receiver should respond. | ||||
|      | ||||
|       If ``Any``, receiver will receive the indicated signals from any | ||||
|       sender. | ||||
|          | ||||
|       If ``Anonymous``, receiver will only receive indicated signals | ||||
|       from ``send``/``send_exact`` which do not specify a sender, or | ||||
|       specify ``Anonymous`` explicitly as the sender. | ||||
|  | ||||
|       Otherwise can be any python object. | ||||
|          | ||||
|     - ``weak``: Whether to use weak references to the receiver. | ||||
|        | ||||
|       By default, the module will attempt to use weak references to | ||||
|       the receiver objects.  If this parameter is ``False``, then strong | ||||
|       references will be used. | ||||
|  | ||||
|     - ``priority``: specifies the priority by which a reciever should | ||||
|       get notified | ||||
|  | ||||
|     Returns ``None``, may raise ``DispatcherTypeError``. | ||||
|     """ | ||||
|     if signal is None: | ||||
|         raise error.DispatcherTypeError( | ||||
|             'Signal cannot be None (receiver=%r sender=%r)' | ||||
|             % (receiver, sender)) | ||||
|     if weak: | ||||
|         receiver = saferef.safe_ref(receiver, on_delete=_remove_receiver) | ||||
|     senderkey = id(sender) | ||||
|     if connections.has_key(senderkey): | ||||
|         signals = connections[senderkey] | ||||
|     else: | ||||
|         connections[senderkey] = signals = {} | ||||
|     # Keep track of senders for cleanup. | ||||
|     # Is Anonymous something we want to clean up? | ||||
|     if sender not in (None, Anonymous, Any): | ||||
|         def remove(object, senderkey=senderkey): | ||||
|             _remove_sender(senderkey=senderkey) | ||||
|         # Skip objects that can not be weakly referenced, which means | ||||
|         # they won't be automatically cleaned up, but that's too bad. | ||||
|         try: | ||||
|             weak_sender = weakref.ref(sender, remove) | ||||
|             senders[senderkey] = weak_sender | ||||
|         except: | ||||
|             pass | ||||
|     receiver_id = id(receiver) | ||||
|     # get current set, remove any current references to | ||||
|     # this receiver in the set, including back-references | ||||
|     if signals.has_key(signal): | ||||
|         receivers = signals[signal] | ||||
|         _remove_old_back_refs(senderkey, signal, receiver, receivers) | ||||
|     else: | ||||
|         receivers = signals[signal] = PriorityList() | ||||
|     try: | ||||
|         current = senders_back.get(receiver_id) | ||||
|         if current is None: | ||||
|             senders_back[receiver_id] = current = [] | ||||
|         if senderkey not in current: | ||||
|             current.append(senderkey) | ||||
|     except: | ||||
|         pass | ||||
|     receivers.add(receiver, priority) | ||||
|     # Update stats. | ||||
|     if __debug__: | ||||
|         global connects | ||||
|         connects += 1 | ||||
|  | ||||
|  | ||||
| def disconnect(receiver, signal=All, sender=Any, weak=True): | ||||
|     """Disconnect ``receiver`` from ``sender`` for ``signal``. | ||||
|  | ||||
|     - ``receiver``: The registered receiver to disconnect. | ||||
|      | ||||
|     - ``signal``: The registered signal to disconnect. | ||||
|      | ||||
|     - ``sender``: The registered sender to disconnect. | ||||
|      | ||||
|     - ``weak``: The weakref state to disconnect. | ||||
|  | ||||
|     ``disconnect`` reverses the process of ``connect``, the semantics for | ||||
|     the individual elements are logically equivalent to a tuple of | ||||
|     ``(receiver, signal, sender, weak)`` used as a key to be deleted | ||||
|     from the internal routing tables.  (The actual process is slightly | ||||
|     more complex but the semantics are basically the same). | ||||
|  | ||||
|     Note: Using ``disconnect`` is not required to cleanup routing when | ||||
|     an object is deleted; the framework will remove routes for deleted | ||||
|     objects automatically.  It's only necessary to disconnect if you | ||||
|     want to stop routing to a live object. | ||||
|          | ||||
|     Returns ``None``, may raise ``DispatcherTypeError`` or | ||||
|     ``DispatcherKeyError``. | ||||
|     """ | ||||
|     if signal is None: | ||||
|         raise error.DispatcherTypeError( | ||||
|             'Signal cannot be None (receiver=%r sender=%r)' | ||||
|             % (receiver, sender)) | ||||
|     if weak: | ||||
|         receiver = saferef.safe_ref(receiver) | ||||
|     senderkey = id(sender) | ||||
|     try: | ||||
|         signals = connections[senderkey] | ||||
|         receivers = signals[signal] | ||||
|     except KeyError: | ||||
|         raise error.DispatcherKeyError( | ||||
|             'No receivers found for signal %r from sender %r'  | ||||
|             % (signal, sender) | ||||
|             ) | ||||
|     try: | ||||
|         # also removes from receivers | ||||
|         _remove_old_back_refs(senderkey, signal, receiver, receivers) | ||||
|     except ValueError: | ||||
|         raise error.DispatcherKeyError( | ||||
|             'No connection to receiver %s for signal %s from sender %s' | ||||
|             % (receiver, signal, sender) | ||||
|             ) | ||||
|     _cleanup_connections(senderkey, signal) | ||||
|     # Update stats. | ||||
|     if __debug__: | ||||
|         global disconnects | ||||
|         disconnects += 1 | ||||
|  | ||||
|  | ||||
| def get_receivers(sender=Any, signal=All): | ||||
|     """Get list of receivers from global tables. | ||||
|  | ||||
|     This function allows you to retrieve the raw list of receivers | ||||
|     from the connections table for the given sender and signal pair. | ||||
|  | ||||
|     Note: There is no guarantee that this is the actual list stored in | ||||
|     the connections table, so the value should be treated as a simple | ||||
|     iterable/truth value rather than, for instance a list to which you | ||||
|     might append new records. | ||||
|  | ||||
|     Normally you would use ``live_receivers(get_receivers(...))`` to | ||||
|     retrieve the actual receiver objects as an iterable object. | ||||
|     """ | ||||
|     try: | ||||
|         return connections[id(sender)][signal] | ||||
|     except KeyError: | ||||
|         return [] | ||||
|  | ||||
|  | ||||
| def live_receivers(receivers): | ||||
|     """Filter sequence of receivers to get resolved, live receivers. | ||||
|  | ||||
|     This is a generator which will iterate over the passed sequence, | ||||
|     checking for weak references and resolving them, then returning | ||||
|     all live receivers. | ||||
|     """ | ||||
|     for receiver in receivers: | ||||
|         if isinstance(receiver, WEAKREF_TYPES): | ||||
|             # Dereference the weak reference. | ||||
|             receiver = receiver() | ||||
|         if receiver is not None: | ||||
|             # Check installed plugins to make sure this receiver is | ||||
|             # live. | ||||
|             live = True | ||||
|             for plugin in plugins: | ||||
|                 if not plugin.is_live(receiver): | ||||
|                     live = False | ||||
|                     break | ||||
|             if live: | ||||
|                 yield receiver | ||||
|              | ||||
|  | ||||
| def get_all_receivers(sender=Any, signal=All): | ||||
|     """Get list of all receivers from global tables. | ||||
|  | ||||
|     This gets all receivers which should receive the given signal from | ||||
|     sender, each receiver should be produced only once by the | ||||
|     resulting generator. | ||||
|     """ | ||||
|     yielded = set() | ||||
|     for receivers in ( | ||||
|         # Get receivers that receive *this* signal from *this* sender. | ||||
|         get_receivers(sender, signal), | ||||
|         # Add receivers that receive *all* signals from *this* sender. | ||||
|         get_receivers(sender, All), | ||||
|         # Add receivers that receive *this* signal from *any* sender. | ||||
|         get_receivers(Any, signal), | ||||
|         # Add receivers that receive *all* signals from *any* sender. | ||||
|         get_receivers(Any, All), | ||||
|         ): | ||||
|         for receiver in receivers: | ||||
|             if receiver: # filter out dead instance-method weakrefs | ||||
|                 try: | ||||
|                     if not receiver in yielded: | ||||
|                         yielded.add(receiver) | ||||
|                         yield receiver | ||||
|                 except TypeError: | ||||
|                     # dead weakrefs raise TypeError on hash... | ||||
|                     pass | ||||
|  | ||||
|  | ||||
| def send(signal=All, sender=Anonymous, *arguments, **named): | ||||
|     """Send ``signal`` from ``sender`` to all connected receivers. | ||||
|      | ||||
|     - ``signal``: (Hashable) signal value; see ``connect`` for details. | ||||
|  | ||||
|     - ``sender``: The sender of the signal. | ||||
|      | ||||
|       If ``Any``, only receivers registered for ``Any`` will receive the | ||||
|       message. | ||||
|  | ||||
|       If ``Anonymous``, only receivers registered to receive messages | ||||
|       from ``Anonymous`` or ``Any`` will receive the message. | ||||
|  | ||||
|       Otherwise can be any Python object (normally one registered with | ||||
|       a connect if you actually want something to occur). | ||||
|  | ||||
|     - ``arguments``: Positional arguments which will be passed to *all* | ||||
|       receivers. Note that this may raise ``TypeError`` if the receivers | ||||
|       do not allow the particular arguments.  Note also that arguments | ||||
|       are applied before named arguments, so they should be used with | ||||
|       care. | ||||
|  | ||||
|     - ``named``: Named arguments which will be filtered according to the | ||||
|       parameters of the receivers to only provide those acceptable to | ||||
|       the receiver. | ||||
|  | ||||
|     Return a list of tuple pairs ``[(receiver, response), ...]`` | ||||
|  | ||||
|     If any receiver raises an error, the error propagates back through | ||||
|     send, terminating the dispatch loop, so it is quite possible to | ||||
|     not have all receivers called if a raises an error. | ||||
|     """ | ||||
|     # Call each receiver with whatever arguments it can accept. | ||||
|     # Return a list of tuple pairs [(receiver, response), ... ]. | ||||
|     responses = [] | ||||
|     for receiver in live_receivers(get_all_receivers(sender, signal)): | ||||
|         # Wrap receiver using installed plugins. | ||||
|         original = receiver | ||||
|         for plugin in plugins: | ||||
|             receiver = plugin.wrap_receiver(receiver) | ||||
|         response = robustapply.robust_apply( | ||||
|             receiver, original, | ||||
|             signal=signal, | ||||
|             sender=sender, | ||||
|             *arguments, | ||||
|             **named | ||||
|             ) | ||||
|         responses.append((receiver, response)) | ||||
|     # Update stats. | ||||
|     if __debug__: | ||||
|         global sends | ||||
|         sends += 1 | ||||
|     return responses | ||||
|  | ||||
|  | ||||
| def send_minimal(signal=All, sender=Anonymous, *arguments, **named): | ||||
|     """Like ``send``, but does not attach ``signal`` and ``sender`` | ||||
|     arguments to the call to the receiver.""" | ||||
|     # Call each receiver with whatever arguments it can accept. | ||||
|     # Return a list of tuple pairs [(receiver, response), ... ]. | ||||
|     responses = [] | ||||
|     for receiver in live_receivers(get_all_receivers(sender, signal)): | ||||
|         # Wrap receiver using installed plugins. | ||||
|         original = receiver | ||||
|         for plugin in plugins: | ||||
|             receiver = plugin.wrap_receiver(receiver) | ||||
|         response = robustapply.robust_apply( | ||||
|             receiver, original, | ||||
|             *arguments, | ||||
|             **named | ||||
|             ) | ||||
|         responses.append((receiver, response)) | ||||
|     # Update stats. | ||||
|     if __debug__: | ||||
|         global sends | ||||
|         sends += 1 | ||||
|     return responses | ||||
|  | ||||
|  | ||||
| def send_exact(signal=All, sender=Anonymous, *arguments, **named): | ||||
|     """Send ``signal`` only to receivers registered for exact message. | ||||
|  | ||||
|     ``send_exact`` allows for avoiding ``Any``/``Anonymous`` registered | ||||
|     handlers, sending only to those receivers explicitly registered | ||||
|     for a particular signal on a particular sender. | ||||
|     """ | ||||
|     responses = [] | ||||
|     for receiver in live_receivers(get_receivers(sender, signal)): | ||||
|         # Wrap receiver using installed plugins. | ||||
|         original = receiver | ||||
|         for plugin in plugins: | ||||
|             receiver = plugin.wrap_receiver(receiver) | ||||
|         response = robustapply.robust_apply( | ||||
|             receiver, original, | ||||
|             signal=signal, | ||||
|             sender=sender, | ||||
|             *arguments, | ||||
|             **named | ||||
|             ) | ||||
|         responses.append((receiver, response)) | ||||
|     return responses | ||||
|      | ||||
|  | ||||
| def send_robust(signal=All, sender=Anonymous, *arguments, **named): | ||||
|     """Send ``signal`` from ``sender`` to all connected receivers catching | ||||
|     errors | ||||
|  | ||||
|     - ``signal``: (Hashable) signal value, see connect for details | ||||
|  | ||||
|     - ``sender``: The sender of the signal. | ||||
|      | ||||
|       If ``Any``, only receivers registered for ``Any`` will receive the | ||||
|       message. | ||||
|  | ||||
|       If ``Anonymous``, only receivers registered to receive messages | ||||
|       from ``Anonymous`` or ``Any`` will receive the message. | ||||
|  | ||||
|       Otherwise can be any Python object (normally one registered with | ||||
|       a connect if you actually want something to occur). | ||||
|  | ||||
|     - ``arguments``: Positional arguments which will be passed to *all* | ||||
|       receivers. Note that this may raise ``TypeError`` if the receivers | ||||
|       do not allow the particular arguments.  Note also that arguments | ||||
|       are applied before named arguments, so they should be used with | ||||
|       care. | ||||
|  | ||||
|     - ``named``: Named arguments which will be filtered according to the | ||||
|       parameters of the receivers to only provide those acceptable to | ||||
|       the receiver. | ||||
|  | ||||
|     Return a list of tuple pairs ``[(receiver, response), ... ]`` | ||||
|  | ||||
|     If any receiver raises an error (specifically, any subclass of | ||||
|     ``Exception``), the error instance is returned as the result for | ||||
|     that receiver. | ||||
|     """ | ||||
|     # Call each receiver with whatever arguments it can accept. | ||||
|     # Return a list of tuple pairs [(receiver, response), ... ]. | ||||
|     responses = [] | ||||
|     for receiver in live_receivers(get_all_receivers(sender, signal)): | ||||
|         original = receiver | ||||
|         for plugin in plugins: | ||||
|             receiver = plugin.wrap_receiver(receiver) | ||||
|         try: | ||||
|             response = robustapply.robust_apply( | ||||
|                 receiver, original, | ||||
|                 signal=signal, | ||||
|                 sender=sender, | ||||
|                 *arguments, | ||||
|                 **named | ||||
|                 ) | ||||
|         except Exception, err: | ||||
|             responses.append((receiver, err)) | ||||
|         else: | ||||
|             responses.append((receiver, response)) | ||||
|     return responses | ||||
|  | ||||
|  | ||||
| def _remove_receiver(receiver): | ||||
|     """Remove ``receiver`` from connections.""" | ||||
|     if not senders_back: | ||||
|         # During module cleanup the mapping will be replaced with None. | ||||
|         return False | ||||
|     backKey = id(receiver) | ||||
|     for senderkey in senders_back.get(backKey, ()): | ||||
|         try: | ||||
|             signals = connections[senderkey].keys() | ||||
|         except KeyError: | ||||
|             pass | ||||
|         else: | ||||
|             for signal in signals: | ||||
|                 try: | ||||
|                     receivers = connections[senderkey][signal] | ||||
|                 except KeyError: | ||||
|                     pass | ||||
|                 else: | ||||
|                     try: | ||||
|                         receivers.remove(receiver) | ||||
|                     except Exception: | ||||
|                         pass | ||||
|                 _cleanup_connections(senderkey, signal) | ||||
|     try: | ||||
|         del senders_back[backKey] | ||||
|     except KeyError: | ||||
|         pass | ||||
|  | ||||
|              | ||||
| def _cleanup_connections(senderkey, signal): | ||||
|     """Delete empty signals for ``senderkey``. Delete ``senderkey`` if | ||||
|     empty.""" | ||||
|     try: | ||||
|         receivers = connections[senderkey][signal] | ||||
|     except: | ||||
|         pass | ||||
|     else: | ||||
|         if not receivers: | ||||
|             # No more connected receivers. Therefore, remove the signal. | ||||
|             try: | ||||
|                 signals = connections[senderkey] | ||||
|             except KeyError: | ||||
|                 pass | ||||
|             else: | ||||
|                 del signals[signal] | ||||
|                 if not signals: | ||||
|                     # No more signal connections. Therefore, remove the sender. | ||||
|                     _remove_sender(senderkey) | ||||
|  | ||||
|  | ||||
| def _remove_sender(senderkey): | ||||
|     """Remove ``senderkey`` from connections.""" | ||||
|     _remove_back_refs(senderkey) | ||||
|     try: | ||||
|         del connections[senderkey] | ||||
|     except KeyError: | ||||
|         pass | ||||
|     # Senderkey will only be in senders dictionary if sender  | ||||
|     # could be weakly referenced. | ||||
|     try: | ||||
|         del senders[senderkey] | ||||
|     except: | ||||
|         pass | ||||
|  | ||||
|  | ||||
| def _remove_back_refs(senderkey): | ||||
|     """Remove all back-references to this ``senderkey``.""" | ||||
|     try: | ||||
|         signals = connections[senderkey] | ||||
|     except KeyError: | ||||
|         signals = None | ||||
|     else: | ||||
|         for signal, receivers in signals.iteritems(): | ||||
|             for receiver in receivers: | ||||
|                 _kill_back_ref(receiver, senderkey) | ||||
|  | ||||
|  | ||||
| def _remove_old_back_refs(senderkey, signal, receiver, receivers): | ||||
|     """Kill old ``senders_back`` references from ``receiver``. | ||||
|  | ||||
|     This guards against multiple registration of the same receiver for | ||||
|     a given signal and sender leaking memory as old back reference | ||||
|     records build up. | ||||
|  | ||||
|     Also removes old receiver instance from receivers. | ||||
|     """ | ||||
|     try: | ||||
|         index = receivers.index(receiver) | ||||
|         # need to scan back references here and remove senderkey | ||||
|     except ValueError: | ||||
|         return False | ||||
|     else: | ||||
|         old_receiver = receivers[index] | ||||
|         del receivers[index] | ||||
|         found = 0 | ||||
|         signals = connections.get(signal) | ||||
|         if signals is not None: | ||||
|             for sig, recs in connections.get(signal, {}).iteritems(): | ||||
|                 if sig != signal: | ||||
|                     for rec in recs: | ||||
|                         if rec is old_receiver: | ||||
|                             found = 1 | ||||
|                             break | ||||
|         if not found: | ||||
|             _kill_back_ref(old_receiver, senderkey) | ||||
|             return True | ||||
|         return False | ||||
|          | ||||
|          | ||||
| def _kill_back_ref(receiver, senderkey): | ||||
|     """Do actual removal of back reference from ``receiver`` to | ||||
|     ``senderkey``.""" | ||||
|     receiverkey = id(receiver) | ||||
|     senders = senders_back.get(receiverkey, ()) | ||||
|     while senderkey in senders: | ||||
|         try: | ||||
|             senders.remove(senderkey) | ||||
|         except: | ||||
|             break | ||||
|     if not senders: | ||||
|         try: | ||||
|             del senders_back[receiverkey] | ||||
|         except KeyError: | ||||
|             pass | ||||
|     return True | ||||
|  | ||||
|      | ||||
							
								
								
									
										22
									
								
								wlauto/external/louie/error.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								wlauto/external/louie/error.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| """Error types for Louie.""" | ||||
|  | ||||
|  | ||||
| class LouieError(Exception): | ||||
|     """Base class for all Louie errors""" | ||||
|  | ||||
|  | ||||
| class DispatcherError(LouieError): | ||||
|     """Base class for all Dispatcher errors""" | ||||
|      | ||||
|  | ||||
| class DispatcherKeyError(KeyError, DispatcherError): | ||||
|     """Error raised when unknown (sender, signal) specified""" | ||||
|      | ||||
|  | ||||
| class DispatcherTypeError(TypeError, DispatcherError): | ||||
|     """Error raised when inappropriate signal-type specified (None)""" | ||||
|  | ||||
|  | ||||
| class PluginTypeError(TypeError, LouieError): | ||||
|     """Error raise when trying to install more than one plugin of a | ||||
|     certain type.""" | ||||
							
								
								
									
										108
									
								
								wlauto/external/louie/plugin.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								wlauto/external/louie/plugin.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| """Common plugins for Louie.""" | ||||
|  | ||||
| from louie import dispatcher | ||||
| from louie import error | ||||
|  | ||||
|  | ||||
| def install_plugin(plugin): | ||||
|     cls = plugin.__class__ | ||||
|     for p in dispatcher.plugins: | ||||
|         if p.__class__ is cls: | ||||
|             raise error.PluginTypeError( | ||||
|                 'Plugin of type %r already installed.' % cls) | ||||
|     dispatcher.plugins.append(plugin) | ||||
|  | ||||
| def remove_plugin(plugin): | ||||
|     dispatcher.plugins.remove(plugin) | ||||
|  | ||||
|  | ||||
| class Plugin(object): | ||||
|     """Base class for Louie plugins. | ||||
|  | ||||
|     Plugins are used to extend or alter the behavior of Louie | ||||
|     in a uniform way without having to modify the Louie code | ||||
|     itself. | ||||
|     """ | ||||
|  | ||||
|     def is_live(self, receiver): | ||||
|         """Return True if the receiver is still live. | ||||
|  | ||||
|         Only called for receivers who have already been determined to | ||||
|         be live by default Louie semantics. | ||||
|         """ | ||||
|         return True | ||||
|  | ||||
|     def wrap_receiver(self, receiver): | ||||
|         """Return a callable that passes arguments to the receiver. | ||||
|  | ||||
|         Useful when you want to change the behavior of all receivers. | ||||
|         """ | ||||
|         return receiver | ||||
|  | ||||
|  | ||||
| class QtWidgetPlugin(Plugin): | ||||
|     """A Plugin for Louie that knows how to handle Qt widgets | ||||
|     when using PyQt built with SIP 4 or higher. | ||||
|  | ||||
|     Weak references are not useful when dealing with QWidget | ||||
|     instances, because even after a QWidget is closed and destroyed, | ||||
|     only the C++ object is destroyed.  The Python 'shell' object | ||||
|     remains, but raises a RuntimeError when an attempt is made to call | ||||
|     an underlying QWidget method. | ||||
|  | ||||
|     This plugin alleviates this behavior, and if a QWidget instance is | ||||
|     found that is just an empty shell, it prevents Louie from | ||||
|     dispatching to any methods on those objects. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         try: | ||||
|             import qt | ||||
|         except ImportError: | ||||
|             self.is_live = self._is_live_no_qt | ||||
|         else: | ||||
|             self.qt = qt | ||||
|  | ||||
|     def is_live(self, receiver): | ||||
|         """If receiver is a method on a QWidget, only return True if | ||||
|         it hasn't been destroyed.""" | ||||
|         if (hasattr(receiver, 'im_self') and | ||||
|             isinstance(receiver.im_self, self.qt.QWidget) | ||||
|             ): | ||||
|             try: | ||||
|                 receiver.im_self.x() | ||||
|             except RuntimeError: | ||||
|                 return False | ||||
|         return True | ||||
|  | ||||
|     def _is_live_no_qt(self, receiver): | ||||
|         return True | ||||
|  | ||||
|  | ||||
| class TwistedDispatchPlugin(Plugin): | ||||
|     """Plugin for Louie that wraps all receivers in callables | ||||
|     that return Twisted Deferred objects. | ||||
|  | ||||
|     When the wrapped receiver is called, it adds a call to the actual | ||||
|     receiver to the reactor event loop, and returns a Deferred that is | ||||
|     called back with the result. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         # Don't import reactor ourselves, but make access to it | ||||
|         # easier. | ||||
|         from twisted import internet | ||||
|         from twisted.internet.defer import Deferred | ||||
|         self._internet = internet | ||||
|         self._Deferred = Deferred | ||||
|  | ||||
|     def wrap_receiver(self, receiver): | ||||
|         def wrapper(*args, **kw): | ||||
|             d = self._Deferred() | ||||
|             def called(dummy): | ||||
|                 return receiver(*args, **kw) | ||||
|             d.addCallback(called) | ||||
|             self._internet.reactor.callLater(0, d.callback, None) | ||||
|             return d | ||||
|         return wrapper | ||||
|  | ||||
							
								
								
									
										128
									
								
								wlauto/external/louie/prioritylist.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								wlauto/external/louie/prioritylist.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| """OrderedList class | ||||
|  | ||||
| This class keeps its elements ordered according to their priority. | ||||
| """ | ||||
| from collections import defaultdict | ||||
| import numbers | ||||
| from bisect import insort | ||||
|  | ||||
| class PriorityList(object): | ||||
|  | ||||
|     def __init__(self): | ||||
|         """ | ||||
|         Returns an OrderedReceivers object that externaly behaves | ||||
|         like a list but it maintains the order of its elements | ||||
|         according to their priority. | ||||
|         """ | ||||
|         self.elements = defaultdict(list) | ||||
|         self.is_ordered = True | ||||
|         self.priorities = [] | ||||
|         self.size = 0 | ||||
|         self._cached_elements = None | ||||
|  | ||||
|     def __del__(self): | ||||
|         pass | ||||
|  | ||||
|     def __iter__(self): | ||||
|         """ | ||||
|         this method makes PriorityList class iterable | ||||
|         """ | ||||
|         self._order_elements() | ||||
|         for priority in reversed(self.priorities):  # highest priority first | ||||
|             for element in self.elements[priority]: | ||||
|                 yield element | ||||
|  | ||||
|     def __getitem__(self, index): | ||||
|         self._order_elements() | ||||
|         return self._to_list()[index] | ||||
|  | ||||
|     def __delitem__(self, index): | ||||
|         self._order_elements() | ||||
|         if isinstance(index, numbers.Integral): | ||||
|             index = int(index) | ||||
|             if index < 0: | ||||
|                 index_range = [len(self)+index] | ||||
|             else: | ||||
|                 index_range = [index] | ||||
|         elif isinstance(index, slice): | ||||
|             index_range = range(index.start or 0, index.stop, index.step or 1) | ||||
|         else: | ||||
|             raise ValueError('Invalid index {}'.format(index)) | ||||
|         current_global_offset = 0 | ||||
|         priority_counts = {priority : count for (priority, count) in | ||||
|                            zip(self.priorities, [len(self.elements[p]) for p in self.priorities])} | ||||
|         for priority in self.priorities: | ||||
|             if not index_range: | ||||
|                 break | ||||
|             priority_offset = 0 | ||||
|             while index_range: | ||||
|                 del_index = index_range[0] | ||||
|                 if priority_counts[priority] + current_global_offset <= del_index: | ||||
|                     current_global_offset += priority_counts[priority] | ||||
|                     break | ||||
|                 within_priority_index = del_index - (current_global_offset + priority_offset) | ||||
|                 self._delete(priority, within_priority_index) | ||||
|                 priority_offset += 1 | ||||
|                 index_range.pop(0) | ||||
|  | ||||
|     def __len__(self): | ||||
|         return self.size | ||||
|  | ||||
|     def add(self, new_element, priority=0, force_ordering=True): | ||||
|         """ | ||||
|         adds a new item in the list. | ||||
|  | ||||
|         - ``new_element`` the element to be inserted in the PriorityList | ||||
|         - ``priority`` is the priority of the element which specifies its | ||||
|         order withing the List | ||||
|         - ``force_ordering`` indicates whether elements should be ordered | ||||
|         right now. If set to False, ordering happens on demand (lazy) | ||||
|         """ | ||||
|         self._add_element(new_element, priority) | ||||
|         if priority not in self.priorities: | ||||
|             self._add_priority(priority, force_ordering) | ||||
|  | ||||
|     def index(self, element): | ||||
|         return self._to_list().index(element) | ||||
|  | ||||
|     def remove(self, element): | ||||
|         index = self.index(element) | ||||
|         self.__delitem__(index) | ||||
|  | ||||
|     def _order_elements(self): | ||||
|         if not self.is_ordered: | ||||
|             self.priorities = sorted(self.priorities) | ||||
|         self.is_ordered = True | ||||
|  | ||||
|     def _to_list(self): | ||||
|         if self._cached_elements == None: | ||||
|             self._order_elements() | ||||
|             self._cached_elements = [] | ||||
|             for priority in self.priorities: | ||||
|                 self._cached_elements += self.elements[priority] | ||||
|         return self._cached_elements | ||||
|  | ||||
|     def _add_element(self, element, priority): | ||||
|         self.elements[priority].append(element) | ||||
|         self.size += 1 | ||||
|         self._cached_elements = None | ||||
|  | ||||
|     def _delete(self, priority, priority_index): | ||||
|         del self.elements[priority][priority_index] | ||||
|         self.size -= 1 | ||||
|         if len(self.elements[priority]) == 0: | ||||
|             self.priorities.remove(priority) | ||||
|         self._cached_elements = None | ||||
|  | ||||
|     def _add_priority(self, priority, force_ordering): | ||||
|         if force_ordering and self.is_ordered: | ||||
|             insort(self.priorities, priority) | ||||
|         elif not force_ordering: | ||||
|             self.priorities.append(priority) | ||||
|             self.is_ordered = False | ||||
|         elif not self.is_ordered: | ||||
|             self.priorities.append(priority) | ||||
|             self._order_elements() | ||||
|         else: | ||||
|             raise AssertionError('Should never get here.') | ||||
|  | ||||
							
								
								
									
										58
									
								
								wlauto/external/louie/robustapply.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								wlauto/external/louie/robustapply.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| """Robust apply mechanism. | ||||
|  | ||||
| Provides a function 'call', which can sort out what arguments a given | ||||
| callable object can take, and subset the given arguments to match only | ||||
| those which are acceptable. | ||||
| """ | ||||
|  | ||||
| def function(receiver): | ||||
|     """Get function-like callable object for given receiver. | ||||
|  | ||||
|     returns (function_or_method, codeObject, fromMethod) | ||||
|  | ||||
|     If fromMethod is true, then the callable already has its first | ||||
|     argument bound. | ||||
|     """ | ||||
|     if hasattr(receiver, '__call__'): | ||||
|         # receiver is a class instance; assume it is callable. | ||||
|         # Reassign receiver to the actual method that will be called. | ||||
|         c = receiver.__call__ | ||||
|         if hasattr(c, 'im_func') or hasattr(c, 'im_code'): | ||||
|             receiver = c | ||||
|     if hasattr(receiver, 'im_func'): | ||||
|         # receiver is an instance-method. | ||||
|         return receiver, receiver.im_func.func_code, 1 | ||||
|     elif not hasattr(receiver, 'func_code'): | ||||
|         raise ValueError( | ||||
|             'unknown reciever type %s %s' % (receiver, type(receiver))) | ||||
|     return receiver, receiver.func_code, 0 | ||||
|  | ||||
|  | ||||
| def robust_apply(receiver, signature, *arguments, **named): | ||||
|     """Call receiver with arguments and appropriate subset of named. | ||||
|     ``signature`` is the callable used to determine the call signature | ||||
|     of the receiver, in case ``receiver`` is a callable wrapper of the | ||||
|     actual receiver.""" | ||||
|     signature, code_object, startIndex = function(signature) | ||||
|     acceptable = code_object.co_varnames[ | ||||
|         startIndex + len(arguments): | ||||
|         code_object.co_argcount | ||||
|         ] | ||||
|     for name in code_object.co_varnames[ | ||||
|         startIndex:startIndex + len(arguments) | ||||
|         ]: | ||||
|         if named.has_key(name): | ||||
|             raise TypeError( | ||||
|                 'Argument %r specified both positionally ' | ||||
|                 'and as a keyword for calling %r' | ||||
|                 % (name, signature) | ||||
|                 ) | ||||
|     if not (code_object.co_flags & 8): | ||||
|         # fc does not have a **kwds type parameter, therefore  | ||||
|         # remove unacceptable arguments. | ||||
|         for arg in named.keys(): | ||||
|             if arg not in acceptable: | ||||
|                 del named[arg] | ||||
|     return receiver(*arguments, **named) | ||||
|  | ||||
|              | ||||
							
								
								
									
										179
									
								
								wlauto/external/louie/saferef.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								wlauto/external/louie/saferef.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| """Refactored 'safe reference from dispatcher.py""" | ||||
|  | ||||
| import weakref | ||||
| import traceback | ||||
|  | ||||
|  | ||||
| def safe_ref(target, on_delete=None): | ||||
|     """Return a *safe* weak reference to a callable target. | ||||
|  | ||||
|     - ``target``: The object to be weakly referenced, if it's a bound | ||||
|       method reference, will create a BoundMethodWeakref, otherwise | ||||
|       creates a simple weakref. | ||||
|          | ||||
|     - ``on_delete``: If provided, will have a hard reference stored to | ||||
|       the callable to be called after the safe reference goes out of | ||||
|       scope with the reference object, (either a weakref or a | ||||
|       BoundMethodWeakref) as argument. | ||||
|     """ | ||||
|     if hasattr(target, 'im_self'): | ||||
|         if target.im_self is not None: | ||||
|             # Turn a bound method into a BoundMethodWeakref instance. | ||||
|             # Keep track of these instances for lookup by disconnect(). | ||||
|             assert hasattr(target, 'im_func'), ( | ||||
|                 "safe_ref target %r has im_self, but no im_func, " | ||||
|                 "don't know how to create reference" | ||||
|                 % target | ||||
|                 ) | ||||
|             reference = BoundMethodWeakref(target=target, on_delete=on_delete) | ||||
|             return reference | ||||
|     if callable(on_delete): | ||||
|         return weakref.ref(target, on_delete) | ||||
|     else: | ||||
|         return weakref.ref(target) | ||||
|      | ||||
|  | ||||
| class BoundMethodWeakref(object): | ||||
|     """'Safe' and reusable weak references to instance methods. | ||||
|  | ||||
|     BoundMethodWeakref objects provide a mechanism for referencing a | ||||
|     bound method without requiring that the method object itself | ||||
|     (which is normally a transient object) is kept alive.  Instead, | ||||
|     the BoundMethodWeakref object keeps weak references to both the | ||||
|     object and the function which together define the instance method. | ||||
|  | ||||
|     Attributes: | ||||
|      | ||||
|     - ``key``: The identity key for the reference, calculated by the | ||||
|       class's calculate_key method applied to the target instance method. | ||||
|  | ||||
|     - ``deletion_methods``: Sequence of callable objects taking single | ||||
|       argument, a reference to this object which will be called when | ||||
|       *either* the target object or target function is garbage | ||||
|       collected (i.e. when this object becomes invalid).  These are | ||||
|       specified as the on_delete parameters of safe_ref calls. | ||||
|  | ||||
|     - ``weak_self``: Weak reference to the target object. | ||||
|  | ||||
|     - ``weak_func``: Weak reference to the target function. | ||||
|  | ||||
|     Class Attributes: | ||||
|          | ||||
|     - ``_all_instances``: Class attribute pointing to all live | ||||
|       BoundMethodWeakref objects indexed by the class's | ||||
|       calculate_key(target) method applied to the target objects. | ||||
|       This weak value dictionary is used to short-circuit creation so | ||||
|       that multiple references to the same (object, function) pair | ||||
|       produce the same BoundMethodWeakref instance. | ||||
|     """ | ||||
|      | ||||
|     _all_instances = weakref.WeakValueDictionary() | ||||
|      | ||||
|     def __new__(cls, target, on_delete=None, *arguments, **named): | ||||
|         """Create new instance or return current instance. | ||||
|  | ||||
|         Basically this method of construction allows us to | ||||
|         short-circuit creation of references to already- referenced | ||||
|         instance methods.  The key corresponding to the target is | ||||
|         calculated, and if there is already an existing reference, | ||||
|         that is returned, with its deletion_methods attribute updated. | ||||
|         Otherwise the new instance is created and registered in the | ||||
|         table of already-referenced methods. | ||||
|         """ | ||||
|         key = cls.calculate_key(target) | ||||
|         current = cls._all_instances.get(key) | ||||
|         if current is not None: | ||||
|             current.deletion_methods.append(on_delete) | ||||
|             return current | ||||
|         else: | ||||
|             base = super(BoundMethodWeakref, cls).__new__(cls) | ||||
|             cls._all_instances[key] = base | ||||
|             base.__init__(target, on_delete, *arguments, **named) | ||||
|             return base | ||||
|  | ||||
|     def __init__(self, target, on_delete=None): | ||||
|         """Return a weak-reference-like instance for a bound method. | ||||
|  | ||||
|         - ``target``: The instance-method target for the weak reference, | ||||
|           must have im_self and im_func attributes and be | ||||
|           reconstructable via the following, which is true of built-in | ||||
|           instance methods:: | ||||
|              | ||||
|             target.im_func.__get__( target.im_self ) | ||||
|  | ||||
|         - ``on_delete``: Optional callback which will be called when | ||||
|           this weak reference ceases to be valid (i.e. either the | ||||
|           object or the function is garbage collected).  Should take a | ||||
|           single argument, which will be passed a pointer to this | ||||
|           object. | ||||
|         """ | ||||
|         def remove(weak, self=self): | ||||
|             """Set self.isDead to True when method or instance is destroyed.""" | ||||
|             methods = self.deletion_methods[:] | ||||
|             del self.deletion_methods[:] | ||||
|             try: | ||||
|                 del self.__class__._all_instances[self.key] | ||||
|             except KeyError: | ||||
|                 pass | ||||
|             for function in methods: | ||||
|                 try: | ||||
|                     if callable(function): | ||||
|                         function(self) | ||||
|                 except Exception: | ||||
|                     try: | ||||
|                         traceback.print_exc() | ||||
|                     except AttributeError, e: | ||||
|                         print ('Exception during saferef %s ' | ||||
|                                'cleanup function %s: %s' % (self, function, e)) | ||||
|         self.deletion_methods = [on_delete] | ||||
|         self.key = self.calculate_key(target) | ||||
|         self.weak_self = weakref.ref(target.im_self, remove) | ||||
|         self.weak_func = weakref.ref(target.im_func, remove) | ||||
|         self.self_name = str(target.im_self) | ||||
|         self.func_name = str(target.im_func.__name__) | ||||
|          | ||||
|     def calculate_key(cls, target): | ||||
|         """Calculate the reference key for this reference. | ||||
|  | ||||
|         Currently this is a two-tuple of the id()'s of the target | ||||
|         object and the target function respectively. | ||||
|         """ | ||||
|         return (id(target.im_self), id(target.im_func)) | ||||
|     calculate_key = classmethod(calculate_key) | ||||
|      | ||||
|     def __str__(self): | ||||
|         """Give a friendly representation of the object.""" | ||||
|         return "%s(%s.%s)" % ( | ||||
|             self.__class__.__name__, | ||||
|             self.self_name, | ||||
|             self.func_name, | ||||
|             ) | ||||
|      | ||||
|     __repr__ = __str__ | ||||
|      | ||||
|     def __nonzero__(self): | ||||
|         """Whether we are still a valid reference.""" | ||||
|         return self() is not None | ||||
|  | ||||
|     def __cmp__(self, other): | ||||
|         """Compare with another reference.""" | ||||
|         if not isinstance(other, self.__class__): | ||||
|             return cmp(self.__class__, type(other)) | ||||
|         return cmp(self.key, other.key) | ||||
|  | ||||
|     def __call__(self): | ||||
|         """Return a strong reference to the bound method. | ||||
|  | ||||
|         If the target cannot be retrieved, then will return None, | ||||
|         otherwise returns a bound instance method for our object and | ||||
|         function. | ||||
|  | ||||
|         Note: You may call this method any number of times, as it does | ||||
|         not invalidate the reference. | ||||
|         """ | ||||
|         target = self.weak_self() | ||||
|         if target is not None: | ||||
|             function = self.weak_func() | ||||
|             if function is not None: | ||||
|                 return function.__get__(target) | ||||
|         return None | ||||
							
								
								
									
										39
									
								
								wlauto/external/louie/sender.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								wlauto/external/louie/sender.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| """Sender classes.""" | ||||
|  | ||||
|  | ||||
| class _SENDER(type): | ||||
|     """Base metaclass for sender classes.""" | ||||
|  | ||||
|     def __str__(cls): | ||||
|         return '<Sender: %s>' % (cls.__name__, ) | ||||
|  | ||||
|  | ||||
| class Any(object): | ||||
|     """Used to represent either 'any sender'. | ||||
|  | ||||
|     The Any class can be used with connect, disconnect, send, or | ||||
|     sendExact to denote that the sender paramater should react to any | ||||
|     sender, not just a particular sender. | ||||
|     """ | ||||
|  | ||||
|     __metaclass__ = _SENDER | ||||
|  | ||||
|  | ||||
| class Anonymous(object): | ||||
|     """Singleton used to signal 'anonymous sender'. | ||||
|  | ||||
|     The Anonymous class is used to signal that the sender of a message | ||||
|     is not specified (as distinct from being 'any sender'). | ||||
|     Registering callbacks for Anonymous will only receive messages | ||||
|     sent without senders.  Sending with anonymous will only send | ||||
|     messages to those receivers registered for Any or Anonymous. | ||||
|  | ||||
|     Note: The default sender for connect is Any, while the default | ||||
|     sender for send is Anonymous.  This has the effect that if you do | ||||
|     not specify any senders in either function then all messages are | ||||
|     routed as though there was a single sender (Anonymous) being used | ||||
|     everywhere. | ||||
|     """ | ||||
|  | ||||
|     __metaclass__ = _SENDER | ||||
|  | ||||
							
								
								
									
										30
									
								
								wlauto/external/louie/signal.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								wlauto/external/louie/signal.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| """Signal class. | ||||
|  | ||||
| This class is provided as a way to consistently define and document | ||||
| signal types.  Signal classes also have a useful string | ||||
| representation. | ||||
|  | ||||
| Louie does not require you to use a subclass of Signal for signals. | ||||
| """ | ||||
|  | ||||
|  | ||||
| class _SIGNAL(type): | ||||
|     """Base metaclass for signal classes.""" | ||||
|  | ||||
|     def __str__(cls): | ||||
|         return '<Signal: %s>' % (cls.__name__, ) | ||||
|  | ||||
|  | ||||
| class Signal(object): | ||||
|  | ||||
|     __metaclass__ = _SIGNAL | ||||
|  | ||||
|  | ||||
| class All(Signal): | ||||
|     """Used to represent 'all signals'. | ||||
|  | ||||
|     The All class can be used with connect, disconnect, send, or | ||||
|     sendExact to denote that the signal should react to all signals, | ||||
|     not just a particular signal. | ||||
|     """ | ||||
|  | ||||
							
								
								
									
										0
									
								
								wlauto/external/louie/test/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								wlauto/external/louie/test/__init__.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										5
									
								
								wlauto/external/louie/test/conftest.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								wlauto/external/louie/test/conftest.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| import sys | ||||
| import os | ||||
|  | ||||
| sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) | ||||
|  | ||||
							
								
								
									
										0
									
								
								wlauto/external/louie/test/fixture.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								wlauto/external/louie/test/fixture.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										154
									
								
								wlauto/external/louie/test/test_dispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								wlauto/external/louie/test/test_dispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| import unittest | ||||
|  | ||||
| import louie | ||||
| from louie import dispatcher | ||||
|  | ||||
|  | ||||
| def x(a): | ||||
|     return a | ||||
|  | ||||
|  | ||||
| class Dummy(object): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class Callable(object): | ||||
|  | ||||
|     def __call__(self, a): | ||||
|         return a | ||||
|  | ||||
|     def a(self, a): | ||||
|         return a | ||||
|  | ||||
|  | ||||
| class TestDispatcher(unittest.TestCase): | ||||
|  | ||||
|     def setUp(self): | ||||
|         louie.reset() | ||||
|  | ||||
|     def _isclean(self): | ||||
|         """Assert that everything has been cleaned up automatically""" | ||||
|         assert len(dispatcher.senders_back) == 0, dispatcher.senders_back | ||||
|         assert len(dispatcher.connections) == 0, dispatcher.connections | ||||
|         assert len(dispatcher.senders) == 0, dispatcher.senders | ||||
|      | ||||
|     def test_Exact(self): | ||||
|         a = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(x, signal, a) | ||||
|         expected = [(x, a)] | ||||
|         result = louie.send('this', a, a=a) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         louie.disconnect(x, signal, a) | ||||
|         assert len(list(louie.get_all_receivers(a, signal))) == 0 | ||||
|         self._isclean() | ||||
|          | ||||
|     def test_AnonymousSend(self): | ||||
|         a = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(x, signal) | ||||
|         expected = [(x, a)] | ||||
|         result = louie.send(signal, None, a=a) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         louie.disconnect(x, signal) | ||||
|         assert len(list(louie.get_all_receivers(None, signal))) == 0 | ||||
|         self._isclean() | ||||
|          | ||||
|     def test_AnyRegistration(self): | ||||
|         a = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(x, signal, louie.Any) | ||||
|         expected = [(x, a)] | ||||
|         result = louie.send('this', object(), a=a) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         louie.disconnect(x, signal, louie.Any) | ||||
|         expected = [] | ||||
|         result = louie.send('this', object(), a=a) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         assert len(list(louie.get_all_receivers(louie.Any, signal))) == 0 | ||||
|         self._isclean() | ||||
|          | ||||
|     def test_AllRegistration(self): | ||||
|         a = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(x, louie.All, a) | ||||
|         expected = [(x, a)] | ||||
|         result = louie.send('this', a, a=a) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         louie.disconnect(x, louie.All, a) | ||||
|         assert len(list(louie.get_all_receivers(a, louie.All))) == 0 | ||||
|         self._isclean() | ||||
|          | ||||
|     def test_GarbageCollected(self): | ||||
|         a = Callable() | ||||
|         b = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(a.a, signal, b) | ||||
|         expected = [] | ||||
|         del a | ||||
|         result = louie.send('this', b, a=b) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         assert len(list(louie.get_all_receivers(b, signal))) == 0, ( | ||||
|             "Remaining handlers: %s" % (louie.get_all_receivers(b, signal),)) | ||||
|         self._isclean() | ||||
|          | ||||
|     def test_GarbageCollectedObj(self): | ||||
|         class x: | ||||
|             def __call__(self, a): | ||||
|                 return a | ||||
|         a = Callable() | ||||
|         b = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(a, signal, b) | ||||
|         expected = [] | ||||
|         del a | ||||
|         result = louie.send('this', b, a=b) | ||||
|         assert result == expected, ( | ||||
|             "Send didn't return expected result:\n\texpected:%s\n\tgot:%s" | ||||
|             % (expected, result)) | ||||
|         assert len(list(louie.get_all_receivers(b, signal))) == 0, ( | ||||
|             "Remaining handlers: %s" % (louie.get_all_receivers(b, signal),)) | ||||
|         self._isclean() | ||||
|  | ||||
|     def test_MultipleRegistration(self): | ||||
|         a = Callable() | ||||
|         b = Dummy() | ||||
|         signal = 'this' | ||||
|         louie.connect(a, signal, b) | ||||
|         louie.connect(a, signal, b) | ||||
|         louie.connect(a, signal, b) | ||||
|         louie.connect(a, signal, b) | ||||
|         louie.connect(a, signal, b) | ||||
|         louie.connect(a, signal, b) | ||||
|         result = louie.send('this', b, a=b) | ||||
|         assert len(result) == 1, result | ||||
|         assert len(list(louie.get_all_receivers(b, signal))) == 1, ( | ||||
|             "Remaining handlers: %s" % (louie.get_all_receivers(b, signal),)) | ||||
|         del a | ||||
|         del b | ||||
|         del result | ||||
|         self._isclean() | ||||
|  | ||||
|     def test_robust(self): | ||||
|         """Test the sendRobust function.""" | ||||
|         def fails(): | ||||
|             raise ValueError('this') | ||||
|         a = object() | ||||
|         signal = 'this' | ||||
|         louie.connect(fails, louie.All, a) | ||||
|         result = louie.send_robust('this', a, a=a) | ||||
|         err = result[0][1] | ||||
|         assert isinstance(err, ValueError) | ||||
|         assert err.args == ('this', ) | ||||
							
								
								
									
										145
									
								
								wlauto/external/louie/test/test_plugin.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								wlauto/external/louie/test/test_plugin.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| """Louie plugin tests.""" | ||||
|  | ||||
| import unittest | ||||
|  | ||||
| import louie | ||||
|  | ||||
| try: | ||||
|     import qt | ||||
|     if not hasattr(qt.qApp, 'for_testing'): | ||||
|         _app = qt.QApplication([]) | ||||
|         _app.for_testing = True | ||||
|         qt.qApp = _app | ||||
| except ImportError: | ||||
|     qt = None | ||||
|  | ||||
|  | ||||
| class ReceiverBase(object): | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.args = [] | ||||
|         self.live = True | ||||
|  | ||||
|     def __call__(self, arg): | ||||
|         self.args.append(arg) | ||||
|  | ||||
| class Receiver1(ReceiverBase): | ||||
|     pass | ||||
|  | ||||
| class Receiver2(ReceiverBase): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class Plugin1(louie.Plugin): | ||||
|  | ||||
|     def is_live(self, receiver): | ||||
|         """ReceiverBase instances are only live if their `live` | ||||
|         attribute is True""" | ||||
|         if isinstance(receiver, ReceiverBase): | ||||
|             return receiver.live | ||||
|         return True | ||||
|  | ||||
|  | ||||
| class Plugin2(louie.Plugin): | ||||
|  | ||||
|     def is_live(self, receiver): | ||||
|         """Pretend all Receiver2 instances are not live.""" | ||||
|         if isinstance(receiver, Receiver2): | ||||
|             return False | ||||
|         return True | ||||
|  | ||||
|  | ||||
| def test_only_one_instance(): | ||||
|     louie.reset() | ||||
|     plugin1a = Plugin1() | ||||
|     plugin1b = Plugin1() | ||||
|     louie.install_plugin(plugin1a) | ||||
|     # XXX: Move these tests into test cases so we can use unittest's | ||||
|     # 'assertRaises' method. | ||||
|     try: | ||||
|         louie.install_plugin(plugin1b) | ||||
|     except louie.error.PluginTypeError: | ||||
|         pass | ||||
|     else: | ||||
|         raise Exception('PluginTypeError not raised') | ||||
|  | ||||
|  | ||||
| def test_is_live(): | ||||
|     louie.reset() | ||||
|     # Create receivers. | ||||
|     receiver1a = Receiver1() | ||||
|     receiver1b = Receiver1() | ||||
|     receiver2a = Receiver2() | ||||
|     receiver2b = Receiver2() | ||||
|     # Connect signals. | ||||
|     louie.connect(receiver1a, 'sig') | ||||
|     louie.connect(receiver1b, 'sig') | ||||
|     louie.connect(receiver2a, 'sig') | ||||
|     louie.connect(receiver2b, 'sig') | ||||
|     # Check reception without plugins. | ||||
|     louie.send('sig', arg='foo') | ||||
|     assert receiver1a.args == ['foo'] | ||||
|     assert receiver1b.args == ['foo'] | ||||
|     assert receiver2a.args == ['foo'] | ||||
|     assert receiver2b.args == ['foo'] | ||||
|     # Install plugin 1. | ||||
|     plugin1 = Plugin1() | ||||
|     louie.install_plugin(plugin1) | ||||
|     # Make some receivers not live. | ||||
|     receiver1a.live = False | ||||
|     receiver2b.live = False | ||||
|     # Check reception. | ||||
|     louie.send('sig', arg='bar') | ||||
|     assert receiver1a.args == ['foo'] | ||||
|     assert receiver1b.args == ['foo', 'bar'] | ||||
|     assert receiver2a.args == ['foo', 'bar'] | ||||
|     assert receiver2b.args == ['foo'] | ||||
|     # Remove plugin 1, install plugin 2. | ||||
|     plugin2 = Plugin2() | ||||
|     louie.remove_plugin(plugin1) | ||||
|     louie.install_plugin(plugin2) | ||||
|     # Check reception. | ||||
|     louie.send('sig', arg='baz') | ||||
|     assert receiver1a.args == ['foo', 'baz'] | ||||
|     assert receiver1b.args == ['foo', 'bar', 'baz'] | ||||
|     assert receiver2a.args == ['foo', 'bar'] | ||||
|     assert receiver2b.args == ['foo'] | ||||
|     # Install plugin 1 alongside plugin 2. | ||||
|     louie.install_plugin(plugin1) | ||||
|     # Check reception. | ||||
|     louie.send('sig', arg='fob') | ||||
|     assert receiver1a.args == ['foo', 'baz'] | ||||
|     assert receiver1b.args == ['foo', 'bar', 'baz', 'fob'] | ||||
|     assert receiver2a.args == ['foo', 'bar'] | ||||
|     assert receiver2b.args == ['foo'] | ||||
|      | ||||
|  | ||||
| if qt is not None: | ||||
|     def test_qt_plugin(): | ||||
|         louie.reset() | ||||
|         # Create receivers. | ||||
|         class Receiver(qt.QWidget): | ||||
|             def __init__(self): | ||||
|                 qt.QObject.__init__(self) | ||||
|                 self.args = [] | ||||
|             def receive(self, arg): | ||||
|                 self.args.append(arg) | ||||
|         receiver1 = Receiver() | ||||
|         receiver2 = Receiver() | ||||
|         # Connect signals. | ||||
|         louie.connect(receiver1.receive, 'sig') | ||||
|         louie.connect(receiver2.receive, 'sig') | ||||
|         # Destroy receiver2 so only a shell is left. | ||||
|         receiver2.close(True) | ||||
|         # Check reception without plugins. | ||||
|         louie.send('sig', arg='foo') | ||||
|         assert receiver1.args == ['foo'] | ||||
|         assert receiver2.args == ['foo'] | ||||
|         # Install plugin. | ||||
|         plugin = louie.QtWidgetPlugin() | ||||
|         louie.install_plugin(plugin) | ||||
|         # Check reception with plugins. | ||||
|         louie.send('sig', arg='bar') | ||||
|         assert receiver1.args == ['foo', 'bar'] | ||||
|         assert receiver2.args == ['foo'] | ||||
|  | ||||
							
								
								
									
										41
									
								
								wlauto/external/louie/test/test_prioritydispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								wlauto/external/louie/test/test_prioritydispatcher.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| import unittest | ||||
|  | ||||
| import louie | ||||
| from louie import dispatcher | ||||
|  | ||||
| class Callable(object): | ||||
|  | ||||
|     def __init__(self, val): | ||||
|         self.val = val | ||||
|  | ||||
|     def __call__(self): | ||||
|         return self.val | ||||
|  | ||||
|  | ||||
| one = Callable(1) | ||||
| two = Callable(2) | ||||
| three = Callable(3) | ||||
|  | ||||
| class TestPriorityDispatcher(unittest.TestCase): | ||||
|  | ||||
|     def test_ConnectNotify(self): | ||||
|         louie.connect( | ||||
|             two, | ||||
|             'one', | ||||
|             priority=200 | ||||
|             ) | ||||
|         louie.connect( | ||||
|             one, | ||||
|             'one', | ||||
|             priority=100 | ||||
|             ) | ||||
|         louie.connect( | ||||
|             three, | ||||
|             'one', | ||||
|             priority=300 | ||||
|             ) | ||||
|         result = [ i[1] for i in louie.send('one')] | ||||
|         if not result == [1, 2, 3]: | ||||
|             print result | ||||
|             assert(False) | ||||
|  | ||||
							
								
								
									
										62
									
								
								wlauto/external/louie/test/test_prioritylist.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								wlauto/external/louie/test/test_prioritylist.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| import unittest | ||||
|  | ||||
| import louie.prioritylist | ||||
| from louie.prioritylist import PriorityList | ||||
|  | ||||
| #def populate_list(plist): | ||||
|  | ||||
| class TestPriorityList(unittest.TestCase): | ||||
|  | ||||
|     def test_Insert(self): | ||||
|         pl = PriorityList() | ||||
|         elements = {3: "element 3", | ||||
|                     2: "element 2", | ||||
|                     1: "element 1", | ||||
|                     5: "element 5", | ||||
|                     4: "element 4" | ||||
|                     } | ||||
|         for key in elements: | ||||
|             pl.add(elements[key], priority=key) | ||||
|  | ||||
|         match = zip(sorted(elements.values()), pl[:]) | ||||
|         for pair in match: | ||||
|             assert(pair[0]==pair[1]) | ||||
|  | ||||
|     def test_Delete(self): | ||||
|         pl = PriorityList() | ||||
|         elements = {2: "element 3", | ||||
|                     1: "element 2", | ||||
|                     0: "element 1", | ||||
|                     4: "element 5", | ||||
|                     3: "element 4" | ||||
|                     } | ||||
|         for key in elements: | ||||
|             pl.add(elements[key], priority=key) | ||||
|         del elements[2] | ||||
|         del pl[2] | ||||
|         match = zip(sorted(elements.values()) , pl[:]) | ||||
|         for pair in match: | ||||
|             assert(pair[0]==pair[1]) | ||||
|  | ||||
|     def test_Multiple(self): | ||||
|         pl = PriorityList() | ||||
|         pl.add('1', 1) | ||||
|         pl.add('2.1', 2) | ||||
|         pl.add('3', 3) | ||||
|         pl.add('2.2', 2) | ||||
|         it = iter(pl) | ||||
|         assert(it.next() == '1') | ||||
|         assert(it.next() == '2.1') | ||||
|         assert(it.next() == '2.2') | ||||
|         assert(it.next() == '3') | ||||
|  | ||||
|     def test_IteratorBreak(self): | ||||
|         pl = PriorityList() | ||||
|         pl.add('1', 1) | ||||
|         pl.add('2.1', 2) | ||||
|         pl.add('3', 3) | ||||
|         pl.add('2.2', 2) | ||||
|         for i in pl: | ||||
|             if i == '2.1': | ||||
|                 break | ||||
|         assert(pl.index('3') == 3) | ||||
							
								
								
									
										34
									
								
								wlauto/external/louie/test/test_robustapply.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								wlauto/external/louie/test/test_robustapply.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| import unittest | ||||
|  | ||||
| from louie.robustapply import robust_apply | ||||
|  | ||||
|  | ||||
| def no_argument(): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def one_argument(blah): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def two_arguments(blah, other): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class TestRobustApply(unittest.TestCase): | ||||
|      | ||||
|     def test_01(self): | ||||
|         robust_apply(no_argument, no_argument) | ||||
|          | ||||
|     def test_02(self): | ||||
|         self.assertRaises(TypeError, robust_apply, no_argument, no_argument, | ||||
|                           'this' ) | ||||
|          | ||||
|     def test_03(self): | ||||
|         self.assertRaises(TypeError, robust_apply, one_argument, one_argument) | ||||
|          | ||||
|     def test_04(self): | ||||
|         """Raise error on duplication of a particular argument""" | ||||
|         self.assertRaises(TypeError, robust_apply, one_argument, one_argument, | ||||
|                           'this', blah='that') | ||||
|  | ||||
							
								
								
									
										83
									
								
								wlauto/external/louie/test/test_saferef.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								wlauto/external/louie/test/test_saferef.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| import unittest | ||||
|  | ||||
| from louie.saferef import safe_ref | ||||
|  | ||||
|  | ||||
| class _Sample1(object): | ||||
|     def x(self): | ||||
|         pass | ||||
|  | ||||
|      | ||||
| def _sample2(obj): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class _Sample3(object): | ||||
|     def __call__(self, obj): | ||||
|         pass | ||||
|  | ||||
|      | ||||
| class TestSaferef(unittest.TestCase): | ||||
|  | ||||
|     # XXX: The original tests had a test for closure, and it had an | ||||
|     # off-by-one problem, perhaps due to scope issues.  It has been | ||||
|     # removed from this test suite. | ||||
|      | ||||
|     def setUp(self): | ||||
|         ts = [] | ||||
|         ss = [] | ||||
|         for x in xrange(5000): | ||||
|             t = _Sample1() | ||||
|             ts.append(t) | ||||
|             s = safe_ref(t.x, self._closure) | ||||
|             ss.append(s) | ||||
|         ts.append(_sample2) | ||||
|         ss.append(safe_ref(_sample2, self._closure)) | ||||
|         for x in xrange(30): | ||||
|             t = _Sample3() | ||||
|             ts.append(t) | ||||
|             s = safe_ref(t, self._closure) | ||||
|             ss.append(s) | ||||
|         self.ts = ts | ||||
|         self.ss = ss | ||||
|         self.closure_count = 0 | ||||
|          | ||||
|     def tearDown(self): | ||||
|         if hasattr(self, 'ts'): | ||||
|             del self.ts | ||||
|         if hasattr(self, 'ss'): | ||||
|             del self.ss | ||||
|          | ||||
|     def test_In(self): | ||||
|         """Test the `in` operator for safe references (cmp)""" | ||||
|         for t in self.ts[:50]: | ||||
|             assert safe_ref(t.x) in self.ss | ||||
|              | ||||
|     def test_Valid(self): | ||||
|         """Test that the references are valid (return instance methods)""" | ||||
|         for s in self.ss: | ||||
|             assert s() | ||||
|              | ||||
|     def test_ShortCircuit(self): | ||||
|         """Test that creation short-circuits to reuse existing references""" | ||||
|         sd = {} | ||||
|         for s in self.ss: | ||||
|             sd[s] = 1 | ||||
|         for t in self.ts: | ||||
|             if hasattr(t, 'x'): | ||||
|                 assert sd.has_key(safe_ref(t.x)) | ||||
|             else: | ||||
|                 assert sd.has_key(safe_ref(t)) | ||||
|                  | ||||
|     def test_Representation(self): | ||||
|         """Test that the reference object's representation works | ||||
|  | ||||
|         XXX Doesn't currently check the results, just that no error | ||||
|             is raised | ||||
|         """ | ||||
|         repr(self.ss[-1]) | ||||
|          | ||||
|     def _closure(self, ref): | ||||
|         """Dumb utility mechanism to increment deletion counter""" | ||||
|         self.closure_count += 1 | ||||
|  | ||||
							
								
								
									
										8
									
								
								wlauto/external/louie/version.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								wlauto/external/louie/version.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| """Louie version information.""" | ||||
|  | ||||
|  | ||||
| NAME = 'Louie' | ||||
| DESCRIPTION = 'Signal dispatching mechanism' | ||||
| VERSION = '1.1' | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user