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