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

Reply via email to