home *** CD-ROM | disk | FTP | other *** search
- """Drop-in replacement for the thread module.
-
- Meant to be used as a brain-dead substitute so that threaded code does
- not need to be rewritten for when the thread module is not present.
-
- Suggested usage is::
-
- try:
- import thread
- except ImportError:
- import dummy_thread as thread
-
- """
- # Exports only things specified by thread documentation;
- # skipping obsolete synonyms allocate(), start_new(), exit_thread().
- __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',
- 'interrupt_main', 'LockType']
-
- import traceback as _traceback
-
- class error(Exception):
- """Dummy implementation of thread.error."""
-
- def __init__(self, *args):
- self.args = args
-
- def start_new_thread(function, args, kwargs={}):
- """Dummy implementation of thread.start_new_thread().
-
- Compatibility is maintained by making sure that ``args`` is a
- tuple and ``kwargs`` is a dictionary. If an exception is raised
- and it is SystemExit (which can be done by thread.exit()) it is
- caught and nothing is done; all other exceptions are printed out
- by using traceback.print_exc().
-
- If the executed function calls interrupt_main the KeyboardInterrupt will be
- raised when the function returns.
-
- """
- if type(args) != type(tuple()):
- raise TypeError("2nd arg must be a tuple")
- if type(kwargs) != type(dict()):
- raise TypeError("3rd arg must be a dict")
- global _main
- _main = False
- try:
- function(*args, **kwargs)
- except SystemExit:
- pass
- except:
- _traceback.print_exc()
- _main = True
- global _interrupt
- if _interrupt:
- _interrupt = False
- raise KeyboardInterrupt
-
- def exit():
- """Dummy implementation of thread.exit()."""
- raise SystemExit
-
- def get_ident():
- """Dummy implementation of thread.get_ident().
-
- Since this module should only be used when threadmodule is not
- available, it is safe to assume that the current process is the
- only thread. Thus a constant can be safely returned.
- """
- return -1
-
- def allocate_lock():
- """Dummy implementation of thread.allocate_lock()."""
- return LockType()
-
- def stack_size(size=None):
- """Dummy implementation of thread.stack_size()."""
- if size is not None:
- raise error("setting thread stack size not supported")
- return 0
-
- class LockType(object):
- """Class implementing dummy implementation of thread.LockType.
-
- Compatibility is maintained by maintaining self.locked_status
- which is a boolean that stores the state of the lock. Pickling of
- the lock, though, should not be done since if the thread module is
- then used with an unpickled ``lock()`` from here problems could
- occur from this class not having atomic methods.
-
- """
-
- def __init__(self):
- self.locked_status = False
-
- def acquire(self, waitflag=None):
- """Dummy implementation of acquire().
-
- For blocking calls, self.locked_status is automatically set to
- True and returned appropriately based on value of
- ``waitflag``. If it is non-blocking, then the value is
- actually checked and not set if it is already acquired. This
- is all done so that threading.Condition's assert statements
- aren't triggered and throw a little fit.
-
- """
- if waitflag is None or waitflag:
- self.locked_status = True
- return True
- else:
- if not self.locked_status:
- self.locked_status = True
- return True
- else:
- return False
-
- __enter__ = acquire
-
- def __exit__(self, typ, val, tb):
- self.release()
-
- def release(self):
- """Release the dummy lock."""
- # XXX Perhaps shouldn't actually bother to test? Could lead
- # to problems for complex, threaded code.
- if not self.locked_status:
- raise error
- self.locked_status = False
- return True
-
- def locked(self):
- return self.locked_status
-
- # Used to signal that interrupt_main was called in a "thread"
- _interrupt = False
- # True when not executing in a "thread"
- _main = True
-
- def interrupt_main():
- """Set _interrupt flag to True to have start_new_thread raise
- KeyboardInterrupt upon exiting."""
- if _main:
- raise KeyboardInterrupt
- else:
- global _interrupt
- _interrupt = True
-