> On Apr 29, 2020, at 11:15 AM, Tom Forbes <t...@tomforb.es> wrote:
>
> What exactly would the issue be with this:
>
> ```
> import functools
> from threading import Lock
>
> def once(func):
> sentinel = object()
> cache = sentinel
> lock = Lock()
>
> @functools.wraps(func)
> def _wrapper():
> nonlocal cache, lock, sentinel
> if cache is sentinel:
> with lock:
> if cache is sentinel:
> cache = func()
> return cache
>
> return _wrapper
> ```
This recipe is the best variant so far and gives us something concrete to talk
about :-)
Benefits: Guarantees the wrapped function is not called more than once.
Restrictions: Only works with zero argument functions.
Risks: Any reentrancy or recursion will result in deadlock.
Limitations: No instrumentation. No ability to reset or clear. Won't work
across multiple processes.
It would be nice to look at some compelling use cases. Off hand, I can't think
of time when I would have used this decorator. Also, I have a nagging worry
that holding a non-reentrant lock across an arbitrary user defined function
call is recipe for deadlocks. That's why during code reviews we typically
check every single use of Lock() to see if it should have been an RLock(),
especially in big systems where GC, __del__, or weakref callbacks can trigger
running any code at just about any time.
Raymond
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/B32VKG5IPHKEL4Y7MP7WMQZXZYYWVT64/
Code of Conduct: http://python.org/psf/codeofconduct/