PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/lib-python/2.7/dummy_thread.py

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