|  | """Drop-in replacement for the thread module. | 
|  |  | 
|  | Meant to be used as a brain-dead substitute so that threaded code does | 
|  | not need to be rewritten for when the thread module is not present. | 
|  |  | 
|  | Suggested usage is:: | 
|  |  | 
|  | try: | 
|  | import thread | 
|  | except ImportError: | 
|  | import dummy_thread as thread | 
|  |  | 
|  | """ | 
|  | # Exports only things specified by thread documentation; | 
|  | # skipping obsolete synonyms allocate(), start_new(), exit_thread(). | 
|  | __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', | 
|  | 'interrupt_main', 'LockType'] | 
|  |  | 
|  | import traceback as _traceback | 
|  |  | 
|  | class error(Exception): | 
|  | """Dummy implementation of thread.error.""" | 
|  |  | 
|  | def __init__(self, *args): | 
|  | self.args = args | 
|  |  | 
|  | def start_new_thread(function, args, kwargs={}): | 
|  | """Dummy implementation of thread.start_new_thread(). | 
|  |  | 
|  | Compatibility is maintained by making sure that ``args`` is a | 
|  | tuple and ``kwargs`` is a dictionary.  If an exception is raised | 
|  | and it is SystemExit (which can be done by thread.exit()) it is | 
|  | caught and nothing is done; all other exceptions are printed out | 
|  | by using traceback.print_exc(). | 
|  |  | 
|  | If the executed function calls interrupt_main the KeyboardInterrupt will be | 
|  | raised when the function returns. | 
|  |  | 
|  | """ | 
|  | if type(args) != type(tuple()): | 
|  | raise TypeError("2nd arg must be a tuple") | 
|  | if type(kwargs) != type(dict()): | 
|  | raise TypeError("3rd arg must be a dict") | 
|  | global _main | 
|  | _main = False | 
|  | try: | 
|  | function(*args, **kwargs) | 
|  | except SystemExit: | 
|  | pass | 
|  | except: | 
|  | _traceback.print_exc() | 
|  | _main = True | 
|  | global _interrupt | 
|  | if _interrupt: | 
|  | _interrupt = False | 
|  | raise KeyboardInterrupt | 
|  |  | 
|  | def exit(): | 
|  | """Dummy implementation of thread.exit().""" | 
|  | raise SystemExit | 
|  |  | 
|  | def get_ident(): | 
|  | """Dummy implementation of thread.get_ident(). | 
|  |  | 
|  | Since this module should only be used when threadmodule is not | 
|  | available, it is safe to assume that the current process is the | 
|  | only thread.  Thus a constant can be safely returned. | 
|  | """ | 
|  | return -1 | 
|  |  | 
|  | def allocate_lock(): | 
|  | """Dummy implementation of thread.allocate_lock().""" | 
|  | return LockType() | 
|  |  | 
|  | def stack_size(size=None): | 
|  | """Dummy implementation of thread.stack_size().""" | 
|  | if size is not None: | 
|  | raise error("setting thread stack size not supported") | 
|  | return 0 | 
|  |  | 
|  | class LockType(object): | 
|  | """Class implementing dummy implementation of thread.LockType. | 
|  |  | 
|  | Compatibility is maintained by maintaining self.locked_status | 
|  | which is a boolean that stores the state of the lock.  Pickling of | 
|  | the lock, though, should not be done since if the thread module is | 
|  | then used with an unpickled ``lock()`` from here problems could | 
|  | occur from this class not having atomic methods. | 
|  |  | 
|  | """ | 
|  |  | 
|  | def __init__(self): | 
|  | self.locked_status = False | 
|  |  | 
|  | def acquire(self, waitflag=None): | 
|  | """Dummy implementation of acquire(). | 
|  |  | 
|  | For blocking calls, self.locked_status is automatically set to | 
|  | True and returned appropriately based on value of | 
|  | ``waitflag``.  If it is non-blocking, then the value is | 
|  | actually checked and not set if it is already acquired.  This | 
|  | is all done so that threading.Condition's assert statements | 
|  | aren't triggered and throw a little fit. | 
|  |  | 
|  | """ | 
|  | if waitflag is None or waitflag: | 
|  | self.locked_status = True | 
|  | return True | 
|  | else: | 
|  | if not self.locked_status: | 
|  | self.locked_status = True | 
|  | return True | 
|  | else: | 
|  | return False | 
|  |  | 
|  | __enter__ = acquire | 
|  |  | 
|  | def __exit__(self, typ, val, tb): | 
|  | self.release() | 
|  |  | 
|  | def release(self): | 
|  | """Release the dummy lock.""" | 
|  | # XXX Perhaps shouldn't actually bother to test?  Could lead | 
|  | #     to problems for complex, threaded code. | 
|  | if not self.locked_status: | 
|  | raise error | 
|  | self.locked_status = False | 
|  | return True | 
|  |  | 
|  | def locked(self): | 
|  | return self.locked_status | 
|  |  | 
|  | # Used to signal that interrupt_main was called in a "thread" | 
|  | _interrupt = False | 
|  | # True when not executing in a "thread" | 
|  | _main = True | 
|  |  | 
|  | def interrupt_main(): | 
|  | """Set _interrupt flag to True to have start_new_thread raise | 
|  | KeyboardInterrupt upon exiting.""" | 
|  | if _main: | 
|  | raise KeyboardInterrupt | 
|  | else: | 
|  | global _interrupt | 
|  | _interrupt = True |