Raymond Hettinger added the comment:

[Antoine Pitrou]
> So perhaps we need C code after all.

This matches my experience with functools.lru_cache() where I used an RLock() 
to handle reentrancy.  That by itself was insufficient.  I also had to make 
otherwise unnecessary variable assignments to hang onto object references to 
avoid a decref triggering arbitrary Python code from reentering before the 
links were all in a consistent state.   Further, I had to create a key wrapper 
to make sure a potentially reentrant __hash__() call wouldn't be made before 
the state was fully updated.  Even then, a potentially reentrant __eq__() call 
couldn't be avoided, so I had to re-order the operations to make sure this was 
the last call after the other state updates.  This defended against all normal 
code, but all these measures still could not defend against signals or a GC 
invocation of __del__, either of which can happen at any time.

On the plus side, we now have a C version of functools.lru_cache() that is 
protected somewhat by the GIL.  On the minus side, it was hard to get right.  
Even with the pure python code as a model, the person who wrote the C code 
didn't fully think through all sources of reentrancy and wrote buggy code that 
shipped in 3.5 and 3.6 (resulting in normal code code triggering 
hard-to-reproduce reentrancy bugs).  The lesson here is that while the C code 
can be written correctly, it isn't easy to do and it is hard to notice when it 
is incorrect.

One other thought:  Given that __del__() can be invoked at almost any time and 
can potentially call any other piece of Python code, we should consider turning 
every lock into an rlock.  Also, there should be some guidance on __del__() 
advising considerable restraint on what gets called.  The world is likely full 
of pure Python code that can't defend itself against arbitrary re-entrancy.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue14976>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to