This bug, filed here – http://bugs.python.org/issue14308 - occurs because of a bad interaction between dummy thread objects created by the threading API when we call threading.currentThread() on a foreign thread. And in particular, because of the _after_fork feature which is called to clean up resources (triggered by `os.fork()` method).
Stephen White also provided a code snippet that demonstrates this problem:-
import os import thread import threading import time def t(): threading.currentThread() # Populate threading._active with a DummyThread time.sleep(3) thread.start_new_thread(t, ()) time.sleep(1) pid = os.fork() if pid == 0: os._exit(0) os.waitpid(pid, 0)
Running this script will give you “no attribute ‘_Thread__block’” error, as explained. For detailed explanations and a monkey-patch solution without modifying python source code, this is a good resource - http://stackoverflow.com/questions/13193278/understand-python-threading-bug
It so happens that django-debug-toolbar’s middleware causes exactly this problem. And it’s extremely annoying to have my django dev server printing out ‘_DummyThread’ object has no attribute ‘_Thread__block’ in my terminal stdout repeatedly whenever my DebugToolbarMiddleware is enabled.
MIDDLEWARE_CLASSES += ( 'debug_toolbar.middleware.DebugToolbarMiddleware', )
So here’s my pull request to resolve this issue on django-debug-toolbar - https://github.com/django-debug-toolbar/django-debug-toolbar/pull/333. I have also taken the liberty to “upgrade” the original use of the thread module to threading module in this pull request. thread module will no longer be available in Python3 but threading module will, so in my opinion, it’s better to simply using the threading module!
Further criticisms and suggestions to improve welcome.