0001 """Drop-in replacement for the thread module. 0002 0003 Meant to be used as a brain-dead substitute so that threaded code does 0004 not need to be rewritten for when the thread module is not present. 0005 0006 Suggested usage is:: 0007 0008 try: 0009 import thread 0010 except ImportError: 0011 import dummy_thread as thread 0012 0013 """ 0014 __author__ = "Brett Cannon" 0015 __email__ = "brett@python.org" 0016 0017 # Exports only things specified by thread documentation 0018 # (skipping obsolete synonyms allocate(), start_new(), exit_thread()) 0019 __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', 0020 'interrupt_main', 'LockType'] 0021 0022 import traceback as _traceback 0023 0024 class error(Exception): 0025 """Dummy implementation of thread.error.""" 0026 0027 def __init__(self, *args): 0028 self.args = args 0029 0030 def start_new_thread(function, args, kwargs={}): 0031 """Dummy implementation of thread.start_new_thread(). 0032 0033 Compatibility is maintained by making sure that ``args`` is a 0034 tuple and ``kwargs`` is a dictionary. If an exception is raised 0035 and it is SystemExit (which can be done by thread.exit()) it is 0036 caught and nothing is done; all other exceptions are printed out 0037 by using traceback.print_exc(). 0038 0039 If the executed function calls interrupt_main the KeyboardInterrupt will be 0040 raised when the function returns. 0041 0042 """ 0043 if type(args) != type(tuple()): 0044 raise TypeError("2nd arg must be a tuple") 0045 if type(kwargs) != type(dict()): 0046 raise TypeError("3rd arg must be a dict") 0047 global _main 0048 _main = False 0049 try: 0050 function(*args, **kwargs) 0051 except SystemExit: 0052 pass 0053 except: 0054 _traceback.print_exc() 0055 _main = True 0056 global _interrupt 0057 if _interrupt: 0058 _interrupt = False 0059 raise KeyboardInterrupt 0060 0061 def exit(): 0062 """Dummy implementation of thread.exit().""" 0063 raise SystemExit 0064 0065 def get_ident(): 0066 """Dummy implementation of thread.get_ident(). 0067 0068 Since this module should only be used when threadmodule is not 0069 available, it is safe to assume that the current process is the 0070 only thread. Thus a constant can be safely returned. 0071 """ 0072 return -1 0073 0074 def allocate_lock(): 0075 """Dummy implementation of thread.allocate_lock().""" 0076 return LockType() 0077 0078 class LockType(object): 0079 """Class implementing dummy implementation of thread.LockType. 0080 0081 Compatibility is maintained by maintaining self.locked_status 0082 which is a boolean that stores the state of the lock. Pickling of 0083 the lock, though, should not be done since if the thread module is 0084 then used with an unpickled ``lock()`` from here problems could 0085 occur from this class not having atomic methods. 0086 0087 """ 0088 0089 def __init__(self): 0090 self.locked_status = False 0091 0092 def acquire(self, waitflag=None): 0093 """Dummy implementation of acquire(). 0094 0095 For blocking calls, self.locked_status is automatically set to 0096 True and returned appropriately based on value of 0097 ``waitflag``. If it is non-blocking, then the value is 0098 actually checked and not set if it is already acquired. This 0099 is all done so that threading.Condition's assert statements 0100 aren't triggered and throw a little fit. 0101 0102 """ 0103 if waitflag is None: 0104 self.locked_status = True 0105 return None 0106 elif not waitflag: 0107 if not self.locked_status: 0108 self.locked_status = True 0109 return True 0110 else: 0111 return False 0112 else: 0113 self.locked_status = True 0114 return True 0115 0116 def release(self): 0117 """Release the dummy lock.""" 0118 # XXX Perhaps shouldn't actually bother to test? Could lead 0119 # to problems for complex, threaded code. 0120 if not self.locked_status: 0121 raise error 0122 self.locked_status = False 0123 return True 0124 0125 def locked(self): 0126 return self.locked_status 0127 0128 # Used to signal that interrupt_main was called in a "thread" 0129 _interrupt = False 0130 # True when not executing in a "thread" 0131 _main = True 0132 0133 def interrupt_main(): 0134 """Set _interrupt flag to True to have start_new_thread raise 0135 KeyboardInterrupt upon exiting.""" 0136 if _main: 0137 raise KeyboardInterrupt 0138 else: 0139 global _interrupt 0140 _interrupt = True 0141
Generated by PyXR 0.9.4