I want to have an object conManager
that is a reentrant context manager instance such that whenever I enter and exit its context it will print a number, but the number must be one higher than the number of the previus context (starting at 0).
Example:
with conManager:
print("Afirst")
with conManager:
print("Asecond")
with conManager:
print("third")
print("Bsecond")
print("Bfirst")
Output expected:
0
Afirst
1
Asecond
2
third
2
Bsecond
1
Bfirst
0
The only solution I have so far is a class with a stack in it, but that's not concurrent-safe. Are there any concurrent-safe solutions?
EDIT: as Sraw pointed out, I said thread safe when I meant concurrent-safe, changed the question accordingly.
The only solution I can think of is overriding conManager
's _call_ so that it returns a context manager, but I'd rather have a cleaner, no-call usage.
EDIT: since someone else showed interest I guess I guess I should post a solution I found
from contextvars import ContextVar
from random import randrange
from weakref import WeakKeyDictionary
context_stack = ContextVar('context_stack')
class ReCm:
def __init__(self):
if not context_stack.get(None):
context_stack.set(WeakKeyDictionary())
context_stack.get()[self] = []
def __enter__(self):
v = randrange(10)
context_stack.get()[self].append(v)
print(f'entered {v}')
return v
def __exit__(self, exc_type, exc_val, exc_tb):
v = context_stack.get()[self].pop()
print(f'exited {v}')