Index: Doc/library/threading.rst =================================================================== --- Doc/library/threading.rst (revision 73468) +++ Doc/library/threading.rst (working copy) @@ -215,7 +215,7 @@ A thread can be flagged as a "daemon thread". The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set -through the :attr:`daemon` property. +through the :attr:`daemon` property or by setting the *daemon* argument to True. There is a "main thread" object; this corresponds to the initial thread of control in the Python program. It is not a daemon thread. @@ -228,7 +228,8 @@ impossible to detect the termination of alien threads. -.. class:: Thread(group=None, target=None, name=None, args=(), kwargs={}) +.. class:: Thread(group=None, target=None, name=None, args=(), kwargs={}, + verbose=None, daemon=False) This constructor should always be called with keyword arguments. Arguments are: @@ -246,6 +247,10 @@ *kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to ``{}``. + *verbose* is a flag used for debugging messages. + + *daemon* will flag the thread as daemonic. + If the subclass overrides the constructor, it must make sure to invoke the base class constructor (``Thread.__init__()``) before doing anything else to the thread. Index: Lib/threading.py =================================================================== --- Lib/threading.py (revision 73468) +++ Lib/threading.py (working copy) @@ -423,7 +423,7 @@ __exc_clear = _sys.exc_clear def __init__(self, group=None, target=None, name=None, - args=(), kwargs=None, verbose=None): + args=(), kwargs=None, verbose=None, daemon=False): assert group is None, "group argument must be None for now" _Verbose.__init__(self, verbose) if kwargs is None: @@ -432,7 +432,7 @@ self.__name = str(name or _newname()) self.__args = args self.__kwargs = kwargs - self.__daemonic = self._set_daemon() + self.__daemonic = daemon self.__ident = None self.__started = Event() self.__stopped = False @@ -442,10 +442,6 @@ # sys.exc_info since it can be changed between instances self.__stderr = _sys.stderr - def _set_daemon(self): - # Overridden in _MainThread and _DummyThread - return current_thread().daemon - def __repr__(self): assert self.__initialized, "Thread.__init__() was not called" status = "initial" @@ -734,15 +730,12 @@ class _MainThread(Thread): def __init__(self): - Thread.__init__(self, name="MainThread") + Thread.__init__(self, name="MainThread", daemon=False) self._Thread__started.set() self._set_ident() with _active_limbo_lock: _active[_get_ident()] = self - def _set_daemon(self): - return False - def _exitfunc(self): self._Thread__stop() t = _pickSomeNonDaemonThread() @@ -774,7 +767,7 @@ class _DummyThread(Thread): def __init__(self): - Thread.__init__(self, name=_newname("Dummy-%d")) + Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True) # Thread.__block consumes an OS-level locking primitive, which # can never be used by a _DummyThread. Since a _DummyThread @@ -786,9 +779,6 @@ with _active_limbo_lock: _active[_get_ident()] = self - def _set_daemon(self): - return True - def join(self, timeout=None): assert False, "cannot join a dummy thread" Index: Lib/test/test_threading.py =================================================================== --- Lib/test/test_threading.py (revision 73468) +++ Lib/test/test_threading.py (working copy) @@ -336,7 +336,15 @@ msg=('%d references still around' % sys.getrefcount(weak_raising_cyclic_object()))) + def test_deamon_param(self): + t = threading.Thread() + self.assertFalse(t.daemon) + t = threading.Thread(daemon=False) + self.assertFalse(t.daemon) + t = threading.Thread(daemon=True) + self.assertTrue(t.daemon) + class ThreadJoinOnShutdown(unittest.TestCase): def _run_and_join(self, script):