When a httplib2.RedirectLimit (maybe also with others) occurred on pywikibot.comms.http.fetch it hangs:
>>> import pywikibot.comms.http >>> pywikibot.comms.http.fetch('http://www.tvtropes.org/api.php') Traceback (most recent call last): File "/home/xzise/.pyenv/versions/3.4.3/lib/python3.4/threading.py", line 920, in _bootstrap_inner self.run() File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 549, in run item.data = self.http.request(*item.args, **item.kwargs) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 260, in request uri, method, body, headers, response, content, max_redirects) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 307, in _follow_redirect max_redirects=max_redirects - 1) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 260, in request uri, method, body, headers, response, content, max_redirects) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 311, in _follow_redirect response, content) httplib2.RedirectLimit: Redirected more times than redirection_limit allows. ^CTraceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/http.py", line 364, in fetch error_handling_callback(request) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/http.py", line 274, in error_handling_callback if isinstance(request.data, SSLHandshakeError): File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 392, in data self._join() File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 386, in _join self.lock.acquire(True) File "/home/xzise/Programms/pywikibot/core/pywikibot/comms/threadedhttp.py", line 323, in acquire return super(S, self).acquire(blocking) File "/home/xzise/.pyenv/versions/3.4.3/lib/python3.4/threading.py", line 421, in acquire self._cond.wait(timeout) File "/home/xzise/.pyenv/versions/3.4.3/lib/python3.4/threading.py", line 290, in wait waiter.acquire() KeyboardInterrupt
From what I could tell it's not releasing the semaphore correctly (although when looking at the code it should and it does actually call that) and when it then tries to check for errors it tries to acquire it and waits then on it.
try: # inside of that it crashes item.data = self.http.request(*item.args, **item.kwargs) finally: if item.lock: # this line is called item.lock.release()
I tried to determine where it acquires the lock but only find the one place in fetch and then one when it tries to get the data in error_handling_callback.
(Note: The line numbers are bit off as I try to debug that one)