source file: /disk/u/t/dev/python-svn/Lib/dummy_thread.py
file stats: 66 lines, 56 executed: 84.8% covered
   1. """Drop-in replacement for the thread module.
   2. 
   3. Meant to be used as a brain-dead substitute so that threaded code does
   4. not need to be rewritten for when the thread module is not present.
   5. 
   6. Suggested usage is::
   7. 
   8.     try:
   9.         import thread
  10.     except ImportError:
  11.         import dummy_thread as thread
  12. 
  13. """
  14. # Exports only things specified by thread documentation;
  15. # skipping obsolete synonyms allocate(), start_new(), exit_thread().
  16. __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',
  17.            'interrupt_main', 'LockType']
  18. 
  19. import traceback as _traceback
  20. import warnings
  21. 
  22. class error(Exception):
  23.     """Dummy implementation of thread.error."""
  24. 
  25.     def __init__(self, *args):
  26.         self.args = args
  27. 
  28. def start_new_thread(function, args, kwargs={}):
  29.     """Dummy implementation of thread.start_new_thread().
  30. 
  31.     Compatibility is maintained by making sure that ``args`` is a
  32.     tuple and ``kwargs`` is a dictionary.  If an exception is raised
  33.     and it is SystemExit (which can be done by thread.exit()) it is
  34.     caught and nothing is done; all other exceptions are printed out
  35.     by using traceback.print_exc().
  36. 
  37.     If the executed function calls interrupt_main the KeyboardInterrupt will be
  38.     raised when the function returns.
  39. 
  40.     """
  41.     if type(args) != type(tuple()):
  42.         raise TypeError("2nd arg must be a tuple")
  43.     if type(kwargs) != type(dict()):
  44.         raise TypeError("3rd arg must be a dict")
  45.     global _main
  46.     _main = False
  47.     try:
  48.         function(*args, **kwargs)
  49.     except SystemExit:
  50.         pass
  51.     except:
  52.         _traceback.print_exc()
  53.     _main = True
  54.     global _interrupt
  55.     if _interrupt:
  56.         _interrupt = False
  57.         raise KeyboardInterrupt
  58. 
  59. def exit():
  60.     """Dummy implementation of thread.exit()."""
  61.     raise SystemExit
  62. 
  63. def get_ident():
  64.     """Dummy implementation of thread.get_ident().
  65. 
  66.     Since this module should only be used when threadmodule is not
  67.     available, it is safe to assume that the current process is the
  68.     only thread.  Thus a constant can be safely returned.
  69.     """
  70.     return -1
  71. 
  72. def allocate_lock():
  73.     """Dummy implementation of thread.allocate_lock()."""
  74.     return LockType()
  75. 
  76. def stack_size(size=None):
  77.     """Dummy implementation of thread.stack_size()."""
  78.     if size is not None:
  79.         raise error("setting thread stack size not supported")
  80.     return 0
  81. 
  82. class LockType(object):
  83.     """Class implementing dummy implementation of thread.LockType.
  84. 
  85.     Compatibility is maintained by maintaining self.locked_status
  86.     which is a boolean that stores the state of the lock.  Pickling of
  87.     the lock, though, should not be done since if the thread module is
  88.     then used with an unpickled ``lock()`` from here problems could
  89.     occur from this class not having atomic methods.
  90. 
  91.     """
  92. 
  93.     def __init__(self):
  94.         self.locked_status = False
  95. 
  96.     def acquire(self, waitflag=None):
  97.         """Dummy implementation of acquire().
  98. 
  99.         For blocking calls, self.locked_status is automatically set to
 100.         True and returned appropriately based on value of
 101.         ``waitflag``.  If it is non-blocking, then the value is
 102.         actually checked and not set if it is already acquired.  This
 103.         is all done so that threading.Condition's assert statements
 104.         aren't triggered and throw a little fit.
 105. 
 106.         """
 107.         if waitflag is None:
 108.             self.locked_status = True
 109.             return None
 110.         elif not waitflag:
 111.             if not self.locked_status:
 112.                 self.locked_status = True
 113.                 return True
 114.             else:
 115.                 return False
 116.         else:
 117.             self.locked_status = True
 118.             return True
 119. 
 120.     __enter__ = acquire
 121. 
 122.     def __exit__(self, typ, val, tb):
 123.         self.release()
 124. 
 125.     def release(self):
 126.         """Release the dummy lock."""
 127.         # XXX Perhaps shouldn't actually bother to test?  Could lead
 128.         #     to problems for complex, threaded code.
 129.         if not self.locked_status:
 130.             raise error
 131.         self.locked_status = False
 132.         return True
 133. 
 134.     def locked(self):
 135.         return self.locked_status
 136. 
 137. # Used to signal that interrupt_main was called in a "thread"
 138. _interrupt = False
 139. # True when not executing in a "thread"
 140. _main = True
 141. 
 142. def interrupt_main():
 143.     """Set _interrupt flag to True to have start_new_thread raise
 144.     KeyboardInterrupt upon exiting."""
 145.     if _main:
 146.         raise KeyboardInterrupt
 147.     else:
 148.         global _interrupt
 149.         _interrupt = True