github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/third_party/stdlib/dummy_thread.py (about)

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