Serhiy Storchaka added the comment: _thread.RLock objects were wrongly pickleable before 3.6.
>>> import pickle, pickletools, _thread >>> lock = _thread.RLock() >>> lock.acquire() True >>> lock <locked _thread.RLock object owner=-1219508480 count=1 at 0xb713acb0> >>> pickle.loads(pickle.dumps(lock)) <unlocked _thread.RLock object owner=0 count=0 at 0xb6facb90> >>> pickletools.dis(pickletools.optimize(pickle.dumps(lock))) 0: \x80 PROTO 3 2: c GLOBAL '_thread RLock' 17: ) EMPTY_TUPLE 18: \x81 NEWOBJ 19: . STOP highest protocol among opcodes = 2 Actually only an information about the type was saved. The state of the lock was lost. Unpickled lock was not a copy of the original lock, but a newly created object with default initial state. There were errors in programs that pickled _thread.RLock objects. Just these errors were unnoticed. But programs likely didn't work as expected. Now an exception raised on early stage allows you to rewrite not working code. I don't know whether QueueHandler was designed to be pickleable. As a workaround try to set the lock attribute to None before pickling and set it to threading.RLock() (or call the createLock() method) after unpickling. This change was made in issue22995. ---------- nosy: +serhiy.storchaka _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue29168> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com